1 // File: BRepAlgoAPI_BooleanOperation.cxx
2 // Created: Fri Oct 15 11:35:03 1993
3 // Author: Remi LEQUETTE
9 #include <BRepAlgo_BooleanOperation.ixx>
10 #include <TopOpeBRep_DSFiller.hxx>
11 #include <TopOpeBRepDS_HDataStructure.hxx>
12 #include <TopOpeBRepDS_BuildTool.hxx>
13 #include <TopOpeBRepTool_OutCurveType.hxx>
14 #include <TopOpeBRepTool_GeomTool.hxx>
15 #include <BRep_Builder.hxx>
16 #include <BRepLib.hxx>
18 #include <TopTools_ListOfShape.hxx>
19 #include <TopTools_ListIteratorOfListOfShape.hxx>
20 #include <TopTools_MapOfShape.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepClass3d_SolidClassifier.hxx>
25 #include <BRepTools_Substitution.hxx>
26 #include <BRepBuilderAPI_Sewing.hxx>
27 #include <BRepCheck.hxx>
28 #include <BRepCheck_Edge.hxx>
29 #include <BRepCheck_Shell.hxx>
31 #include <TopOpeBRepDS_DSX.hxx>
33 #include <TopOpeBRepBuild_Tools.hxx>
34 #include <TopExp_Explorer.hxx>
36 #include <TopTools_IndexedMapOfShape.hxx>
40 Standard_IMPORT Standard_Boolean TopOpeBRepTool_GetcontextNOSEW();
43 #define Opecom(st1,st2) (((st1)==TopAbs_IN) && ((st2)==TopAbs_IN))
44 #define Opefus(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_OUT))
45 #define Opecut(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_IN))
47 // -------------------------------------------------------------------
48 static void Sub_Classify(TopExp_Explorer& Ex,
49 const TopAbs_State St1,
50 TopTools_ListOfShape& Solids2,
52 TopTools_ListIteratorOfListOfShape& LIter,
53 TopoDS_Shape& myShape);
57 Standard_IMPORT Standard_Integer TopOpeBRepTool_BOOOPE_CHECK_DEB;
60 //modified by NIZHNY-MZV Wed Apr 19 17:19:11 2000
61 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
62 //about using of this global variable
63 Standard_IMPORT Standard_Boolean GLOBAL_USE_NEW_BUILDER;
65 //modified by NIZNHY-PKV Sun Dec 15 17:17:56 2002 f
66 Standard_IMPORT void FDSCNX_Close();// see TopOpeBRepDS_connex.cxx
67 Standard_IMPORT void FDSSDM_Close();// see TopOpeBRepDS_samdom.cxx
69 //=======================================================================
71 //purpose : alias ~BRepAlgoAPI_BooleanOperation
72 //=======================================================================
73 void BRepAlgo_BooleanOperation::Delete()
78 //modified by NIZNHY-PKV Sun Dec 15 17:17:58 2002 t
80 //=======================================================================
81 //function : BRepAlgoAPI_BooleanOperation
83 //=======================================================================
84 BRepAlgo_BooleanOperation::BRepAlgo_BooleanOperation(const TopoDS_Shape& S1,
85 const TopoDS_Shape& S2)
86 : myS1(S1),myS2(S2),myBuilderCanWork(Standard_False)
88 TopOpeBRepDS_BuildTool BT;
89 myHBuilder = new TopOpeBRepBuild_HBuilder(BT);
92 //=======================================================================
93 //function : PerformDS
95 //=======================================================================
96 void BRepAlgo_BooleanOperation::PerformDS()
98 // const Standard_Boolean CheckShapes = Standard_True;
100 // create a data structure
101 Handle(TopOpeBRepDS_HDataStructure) HDS;
102 if (myHBuilder->DataStructure().IsNull())
103 HDS = new TopOpeBRepDS_HDataStructure();
105 HDS = myHBuilder->DataStructure();
106 HDS->ChangeDS().Init();
110 TopOpeBRepDS_SettraceSPSX_HDS(HDS);
113 // fill the data Structure
114 TopOpeBRep_DSFiller DSFiller;
116 // define face/face intersection tolerances
117 Standard_Boolean forcetoli = Standard_False;
120 Standard_Real tolarc=0,toltang=0;
122 Standard_Real tolarc,toltang;
124 TopOpeBRep_ShapeIntersector& tobsi = DSFiller.ChangeShapeIntersector();
125 TopOpeBRep_FacesIntersector& tobfi = tobsi.ChangeFacesIntersector();
126 tobfi.ForceTolerances(tolarc,toltang);
128 DSFiller.Insert(myS1,myS2,HDS);
130 // 020499 : JYL : reject if there is an edge of the SD
131 // not coded sameparameter and not degenerated
132 Standard_Boolean esp = HDS->EdgesSameParameter();
133 Standard_Boolean tede = Standard_True;
135 Standard_Integer i,n = HDS->NbShapes();
136 for (i = 1 ; i <= n; i++) {
137 const TopoDS_Shape& s = HDS->Shape(i);
138 if ( s.ShapeType() == TopAbs_EDGE ) {
139 const TopoDS_Edge& e = TopoDS::Edge(s);
140 Standard_Boolean sp = BRep_Tool::SameParameter(e);
141 Standard_Boolean de = BRep_Tool::Degenerated(e);
143 tede = Standard_False;
149 myBuilderCanWork = (esp || tede) ;
151 if (!esp) cout<<"BRepAlgo_BooleanOperation(DEB) some edges not SameParameter"<<endl;
153 if (!myBuilderCanWork) return;
155 Standard_Real tol3dAPPROX = 1e-7;
156 Standard_Real tol2dAPPROX = 1e-7;
157 // set tolerance values used by the APPROX process
159 TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
160 TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
161 GTofBTofBuilder.SetTolerances(tol3dAPPROX,tol2dAPPROX);
163 //modified by NIZHNY-MZV Thu Apr 20 09:35:44 2000
164 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
165 //about using of this global variable
166 GLOBAL_USE_NEW_BUILDER = Standard_True;
167 myHBuilder->Perform(HDS,myS1,myS2);
168 GLOBAL_USE_NEW_BUILDER = Standard_False;
171 //=======================================================================
174 //=======================================================================
175 void BRepAlgo_BooleanOperation::Perform(const TopAbs_State St1,
176 const TopAbs_State St2)
178 if ( ! BuilderCanWork() ) {
182 // modif JYL suite aux modifs LBR #if MODIF ...
183 // on privilegie le traitement KPart (si c'en est un)
185 Standard_Integer kp = myHBuilder->IsKPart();
187 Standard_Boolean sewing = Standard_True;
189 //modified by NIZHNY-MZV Thu Apr 20 09:34:33 2000
190 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
191 //about using of this global variable
192 GLOBAL_USE_NEW_BUILDER = Standard_True;
193 myHBuilder->MergeKPart(St1,St2);
194 GLOBAL_USE_NEW_BUILDER = Standard_False;
196 BB.MakeCompound(TopoDS::Compound(myShape));
199 TopTools_ListIteratorOfListOfShape its(myHBuilder->Merged(myS1,St1));
200 for(; its.More(); its.Next()) BB.Add(myShape,its.Value());
206 //======================================================================
207 //== Exploration of input shapes
208 //== Creation of the list of solids
209 //== Creation of the list of faces OUT OF solid
210 //== Creation of the list of edges OUT OF face
211 Standard_Integer nbs1,nbs2,nbf1,nbf2,nbe1,nbe2,nbv1,nbv2;
213 TopTools_ListOfShape Solids1,Solids2,Faces1,Faces2,Edges1,Edges2,Vertex1,Vertex2;
215 for(Ex.Init(myS1,TopAbs_SOLID),nbs1=0; Ex.More(); Ex.Next()) {
216 Solids1.Append(Ex.Current()); nbs1++;
218 for(Ex.Init(myS2,TopAbs_SOLID),nbs2=0; Ex.More(); Ex.Next()) {
219 Solids2.Append(Ex.Current()); nbs2++;
221 //== Faces not in a solid
222 for(Ex.Init(myS1,TopAbs_FACE,TopAbs_SOLID),nbf1=0; Ex.More(); Ex.Next()) {
223 Faces1.Append(Ex.Current()); nbf1++;
225 for(Ex.Init(myS2,TopAbs_FACE,TopAbs_SOLID),nbf2=0; Ex.More(); Ex.Next()) {
226 Faces2.Append(Ex.Current()); nbf2++;
228 //== Edges not in a solid
229 for(Ex.Init(myS1,TopAbs_EDGE,TopAbs_FACE),nbe1=0; Ex.More(); Ex.Next()) {
230 Edges1.Append(Ex.Current()); nbe1++;
232 for(Ex.Init(myS2,TopAbs_EDGE,TopAbs_FACE),nbe2=0; Ex.More(); Ex.Next()) {
233 Edges2.Append(Ex.Current()); nbe2++;
235 //== Vertices not in an edge
236 for(Ex.Init(myS1,TopAbs_VERTEX,TopAbs_EDGE),nbv1=0; Ex.More(); Ex.Next()) {
237 Vertex1.Append(Ex.Current()); nbv1++;
239 for(Ex.Init(myS2,TopAbs_VERTEX,TopAbs_EDGE),nbv2=0; Ex.More(); Ex.Next()) {
240 Vertex2.Append(Ex.Current()); nbv2++;
243 //-- cout<<"Solids1: "<<nbs1<<" Faces1: "<<nbf1<<" Edges1:"<<nbe1<<" Vtx1:"<<nbv1<<endl;
244 //-- cout<<"Solids2: "<<nbs2<<" Faces2: "<<nbf2<<" Edges2:"<<nbe2<<" Vtx2:"<<nbv2<<endl;
248 //== Reject operations without direction
251 //-- Cut Solid by Edge
252 // Standard_Boolean Correct = Standard_True;
253 if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_IN)
254 || (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_IN)) {
255 //-- cout<<"***** Invalid Operation : Cut of a Solid by a Non Solid "<<endl;
260 if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_OUT)
261 || (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_OUT)) {
262 //-- cout<<"***** Invalid Operation : Fusion of a Solid and a Non Solid "<<endl;
268 if( (nbs1>0 && nbs2>0)
269 && (nbe1 || nbe2 || nbf1 || nbf2 || nbv1 || nbv2)) {
270 //-- cout<<"***** Not Yet Implemented : Compound of solid and non Solid"<<endl;
274 //======================================================================
275 // make a compound with the new solids
276 BB.MakeCompound(TopoDS::Compound(myShape));
278 TopTools_ListIteratorOfListOfShape LIter;
279 //----------------------------------------------------------------------
284 if ( Opecom(St1,St2) ) {
285 TopTools_ListIteratorOfListOfShape itloe = myHBuilder->Section();
286 for(; itloe.More(); itloe.Next()) BB.Add(myShape,itloe.Value());
290 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
292 for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
293 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
294 TopTools_ListIteratorOfListOfShape its;
295 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
296 its.More();its.Next()) BB.Add(myShape,its.Value());
299 const TopoDS_Shape& LV = LIter.Value();
300 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
301 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
306 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
308 //-- End Classification
313 if ( Opefus(St1,St2) ) {
315 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
316 for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
317 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
318 TopTools_ListIteratorOfListOfShape its;
319 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
320 its.More();its.Next()) BB.Add(myShape,its.Value());
323 const TopoDS_Shape& LV = LIter.Value();
324 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
325 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
330 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
332 //-- End Classification
339 else if (nbf1 || nbf2) {
342 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
343 // modified by IFV for treating operation between shell and solid
344 const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS1,St1);
345 TopTools_IndexedMapOfShape aMapOfFaces;
347 sewing = Standard_False;
349 if(MergedShapes.Extent() != 0) {
350 TopTools_ListIteratorOfListOfShape its(MergedShapes);
351 for(; its.More(); its.Next()) {
352 BB.Add(myShape,its.Value());
354 TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
357 for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
359 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
360 TopTools_ListIteratorOfListOfShape its;
361 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
362 its.More();its.Next()) {
363 if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
367 const TopoDS_Shape& LV = LIter.Value();
368 if(!aMapOfFaces.Contains(LV)) {
369 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
370 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
375 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
377 //-- End Classification
384 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
385 // modified by IFV for treating operation between shell and solid
386 const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS2,St2);
387 TopTools_IndexedMapOfShape aMapOfFaces;
388 sewing = Standard_False;
390 if(MergedShapes.Extent() != 0) {
391 TopTools_ListIteratorOfListOfShape its(MergedShapes);
392 for(; its.More(); its.Next()) {
393 BB.Add(myShape,its.Value());
395 TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
398 for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
399 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
400 TopTools_ListIteratorOfListOfShape its;
401 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
402 its.More();its.Next()) {
403 if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
407 const TopoDS_Shape& LV = LIter.Value();
408 if(!aMapOfFaces.Contains(LV)) {
409 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
410 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
415 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
417 //-- End Classification
424 //----------------------------------------------------------------------
426 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
428 for(LIter.Initialize(Edges1);LIter.More();LIter.Next()) {
429 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
430 TopTools_ListIteratorOfListOfShape its;
431 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
432 its.More();its.Next()) {
433 BB.Add(myShape,its.Value());
437 const TopoDS_Shape& LV = LIter.Value();
438 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
439 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
444 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
446 //-- End Classification
451 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
453 for(LIter.Initialize(Edges2);LIter.More();LIter.Next()) {
454 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
455 TopTools_ListIteratorOfListOfShape its;
456 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
457 its.More();its.Next()) {
458 BB.Add(myShape,its.Value());
462 const TopoDS_Shape& LV = LIter.Value();
463 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
464 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
469 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
471 //-- End Classification
475 //----------------------------------------------------------------------
476 //-- V1:Vertex1 state1 = OUT -> Preserve V1 if V1 is Out all S2
477 //-- V1:Vertex1 state1 = IN -> Preserve V1 if V1 is In one of S2
479 if(St1 == TopAbs_IN) {
480 for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
481 Standard_Boolean keep = Standard_False;
482 Standard_Boolean ok = Standard_True;
483 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
484 gp_Pnt P=BRep_Tool::Pnt(V);
485 Standard_Real Tol = BRep_Tool::Tolerance(V);
486 TopTools_ListIteratorOfListOfShape SIter;
487 for(SIter.Initialize(Solids2);
488 SIter.More() && ok==Standard_True;
490 BRepClass3d_SolidClassifier SolClass(SIter.Value());
491 SolClass.Perform(P,Tol);
492 if(SolClass.State() == TopAbs_IN) {
494 keep = Standard_True;
498 BB.Add(myShape,LIter.Value());
503 if(St1 == TopAbs_OUT) {
504 for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
505 Standard_Boolean keep = Standard_True;
506 Standard_Boolean ok = Standard_True;
507 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
508 gp_Pnt P=BRep_Tool::Pnt(V);
509 Standard_Real Tol = BRep_Tool::Tolerance(V);
510 TopTools_ListIteratorOfListOfShape SIter;
511 for(SIter.Initialize(Solids2);
512 SIter.More() && ok==Standard_True;
514 BRepClass3d_SolidClassifier SolClass(SIter.Value());
515 SolClass.Perform(P,Tol);
516 if(SolClass.State() != TopAbs_OUT) {
517 keep = Standard_False;
522 BB.Add(myShape,LIter.Value());
530 if(St2 == TopAbs_IN) {
531 for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
532 Standard_Boolean keep = Standard_False;
533 Standard_Boolean ok = Standard_True;
534 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
535 gp_Pnt P=BRep_Tool::Pnt(V);
536 Standard_Real Tol = BRep_Tool::Tolerance(V);
537 TopTools_ListIteratorOfListOfShape SIter;
538 for(SIter.Initialize(Solids1);
539 SIter.More() && ok==Standard_True;
541 BRepClass3d_SolidClassifier SolClass(SIter.Value());
542 SolClass.Perform(P,Tol);
543 if(SolClass.State() == TopAbs_IN) {
545 keep = Standard_True;
549 BB.Add(myShape,LIter.Value());
554 if(St2 == TopAbs_OUT) {
555 for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
556 Standard_Boolean keep = Standard_True;
557 Standard_Boolean ok = Standard_True;
558 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
559 gp_Pnt P=BRep_Tool::Pnt(V);
560 Standard_Real Tol = BRep_Tool::Tolerance(V);
561 TopTools_ListIteratorOfListOfShape SIter;
562 for(SIter.Initialize(Solids1);
563 SIter.More() && ok==Standard_True;
565 BRepClass3d_SolidClassifier SolClass(SIter.Value());
566 SolClass.Perform(P,Tol);
567 if(SolClass.State() != TopAbs_OUT) {
568 keep = Standard_False;
573 BB.Add(myShape,LIter.Value());
581 myHBuilder->MergeShapes(myS1,St1,myS2,St2);
582 if(myHBuilder->IsMerged(myS1,St1)) {
583 TopTools_ListIteratorOfListOfShape its;
584 its = myHBuilder->Merged(myS1,St1);
585 Standard_Integer nbSolids = 0;
586 for(; its.More(); its.Next(), nbSolids++) {
587 BB.Add(myShape,its.Value());
594 myHBuilder->MergeSolids(myS1,St1,myS2,St2);
595 TopTools_ListIteratorOfListOfShape its;
597 BB.MakeCompound(TopoDS::Compound(myShape));
598 its = myHBuilder->Merged(myS1,St1);
600 BB.Add(myShape,its.Value());
609 // Creation of the Map used in IsDeleted.
611 ex.Init(myShape,TopAbs_FACE);
612 for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
613 ex.Init(myShape,TopAbs_EDGE); // for FRIKO
614 for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
616 // Checking same parameter of new edges of section
617 Standard_Real eTol,cTol;
618 for (myHBuilder->InitSection(1);
619 myHBuilder->MoreSection();
620 myHBuilder->NextSection()) {
621 const TopoDS_Shape& cur = myHBuilder->CurrentSection();
622 if (cur.ShapeType()==TopAbs_EDGE) {
623 BRepCheck_Edge bce(TopoDS::Edge(cur));
624 cTol=bce.Tolerance();
625 eTol = BRep_Tool::Tolerance(TopoDS::Edge(cur));
627 BB.UpdateEdge(TopoDS::Edge(cur), cTol);
628 for (ex.Init(cur, TopAbs_VERTEX); ex.More(); ex.Next()) {
629 eTol = BRep_Tool::Tolerance(TopoDS::Vertex(ex.Current()));
631 // Update can only increase tolerance, so if the vertex
632 // has a greater tolerance thanits edges it is not touched
633 BB.UpdateVertex(TopoDS::Vertex(ex.Current()), cTol);
640 Standard_Real maxTol = RealLast(); // MSV: unlimit tolerance
641 TopOpeBRepBuild_Tools::CorrectTolerances(myShape,maxTol);
643 TopExp_Explorer ex1, ex2, ex3;
644 TopTools_ListOfShape theOldShell, theNewShell;
645 Standard_Boolean modif =Standard_False;
648 Standard_Boolean nosew = TopOpeBRepTool_GetcontextNOSEW();
649 if (nosew) sewing = Standard_False;
654 for (ex1.Init(myShape, TopAbs_SHELL); ex1.More(); ex1.Next()) {
655 BRepCheck_Shell bcs(TopoDS::Shell(ex1.Current()));
656 if (bcs.Closed()==BRepCheck_NotClosed) {
657 // it is required to add them face by face to avoid IsModified on faces
658 BRepBuilderAPI_Sewing brts;
659 for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
660 brts.Add(ex3.Current());
663 ex2.Init(brts.SewedShape(), TopAbs_SHELL);
667 ex2.Init(brts.SewedShape(), TopAbs_SHELL);
668 theOldShell.Append(ex1.Current());
669 theNewShell.Append(ex2.Current());
670 modif =Standard_True;
671 for (ex3.Init(ex1.Current(), TopAbs_EDGE); ex3.More(); ex3.Next()) {
672 const TopoDS_Edge& ledg = TopoDS::Edge(ex3.Current());
673 if (brts.IsSectionBound(ledg)) {
674 topToSew.Bind(ledg, brts.SectionToBoundary(ledg));
675 if (!BRep_Tool::SameParameter(brts.SectionToBoundary(ledg))) {
676 BRepLib::SameParameter(ledg, BRep_Tool::Tolerance(brts.SectionToBoundary(ledg)));
680 for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
681 if (brts.IsModified(ex3.Current())) {
682 topToSew.Bind(ex3.Current(), brts.Modified(ex3.Current()));
692 BRepTools_Substitution bsub;
693 TopTools_ListIteratorOfListOfShape itl(theOldShell);
694 TopTools_ListOfShape forSub;
695 for (; itl.More();itl.Next()) {
696 forSub.Append(theNewShell.First());
697 bsub.Substitute(itl.Value(), forSub);
698 theNewShell.RemoveFirst();
702 if (bsub.IsCopied(myShape)) {
703 myShape=(bsub.Copy(myShape)).First();
712 //=======================================================================
715 //=======================================================================
716 Handle(TopOpeBRepBuild_HBuilder) BRepAlgo_BooleanOperation::Builder()const
722 //=======================================================================
723 //function : TopoDS_Shape&
725 //=======================================================================
726 const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape1() const
732 //=======================================================================
733 //function : TopoDS_Shape&
735 //=======================================================================
736 const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape2() const
741 //=======================================================================
742 //function : BuilderCanWork
744 //=======================================================================
745 void BRepAlgo_BooleanOperation::BuilderCanWork(const Standard_Boolean Val)
747 myBuilderCanWork = Val;
750 //=======================================================================
751 //function : BuilderCanWork
753 //=======================================================================
754 Standard_Boolean BRepAlgo_BooleanOperation::BuilderCanWork() const
756 return myBuilderCanWork;
760 void Sub_Classify(TopExp_Explorer& Ex,
761 const TopAbs_State St1,
762 TopTools_ListOfShape& Solids2,
764 TopTools_ListIteratorOfListOfShape& LIter,
765 TopoDS_Shape& myShape) {
766 Ex.Init(LIter.Value(),TopAbs_VERTEX);
768 if(St1 == TopAbs_IN) {
769 Standard_Boolean keep = Standard_False;
770 Standard_Boolean ok = Standard_True;
771 const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
772 gp_Pnt P=BRep_Tool::Pnt(V);
773 Standard_Real Tol = BRep_Tool::Tolerance(V);
774 TopTools_ListIteratorOfListOfShape SIter;
775 for(SIter.Initialize(Solids2);
776 SIter.More() && ok==Standard_True;
778 BRepClass3d_SolidClassifier SolClass(SIter.Value());
779 SolClass.Perform(P,Tol);
780 if(SolClass.State() == TopAbs_IN) {
782 keep = Standard_True;
786 BB.Add(myShape,LIter.Value());
790 if(St1 == TopAbs_OUT) {
791 Standard_Boolean keep = Standard_True;
792 Standard_Boolean ok = Standard_True;
793 const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
794 gp_Pnt P=BRep_Tool::Pnt(V);
795 Standard_Real Tol = BRep_Tool::Tolerance(V);
796 TopTools_ListIteratorOfListOfShape SIter;
797 for(SIter.Initialize(Solids2);
798 SIter.More() && ok==Standard_True;
800 BRepClass3d_SolidClassifier SolClass(SIter.Value());
801 SolClass.Perform(P,Tol);
802 if(SolClass.State() != TopAbs_OUT) {
803 keep = Standard_False;
808 BB.Add(myShape,LIter.Value());
816 //=======================================================================
817 //function : InitParameters
818 //purpose : Info on geometry : PCurve, Approx, ...
819 //=======================================================================
820 void BRepAlgo_BooleanOperation::InitParameters()
822 TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
823 TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
825 GTofBTofBuilder.Define(TopOpeBRepTool_APPROX);
826 GTofBTofBuilder.DefineCurves(Standard_True);
827 GTofBTofBuilder.DefinePCurves1(Standard_True);
828 GTofBTofBuilder.DefinePCurves2(Standard_True);
831 //=======================================================================
832 //function : Modified
834 //=======================================================================
835 const TopTools_ListOfShape& BRepAlgo_BooleanOperation::Modified(const TopoDS_Shape& S)
838 TopTools_MapOfShape aMap; // to check if shape can be added in list more then one time
840 if (myHBuilder->IsSplit(S, TopAbs_OUT)) {
841 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_OUT));
842 for(;It.More();It.Next()) {
843 if (topToSew.IsBound(It.Value()))
844 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
846 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
849 if (myHBuilder->IsSplit(S, TopAbs_IN)) {
850 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_IN));
851 for(;It.More();It.Next()) {
852 if (topToSew.IsBound(It.Value()))
853 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
855 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
858 if (myHBuilder->IsSplit(S, TopAbs_ON)) {
859 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_ON));
860 for(;It.More();It.Next()) {
861 if (topToSew.IsBound(It.Value()))
862 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
864 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
868 if (myHBuilder->IsMerged(S, TopAbs_OUT)) {
869 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_OUT));
870 for(;It.More();It.Next()) {
871 if (topToSew.IsBound(It.Value()))
872 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
874 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
877 if (myHBuilder->IsMerged(S, TopAbs_IN)) {
878 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_IN));
879 for(;It.More();It.Next()) {
880 if (topToSew.IsBound(It.Value()))
881 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
883 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
886 if (myHBuilder->IsMerged(S, TopAbs_ON)) {
887 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_ON));
888 for(;It.More();It.Next()) {
889 if (topToSew.IsBound(It.Value()))
890 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
892 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
899 //=======================================================================
900 //function : IsDeleted
902 //=======================================================================
903 Standard_Boolean BRepAlgo_BooleanOperation::IsDeleted(const TopoDS_Shape& S)
905 Standard_Boolean Deleted = Standard_True;
906 if (myMap.Contains(S) ||
907 myHBuilder->IsMerged(S, TopAbs_OUT) ||
908 myHBuilder->IsMerged(S, TopAbs_IN) ||
909 myHBuilder->IsMerged(S, TopAbs_ON) ||
910 myHBuilder->IsSplit (S, TopAbs_OUT) ||
911 myHBuilder->IsSplit (S, TopAbs_IN) ||
912 myHBuilder->IsSplit (S, TopAbs_ON))
913 return Standard_False;