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