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.
20 #include <BRepAlgo_BooleanOperation.ixx>
21 #include <TopOpeBRep_DSFiller.hxx>
22 #include <TopOpeBRepDS_HDataStructure.hxx>
23 #include <TopOpeBRepDS_BuildTool.hxx>
24 #include <TopOpeBRepTool_OutCurveType.hxx>
25 #include <TopOpeBRepTool_GeomTool.hxx>
26 #include <BRep_Builder.hxx>
27 #include <BRepLib.hxx>
29 #include <TopTools_ListOfShape.hxx>
30 #include <TopTools_ListIteratorOfListOfShape.hxx>
31 #include <TopTools_MapOfShape.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRepClass3d_SolidClassifier.hxx>
36 #include <BRepTools_Substitution.hxx>
37 #include <BRepBuilderAPI_Sewing.hxx>
38 #include <BRepCheck.hxx>
39 #include <BRepCheck_Edge.hxx>
40 #include <BRepCheck_Shell.hxx>
42 #include <TopOpeBRepDS_DSX.hxx>
44 #include <TopOpeBRepBuild_Tools.hxx>
45 #include <TopExp_Explorer.hxx>
47 #include <TopTools_IndexedMapOfShape.hxx>
51 extern Standard_Boolean TopOpeBRepTool_GetcontextNOSEW();
54 #define Opecom(st1,st2) (((st1)==TopAbs_IN) && ((st2)==TopAbs_IN))
55 #define Opefus(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_OUT))
56 #define Opecut(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_IN))
58 // -------------------------------------------------------------------
59 static void Sub_Classify(TopExp_Explorer& Ex,
60 const TopAbs_State St1,
61 TopTools_ListOfShape& Solids2,
63 TopTools_ListIteratorOfListOfShape& LIter,
64 TopoDS_Shape& myShape);
68 Standard_IMPORT Standard_Integer TopOpeBRepTool_BOOOPE_CHECK_DEB;
71 //modified by NIZHNY-MZV Wed Apr 19 17:19:11 2000
72 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
73 //about using of this global variable
74 extern Standard_Boolean GLOBAL_USE_NEW_BUILDER;
76 //modified by NIZNHY-PKV Sun Dec 15 17:17:56 2002 f
77 extern void FDSCNX_Close();// see TopOpeBRepDS_connex.cxx
78 extern void FDSSDM_Close();// see TopOpeBRepDS_samdom.cxx
80 //=======================================================================
82 //purpose : alias ~BRepAlgoAPI_BooleanOperation
83 //=======================================================================
84 void BRepAlgo_BooleanOperation::Delete()
89 //modified by NIZNHY-PKV Sun Dec 15 17:17:58 2002 t
91 //=======================================================================
92 //function : BRepAlgoAPI_BooleanOperation
94 //=======================================================================
95 BRepAlgo_BooleanOperation::BRepAlgo_BooleanOperation(const TopoDS_Shape& S1,
96 const TopoDS_Shape& S2)
97 : myS1(S1),myS2(S2),myBuilderCanWork(Standard_False)
99 TopOpeBRepDS_BuildTool BT;
100 myHBuilder = new TopOpeBRepBuild_HBuilder(BT);
103 //=======================================================================
104 //function : PerformDS
106 //=======================================================================
107 void BRepAlgo_BooleanOperation::PerformDS()
109 // const Standard_Boolean CheckShapes = Standard_True;
111 // create a data structure
112 Handle(TopOpeBRepDS_HDataStructure) HDS;
113 if (myHBuilder->DataStructure().IsNull())
114 HDS = new TopOpeBRepDS_HDataStructure();
116 HDS = myHBuilder->DataStructure();
117 HDS->ChangeDS().Init();
121 TopOpeBRepDS_SettraceSPSX_HDS(HDS);
124 // fill the data Structure
125 TopOpeBRep_DSFiller DSFiller;
127 // define face/face intersection tolerances
128 Standard_Boolean forcetoli = Standard_False;
130 Standard_Real tolarc=0,toltang=0;
131 TopOpeBRep_ShapeIntersector& tobsi = DSFiller.ChangeShapeIntersector();
132 TopOpeBRep_FacesIntersector& tobfi = tobsi.ChangeFacesIntersector();
133 tobfi.ForceTolerances(tolarc,toltang);
135 DSFiller.Insert(myS1,myS2,HDS);
137 // 020499 : JYL : reject if there is an edge of the SD
138 // not coded sameparameter and not degenerated
139 Standard_Boolean esp = HDS->EdgesSameParameter();
140 Standard_Boolean tede = Standard_True;
142 Standard_Integer i,n = HDS->NbShapes();
143 for (i = 1 ; i <= n; i++) {
144 const TopoDS_Shape& s = HDS->Shape(i);
145 if ( s.ShapeType() == TopAbs_EDGE ) {
146 const TopoDS_Edge& e = TopoDS::Edge(s);
147 Standard_Boolean sp = BRep_Tool::SameParameter(e);
148 Standard_Boolean de = BRep_Tool::Degenerated(e);
150 tede = Standard_False;
156 myBuilderCanWork = (esp || tede) ;
158 if (!esp) cout<<"BRepAlgo_BooleanOperation(DEB) some edges not SameParameter"<<endl;
160 if (!myBuilderCanWork) return;
162 Standard_Real tol3dAPPROX = 1e-7;
163 Standard_Real tol2dAPPROX = 1e-7;
164 // set tolerance values used by the APPROX process
166 TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
167 TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
168 GTofBTofBuilder.SetTolerances(tol3dAPPROX,tol2dAPPROX);
170 //modified by NIZHNY-MZV Thu Apr 20 09:35:44 2000
171 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
172 //about using of this global variable
173 GLOBAL_USE_NEW_BUILDER = Standard_True;
174 myHBuilder->Perform(HDS,myS1,myS2);
175 GLOBAL_USE_NEW_BUILDER = Standard_False;
178 //=======================================================================
181 //=======================================================================
182 void BRepAlgo_BooleanOperation::Perform(const TopAbs_State St1,
183 const TopAbs_State St2)
185 if ( ! BuilderCanWork() ) {
189 // modif JYL suite aux modifs LBR #if MODIF ...
190 // on privilegie le traitement KPart (si c'en est un)
192 Standard_Integer kp = myHBuilder->IsKPart();
194 Standard_Boolean sewing = Standard_True;
196 //modified by NIZHNY-MZV Thu Apr 20 09:34:33 2000
197 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
198 //about using of this global variable
199 GLOBAL_USE_NEW_BUILDER = Standard_True;
200 myHBuilder->MergeKPart(St1,St2);
201 GLOBAL_USE_NEW_BUILDER = Standard_False;
203 BB.MakeCompound(TopoDS::Compound(myShape));
206 TopTools_ListIteratorOfListOfShape its(myHBuilder->Merged(myS1,St1));
207 for(; its.More(); its.Next()) BB.Add(myShape,its.Value());
213 //======================================================================
214 //== Exploration of input shapes
215 //== Creation of the list of solids
216 //== Creation of the list of faces OUT OF solid
217 //== Creation of the list of edges OUT OF face
218 Standard_Integer nbs1,nbs2,nbf1,nbf2,nbe1,nbe2,nbv1,nbv2;
220 TopTools_ListOfShape Solids1,Solids2,Faces1,Faces2,Edges1,Edges2,Vertex1,Vertex2;
222 for(Ex.Init(myS1,TopAbs_SOLID),nbs1=0; Ex.More(); Ex.Next()) {
223 Solids1.Append(Ex.Current()); nbs1++;
225 for(Ex.Init(myS2,TopAbs_SOLID),nbs2=0; Ex.More(); Ex.Next()) {
226 Solids2.Append(Ex.Current()); nbs2++;
228 //== Faces not in a solid
229 for(Ex.Init(myS1,TopAbs_FACE,TopAbs_SOLID),nbf1=0; Ex.More(); Ex.Next()) {
230 Faces1.Append(Ex.Current()); nbf1++;
232 for(Ex.Init(myS2,TopAbs_FACE,TopAbs_SOLID),nbf2=0; Ex.More(); Ex.Next()) {
233 Faces2.Append(Ex.Current()); nbf2++;
235 //== Edges not in a solid
236 for(Ex.Init(myS1,TopAbs_EDGE,TopAbs_FACE),nbe1=0; Ex.More(); Ex.Next()) {
237 Edges1.Append(Ex.Current()); nbe1++;
239 for(Ex.Init(myS2,TopAbs_EDGE,TopAbs_FACE),nbe2=0; Ex.More(); Ex.Next()) {
240 Edges2.Append(Ex.Current()); nbe2++;
242 //== Vertices not in an edge
243 for(Ex.Init(myS1,TopAbs_VERTEX,TopAbs_EDGE),nbv1=0; Ex.More(); Ex.Next()) {
244 Vertex1.Append(Ex.Current()); nbv1++;
246 for(Ex.Init(myS2,TopAbs_VERTEX,TopAbs_EDGE),nbv2=0; Ex.More(); Ex.Next()) {
247 Vertex2.Append(Ex.Current()); nbv2++;
250 //-- cout<<"Solids1: "<<nbs1<<" Faces1: "<<nbf1<<" Edges1:"<<nbe1<<" Vtx1:"<<nbv1<<endl;
251 //-- cout<<"Solids2: "<<nbs2<<" Faces2: "<<nbf2<<" Edges2:"<<nbe2<<" Vtx2:"<<nbv2<<endl;
255 //== Reject operations without direction
258 //-- Cut Solid by Edge
259 // Standard_Boolean Correct = Standard_True;
260 if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_IN)
261 || (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_IN)) {
262 //-- cout<<"***** Invalid Operation : Cut of a Solid by a Non Solid "<<endl;
267 if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_OUT)
268 || (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_OUT)) {
269 //-- cout<<"***** Invalid Operation : Fusion of a Solid and a Non Solid "<<endl;
275 if( (nbs1>0 && nbs2>0)
276 && (nbe1 || nbe2 || nbf1 || nbf2 || nbv1 || nbv2)) {
277 //-- cout<<"***** Not Yet Implemented : Compound of solid and non Solid"<<endl;
281 //======================================================================
282 // make a compound with the new solids
283 BB.MakeCompound(TopoDS::Compound(myShape));
285 TopTools_ListIteratorOfListOfShape LIter;
286 //----------------------------------------------------------------------
291 if ( Opecom(St1,St2) ) {
292 TopTools_ListIteratorOfListOfShape itloe = myHBuilder->Section();
293 for(; itloe.More(); itloe.Next()) BB.Add(myShape,itloe.Value());
297 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
299 for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
300 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
301 TopTools_ListIteratorOfListOfShape its;
302 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
303 its.More();its.Next()) BB.Add(myShape,its.Value());
306 const TopoDS_Shape& LV = LIter.Value();
307 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
308 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
313 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
315 //-- End Classification
320 if ( Opefus(St1,St2) ) {
322 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
323 for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
324 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
325 TopTools_ListIteratorOfListOfShape its;
326 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
327 its.More();its.Next()) BB.Add(myShape,its.Value());
330 const TopoDS_Shape& LV = LIter.Value();
331 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
332 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
337 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
339 //-- End Classification
346 else if (nbf1 || nbf2) {
349 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
350 // modified by IFV for treating operation between shell and solid
351 const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS1,St1);
352 TopTools_IndexedMapOfShape aMapOfFaces;
354 sewing = Standard_False;
356 if(MergedShapes.Extent() != 0) {
357 TopTools_ListIteratorOfListOfShape its(MergedShapes);
358 for(; its.More(); its.Next()) {
359 BB.Add(myShape,its.Value());
361 TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
364 for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
366 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
367 TopTools_ListIteratorOfListOfShape its;
368 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
369 its.More();its.Next()) {
370 if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
374 const TopoDS_Shape& LV = LIter.Value();
375 if(!aMapOfFaces.Contains(LV)) {
376 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
377 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
382 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
384 //-- End Classification
391 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
392 // modified by IFV for treating operation between shell and solid
393 const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS2,St2);
394 TopTools_IndexedMapOfShape aMapOfFaces;
395 sewing = Standard_False;
397 if(MergedShapes.Extent() != 0) {
398 TopTools_ListIteratorOfListOfShape its(MergedShapes);
399 for(; its.More(); its.Next()) {
400 BB.Add(myShape,its.Value());
402 TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
405 for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
406 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
407 TopTools_ListIteratorOfListOfShape its;
408 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
409 its.More();its.Next()) {
410 if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
414 const TopoDS_Shape& LV = LIter.Value();
415 if(!aMapOfFaces.Contains(LV)) {
416 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
417 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
422 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
424 //-- End Classification
431 //----------------------------------------------------------------------
433 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
435 for(LIter.Initialize(Edges1);LIter.More();LIter.Next()) {
436 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
437 TopTools_ListIteratorOfListOfShape its;
438 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
439 its.More();its.Next()) {
440 BB.Add(myShape,its.Value());
444 const TopoDS_Shape& LV = LIter.Value();
445 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
446 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
451 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
453 //-- End Classification
458 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
460 for(LIter.Initialize(Edges2);LIter.More();LIter.Next()) {
461 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
462 TopTools_ListIteratorOfListOfShape its;
463 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
464 its.More();its.Next()) {
465 BB.Add(myShape,its.Value());
469 const TopoDS_Shape& LV = LIter.Value();
470 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
471 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
476 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
478 //-- End Classification
482 //----------------------------------------------------------------------
483 //-- V1:Vertex1 state1 = OUT -> Preserve V1 if V1 is Out all S2
484 //-- V1:Vertex1 state1 = IN -> Preserve V1 if V1 is In one of S2
486 if(St1 == TopAbs_IN) {
487 for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
488 Standard_Boolean keep = Standard_False;
489 Standard_Boolean ok = Standard_True;
490 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
491 gp_Pnt P=BRep_Tool::Pnt(V);
492 Standard_Real Tol = BRep_Tool::Tolerance(V);
493 TopTools_ListIteratorOfListOfShape SIter;
494 for(SIter.Initialize(Solids2);
495 SIter.More() && ok==Standard_True;
497 BRepClass3d_SolidClassifier SolClass(SIter.Value());
498 SolClass.Perform(P,Tol);
499 if(SolClass.State() == TopAbs_IN) {
501 keep = Standard_True;
505 BB.Add(myShape,LIter.Value());
510 if(St1 == TopAbs_OUT) {
511 for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
512 Standard_Boolean keep = Standard_True;
513 Standard_Boolean ok = Standard_True;
514 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
515 gp_Pnt P=BRep_Tool::Pnt(V);
516 Standard_Real Tol = BRep_Tool::Tolerance(V);
517 TopTools_ListIteratorOfListOfShape SIter;
518 for(SIter.Initialize(Solids2);
519 SIter.More() && ok==Standard_True;
521 BRepClass3d_SolidClassifier SolClass(SIter.Value());
522 SolClass.Perform(P,Tol);
523 if(SolClass.State() != TopAbs_OUT) {
524 keep = Standard_False;
529 BB.Add(myShape,LIter.Value());
537 if(St2 == TopAbs_IN) {
538 for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
539 Standard_Boolean keep = Standard_False;
540 Standard_Boolean ok = Standard_True;
541 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
542 gp_Pnt P=BRep_Tool::Pnt(V);
543 Standard_Real Tol = BRep_Tool::Tolerance(V);
544 TopTools_ListIteratorOfListOfShape SIter;
545 for(SIter.Initialize(Solids1);
546 SIter.More() && ok==Standard_True;
548 BRepClass3d_SolidClassifier SolClass(SIter.Value());
549 SolClass.Perform(P,Tol);
550 if(SolClass.State() == TopAbs_IN) {
552 keep = Standard_True;
556 BB.Add(myShape,LIter.Value());
561 if(St2 == TopAbs_OUT) {
562 for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
563 Standard_Boolean keep = Standard_True;
564 Standard_Boolean ok = Standard_True;
565 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
566 gp_Pnt P=BRep_Tool::Pnt(V);
567 Standard_Real Tol = BRep_Tool::Tolerance(V);
568 TopTools_ListIteratorOfListOfShape SIter;
569 for(SIter.Initialize(Solids1);
570 SIter.More() && ok==Standard_True;
572 BRepClass3d_SolidClassifier SolClass(SIter.Value());
573 SolClass.Perform(P,Tol);
574 if(SolClass.State() != TopAbs_OUT) {
575 keep = Standard_False;
580 BB.Add(myShape,LIter.Value());
588 myHBuilder->MergeShapes(myS1,St1,myS2,St2);
589 if(myHBuilder->IsMerged(myS1,St1)) {
590 TopTools_ListIteratorOfListOfShape its;
591 its = myHBuilder->Merged(myS1,St1);
592 Standard_Integer nbSolids = 0;
593 for(; its.More(); its.Next(), nbSolids++) {
594 BB.Add(myShape,its.Value());
601 myHBuilder->MergeSolids(myS1,St1,myS2,St2);
602 TopTools_ListIteratorOfListOfShape its;
604 BB.MakeCompound(TopoDS::Compound(myShape));
605 its = myHBuilder->Merged(myS1,St1);
607 BB.Add(myShape,its.Value());
616 // Creation of the Map used in IsDeleted.
618 ex.Init(myShape,TopAbs_FACE);
619 for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
620 ex.Init(myShape,TopAbs_EDGE); // for FRIKO
621 for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
623 // Checking same parameter of new edges of section
624 Standard_Real eTol,cTol;
625 for (myHBuilder->InitSection(1);
626 myHBuilder->MoreSection();
627 myHBuilder->NextSection()) {
628 const TopoDS_Shape& cur = myHBuilder->CurrentSection();
629 if (cur.ShapeType()==TopAbs_EDGE) {
630 BRepCheck_Edge bce(TopoDS::Edge(cur));
631 cTol=bce.Tolerance();
632 eTol = BRep_Tool::Tolerance(TopoDS::Edge(cur));
634 BB.UpdateEdge(TopoDS::Edge(cur), cTol);
635 for (ex.Init(cur, TopAbs_VERTEX); ex.More(); ex.Next()) {
636 eTol = BRep_Tool::Tolerance(TopoDS::Vertex(ex.Current()));
638 // Update can only increase tolerance, so if the vertex
639 // has a greater tolerance thanits edges it is not touched
640 BB.UpdateVertex(TopoDS::Vertex(ex.Current()), cTol);
647 Standard_Real maxTol = RealLast(); // MSV: unlimit tolerance
648 TopOpeBRepBuild_Tools::CorrectTolerances(myShape,maxTol);
650 TopExp_Explorer ex1, ex2, ex3;
651 TopTools_ListOfShape theOldShell, theNewShell;
652 Standard_Boolean modif =Standard_False;
655 Standard_Boolean nosew = TopOpeBRepTool_GetcontextNOSEW();
656 if (nosew) sewing = Standard_False;
661 for (ex1.Init(myShape, TopAbs_SHELL); ex1.More(); ex1.Next()) {
662 BRepCheck_Shell bcs(TopoDS::Shell(ex1.Current()));
663 if (bcs.Closed()==BRepCheck_NotClosed) {
664 // it is required to add them face by face to avoid IsModified on faces
665 BRepBuilderAPI_Sewing brts;
666 for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
667 brts.Add(ex3.Current());
670 ex2.Init(brts.SewedShape(), TopAbs_SHELL);
674 ex2.Init(brts.SewedShape(), TopAbs_SHELL);
675 theOldShell.Append(ex1.Current());
676 theNewShell.Append(ex2.Current());
677 modif =Standard_True;
678 for (ex3.Init(ex1.Current(), TopAbs_EDGE); ex3.More(); ex3.Next()) {
679 const TopoDS_Edge& ledg = TopoDS::Edge(ex3.Current());
680 if (brts.IsSectionBound(ledg)) {
681 topToSew.Bind(ledg, brts.SectionToBoundary(ledg));
682 if (!BRep_Tool::SameParameter(brts.SectionToBoundary(ledg))) {
683 BRepLib::SameParameter(ledg, BRep_Tool::Tolerance(brts.SectionToBoundary(ledg)));
687 for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
688 if (brts.IsModified(ex3.Current())) {
689 topToSew.Bind(ex3.Current(), brts.Modified(ex3.Current()));
699 BRepTools_Substitution bsub;
700 TopTools_ListIteratorOfListOfShape itl(theOldShell);
701 TopTools_ListOfShape forSub;
702 for (; itl.More();itl.Next()) {
703 forSub.Append(theNewShell.First());
704 bsub.Substitute(itl.Value(), forSub);
705 theNewShell.RemoveFirst();
709 if (bsub.IsCopied(myShape)) {
710 myShape=(bsub.Copy(myShape)).First();
719 //=======================================================================
722 //=======================================================================
723 Handle(TopOpeBRepBuild_HBuilder) BRepAlgo_BooleanOperation::Builder()const
729 //=======================================================================
730 //function : TopoDS_Shape&
732 //=======================================================================
733 const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape1() const
739 //=======================================================================
740 //function : TopoDS_Shape&
742 //=======================================================================
743 const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape2() const
748 //=======================================================================
749 //function : BuilderCanWork
751 //=======================================================================
752 void BRepAlgo_BooleanOperation::BuilderCanWork(const Standard_Boolean Val)
754 myBuilderCanWork = Val;
757 //=======================================================================
758 //function : BuilderCanWork
760 //=======================================================================
761 Standard_Boolean BRepAlgo_BooleanOperation::BuilderCanWork() const
763 return myBuilderCanWork;
767 void Sub_Classify(TopExp_Explorer& Ex,
768 const TopAbs_State St1,
769 TopTools_ListOfShape& Solids2,
771 TopTools_ListIteratorOfListOfShape& LIter,
772 TopoDS_Shape& myShape) {
773 Ex.Init(LIter.Value(),TopAbs_VERTEX);
775 if(St1 == TopAbs_IN) {
776 Standard_Boolean keep = Standard_False;
777 Standard_Boolean ok = Standard_True;
778 const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
779 gp_Pnt P=BRep_Tool::Pnt(V);
780 Standard_Real Tol = BRep_Tool::Tolerance(V);
781 TopTools_ListIteratorOfListOfShape SIter;
782 for(SIter.Initialize(Solids2);
783 SIter.More() && ok==Standard_True;
785 BRepClass3d_SolidClassifier SolClass(SIter.Value());
786 SolClass.Perform(P,Tol);
787 if(SolClass.State() == TopAbs_IN) {
789 keep = Standard_True;
793 BB.Add(myShape,LIter.Value());
797 if(St1 == TopAbs_OUT) {
798 Standard_Boolean keep = Standard_True;
799 Standard_Boolean ok = Standard_True;
800 const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
801 gp_Pnt P=BRep_Tool::Pnt(V);
802 Standard_Real Tol = BRep_Tool::Tolerance(V);
803 TopTools_ListIteratorOfListOfShape SIter;
804 for(SIter.Initialize(Solids2);
805 SIter.More() && ok==Standard_True;
807 BRepClass3d_SolidClassifier SolClass(SIter.Value());
808 SolClass.Perform(P,Tol);
809 if(SolClass.State() != TopAbs_OUT) {
810 keep = Standard_False;
815 BB.Add(myShape,LIter.Value());
823 //=======================================================================
824 //function : InitParameters
825 //purpose : Info on geometry : PCurve, Approx, ...
826 //=======================================================================
827 void BRepAlgo_BooleanOperation::InitParameters()
829 TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
830 TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
832 GTofBTofBuilder.Define(TopOpeBRepTool_APPROX);
833 GTofBTofBuilder.DefineCurves(Standard_True);
834 GTofBTofBuilder.DefinePCurves1(Standard_True);
835 GTofBTofBuilder.DefinePCurves2(Standard_True);
838 //=======================================================================
839 //function : Modified
841 //=======================================================================
842 const TopTools_ListOfShape& BRepAlgo_BooleanOperation::Modified(const TopoDS_Shape& S)
845 TopTools_MapOfShape aMap; // to check if shape can be added in list more then one time
847 if (myHBuilder->IsSplit(S, TopAbs_OUT)) {
848 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_OUT));
849 for(;It.More();It.Next()) {
850 if (topToSew.IsBound(It.Value()))
851 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
853 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
856 if (myHBuilder->IsSplit(S, TopAbs_IN)) {
857 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_IN));
858 for(;It.More();It.Next()) {
859 if (topToSew.IsBound(It.Value()))
860 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
862 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
865 if (myHBuilder->IsSplit(S, TopAbs_ON)) {
866 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_ON));
867 for(;It.More();It.Next()) {
868 if (topToSew.IsBound(It.Value()))
869 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
871 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
875 if (myHBuilder->IsMerged(S, TopAbs_OUT)) {
876 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_OUT));
877 for(;It.More();It.Next()) {
878 if (topToSew.IsBound(It.Value()))
879 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
881 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
884 if (myHBuilder->IsMerged(S, TopAbs_IN)) {
885 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_IN));
886 for(;It.More();It.Next()) {
887 if (topToSew.IsBound(It.Value()))
888 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
890 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
893 if (myHBuilder->IsMerged(S, TopAbs_ON)) {
894 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_ON));
895 for(;It.More();It.Next()) {
896 if (topToSew.IsBound(It.Value()))
897 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
899 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
906 //=======================================================================
907 //function : IsDeleted
909 //=======================================================================
910 Standard_Boolean BRepAlgo_BooleanOperation::IsDeleted(const TopoDS_Shape& S)
912 Standard_Boolean Deleted = Standard_True;
913 if (myMap.Contains(S) ||
914 myHBuilder->IsMerged(S, TopAbs_OUT) ||
915 myHBuilder->IsMerged(S, TopAbs_IN) ||
916 myHBuilder->IsMerged(S, TopAbs_ON) ||
917 myHBuilder->IsSplit (S, TopAbs_OUT) ||
918 myHBuilder->IsSplit (S, TopAbs_IN) ||
919 myHBuilder->IsSplit (S, TopAbs_ON))
920 return Standard_False;