0022312: Translation of french commentaries in OCCT files
[occt.git] / src / BRepAlgo / BRepAlgo_BooleanOperation.cxx
1 // File:        BRepAlgoAPI_BooleanOperation.cxx
2 // Created:     Fri Oct 15 11:35:03 1993
3 // Author:      Remi LEQUETTE
4 //              <rle@phylox>
5
6 #define TRC 0 
7 #define MODIF 1 
8
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>
17 #include <TopoDS.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>
23
24 //  sewing
25 #include <BRepTools_Substitution.hxx>
26 #include <BRepBuilderAPI_Sewing.hxx>
27 #include <BRepCheck.hxx>
28 #include <BRepCheck_Edge.hxx>
29 #include <BRepCheck_Shell.hxx>
30
31 #include <TopOpeBRepDS_DSX.hxx>
32
33 #include <TopOpeBRepBuild_Tools.hxx>
34 #include <TopExp_Explorer.hxx>
35 #include <TopExp.hxx>
36 #include <TopTools_IndexedMapOfShape.hxx>
37
38
39 #ifdef DEB
40 Standard_IMPORT Standard_Boolean TopOpeBRepTool_GetcontextNOSEW();
41 #endif
42
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))
46
47 // -------------------------------------------------------------------
48 static void Sub_Classify(TopExp_Explorer& Ex,
49                          const TopAbs_State St1,
50                          TopTools_ListOfShape& Solids2,
51                          BRep_Builder& BB,
52                          TopTools_ListIteratorOfListOfShape& LIter,
53                          TopoDS_Shape& myShape); 
54
55
56 #ifdef DEB
57 Standard_IMPORT Standard_Integer TopOpeBRepTool_BOOOPE_CHECK_DEB;
58 #endif
59
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;
64 //
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
68
69 //=======================================================================
70 //function : Delete 
71 //purpose  : alias ~BRepAlgoAPI_BooleanOperation
72 //=======================================================================
73   void BRepAlgo_BooleanOperation::Delete()
74 {
75   FDSSDM_Close();
76   FDSCNX_Close();
77 }
78 //modified by NIZNHY-PKV Sun Dec 15 17:17:58 2002 t
79
80 //=======================================================================
81 //function : BRepAlgoAPI_BooleanOperation
82 //purpose  : 
83 //=======================================================================
84   BRepAlgo_BooleanOperation::BRepAlgo_BooleanOperation(const TopoDS_Shape& S1, 
85                                                        const TopoDS_Shape& S2)
86 : myS1(S1),myS2(S2),myBuilderCanWork(Standard_False)
87 {
88   TopOpeBRepDS_BuildTool BT;
89   myHBuilder = new TopOpeBRepBuild_HBuilder(BT);
90 }
91
92 //=======================================================================
93 //function : PerformDS
94 //purpose  : 
95 //=======================================================================
96   void BRepAlgo_BooleanOperation::PerformDS()
97 {
98 //  const Standard_Boolean CheckShapes = Standard_True;
99
100   // create a data structure
101   Handle(TopOpeBRepDS_HDataStructure) HDS;
102   if (myHBuilder->DataStructure().IsNull())
103     HDS = new TopOpeBRepDS_HDataStructure();
104   else {
105     HDS = myHBuilder->DataStructure();
106     HDS->ChangeDS().Init();
107   }
108
109 #ifdef DEB
110   TopOpeBRepDS_SettraceSPSX_HDS(HDS);
111 #endif
112
113   // fill the data Structure
114   TopOpeBRep_DSFiller DSFiller;
115  
116   // define face/face intersection tolerances
117   Standard_Boolean forcetoli = Standard_False;
118   if (forcetoli) {
119 #ifndef DEB
120     Standard_Real tolarc=0,toltang=0;
121 #else
122     Standard_Real tolarc,toltang;
123 #endif
124     TopOpeBRep_ShapeIntersector& tobsi = DSFiller.ChangeShapeIntersector();
125     TopOpeBRep_FacesIntersector& tobfi = tobsi.ChangeFacesIntersector();
126     tobfi.ForceTolerances(tolarc,toltang);
127   }
128   DSFiller.Insert(myS1,myS2,HDS);
129
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;
134   if (!esp) {
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);
142         if ( !sp && !de ) {
143           tede = Standard_False;
144           break;
145         }
146       }
147     }
148   }
149   myBuilderCanWork = (esp || tede) ;
150 #ifdef DEB
151   if (!esp) cout<<"BRepAlgo_BooleanOperation(DEB) some edges not SameParameter"<<endl;
152 #endif  
153   if (!myBuilderCanWork) return;
154   
155   Standard_Real tol3dAPPROX = 1e-7;
156   Standard_Real tol2dAPPROX = 1e-7;
157   // set tolerance values used by the APPROX process
158   
159   TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
160   TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
161   GTofBTofBuilder.SetTolerances(tol3dAPPROX,tol2dAPPROX);
162   
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;
169 }
170
171 //=======================================================================
172 //function : Perform
173 //purpose  : 
174 //=======================================================================
175   void  BRepAlgo_BooleanOperation::Perform(const TopAbs_State St1, 
176                                            const TopAbs_State St2)
177 {
178   if ( ! BuilderCanWork() ) {
179     return;
180   }
181
182   // modif JYL suite aux modifs LBR #if MODIF ...
183   // on privilegie le traitement KPart (si c'en est un) 
184   // a tous les autres
185   Standard_Integer kp = myHBuilder->IsKPart();
186   BRep_Builder BB;
187   Standard_Boolean sewing = Standard_True;
188   if ( kp ) {
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;
195
196     BB.MakeCompound(TopoDS::Compound(myShape));
197     Done();
198
199     TopTools_ListIteratorOfListOfShape its(myHBuilder->Merged(myS1,St1));
200     for(; its.More(); its.Next()) BB.Add(myShape,its.Value());
201
202   }
203   else {
204 #if MODIF 
205
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;
212
213     TopTools_ListOfShape Solids1,Solids2,Faces1,Faces2,Edges1,Edges2,Vertex1,Vertex2;
214     TopExp_Explorer Ex;
215     for(Ex.Init(myS1,TopAbs_SOLID),nbs1=0; Ex.More(); Ex.Next()) {
216       Solids1.Append(Ex.Current()); nbs1++;
217     }
218     for(Ex.Init(myS2,TopAbs_SOLID),nbs2=0; Ex.More(); Ex.Next()) { 
219       Solids2.Append(Ex.Current()); nbs2++;
220     }
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++;
224     }
225     for(Ex.Init(myS2,TopAbs_FACE,TopAbs_SOLID),nbf2=0; Ex.More(); Ex.Next())  {
226       Faces2.Append(Ex.Current()); nbf2++;
227     }
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++;
231     }
232     for(Ex.Init(myS2,TopAbs_EDGE,TopAbs_FACE),nbe2=0;  Ex.More(); Ex.Next()) {
233       Edges2.Append(Ex.Current()); nbe2++;
234     }
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++;
238     }
239     for(Ex.Init(myS2,TopAbs_VERTEX,TopAbs_EDGE),nbv2=0;  Ex.More(); Ex.Next()) {
240       Vertex2.Append(Ex.Current()); nbv2++;
241     }
242
243     //-- cout<<"Solids1: "<<nbs1<<"  Faces1: "<<nbf1<<" Edges1:"<<nbe1<<" Vtx1:"<<nbv1<<endl;
244     //-- cout<<"Solids2: "<<nbs2<<"  Faces2: "<<nbf2<<" Edges2:"<<nbe2<<" Vtx2:"<<nbv2<<endl;
245
246     //== 
247
248     //== Reject operations without direction 
249   
250
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;
256       Done();
257       return;
258     }
259
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;
263       Done();
264       return;
265     }
266  
267
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;
271       Done();
272       return;
273     }
274     //======================================================================
275     // make a compound with the new solids
276     BB.MakeCompound(TopoDS::Compound(myShape));
277     
278     TopTools_ListIteratorOfListOfShape LIter;
279     //----------------------------------------------------------------------
280     TopoDS_Shape SNULL;
281     
282     if (nbf1 && nbf2) {
283       SNULL.Nullify();
284       if ( Opecom(St1,St2) ) {
285         TopTools_ListIteratorOfListOfShape itloe = myHBuilder->Section();
286         for(; itloe.More(); itloe.Next()) BB.Add(myShape,itloe.Value());
287       } 
288       else {
289         if(nbf1) { 
290           myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
291
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());
297             }
298             else {
299               const TopoDS_Shape& LV = LIter.Value();
300               if(  (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )        
301                  ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN  )) {
302                 BB.Add(myShape,LV);
303               }
304               else { 
305                 //-- Classify : 
306                 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape); 
307               }
308               //-- End Classification 
309             }
310           }
311         } // nbf1
312         SNULL.Nullify();    
313         if ( Opefus(St1,St2) ) {
314           if(nbf2) {
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());
321               }
322               else {
323                 const TopoDS_Shape& LV = LIter.Value();
324                 if(  (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )      
325                    ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN  )) {
326                   BB.Add(myShape,LV);
327                 }
328                 else { 
329                   //-- Classify : 
330                   Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape); 
331                 }
332                 //-- End Classification         
333               }
334             }
335           } // nbf2
336         } // Fus
337       }
338     } // nbf1 && nbf2
339     else if (nbf1 || nbf2) {
340       SNULL.Nullify();
341       if(nbf1) { 
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;
346
347         sewing = Standard_False;
348
349         if(MergedShapes.Extent() != 0) {
350           TopTools_ListIteratorOfListOfShape its(MergedShapes);
351           for(; its.More(); its.Next()) {
352             BB.Add(myShape,its.Value());
353           }
354           TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
355         }
356
357         for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
358
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());
364             }
365           }
366           else {
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  )) {
371                 BB.Add(myShape,LV);
372               }
373               else { 
374                 //-- Classify : 
375                 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape); 
376               }
377               //-- End Classification 
378             }
379           }
380         }
381       } // nbf1
382       SNULL.Nullify();    
383       if(nbf2) {
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;
389
390         if(MergedShapes.Extent() != 0) {
391           TopTools_ListIteratorOfListOfShape its(MergedShapes);
392           for(; its.More(); its.Next()) {
393             BB.Add(myShape,its.Value());
394           }
395           TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
396         }
397
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());
404             }
405           }
406           else {
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  )) {
411                 BB.Add(myShape,LV);
412               }
413               else { 
414                 //-- Classify : 
415                 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape); 
416               }
417               //-- End Classification   
418             }
419           }
420         }
421       } // nbf2
422     } // (nbf1 || nbf2)
423     
424     //----------------------------------------------------------------------
425     if(nbe1) { 
426       myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
427
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());
434           }
435         }
436         else {
437           const TopoDS_Shape& LV = LIter.Value();
438           if(  (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )            
439              ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN  )) {
440             BB.Add(myShape,LV);
441           }
442           else { 
443             //-- Classify : 
444             Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape); 
445           }
446           //-- End Classification 
447         }
448       }
449     }
450     if(nbe2) { 
451       myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
452       
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());
459           }
460         }
461         else {
462           const TopoDS_Shape& LV = LIter.Value();
463           if(  (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )            
464              ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN  ))  {     
465             BB.Add(myShape,LV);
466           }
467           else { 
468             //-- Classify : 
469             Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape); 
470           }
471           //-- End Classification 
472         }
473       }
474     }
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 
478     if(nbv1 && nbs2) { 
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;
489               SIter.Next()) {     
490             BRepClass3d_SolidClassifier SolClass(SIter.Value());
491             SolClass.Perform(P,Tol);
492             if(SolClass.State() == TopAbs_IN) {
493               ok=Standard_False;
494               keep = Standard_True;
495             }
496           }
497           if(keep) { 
498             BB.Add(myShape,LIter.Value());
499           }
500         }
501       }
502       else { 
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;
513                 SIter.Next()) {           
514               BRepClass3d_SolidClassifier SolClass(SIter.Value());
515               SolClass.Perform(P,Tol);
516               if(SolClass.State() != TopAbs_OUT) {
517                 keep = Standard_False;
518                 ok   = Standard_False;
519               }
520             }
521             if(keep) { 
522               BB.Add(myShape,LIter.Value());
523             }
524           }
525         }
526       }    
527     }
528   
529     if(nbv2 && nbs1) { 
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;
540               SIter.Next()) {     
541             BRepClass3d_SolidClassifier SolClass(SIter.Value());
542             SolClass.Perform(P,Tol);
543             if(SolClass.State() == TopAbs_IN) {
544               ok=Standard_False;
545               keep = Standard_True;
546             }
547           }
548           if(keep) { 
549             BB.Add(myShape,LIter.Value());
550           }
551         }
552       }
553       else { 
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;
564                 SIter.Next()) {           
565               BRepClass3d_SolidClassifier SolClass(SIter.Value());
566               SolClass.Perform(P,Tol);
567               if(SolClass.State() != TopAbs_OUT) {
568                 keep = Standard_False;
569                 ok   = Standard_False;
570               }
571             }
572             if(keep) { 
573               BB.Add(myShape,LIter.Value());
574             }
575           }
576         }
577       }    
578     }
579     
580     if(nbs1 && nbs2 ) { 
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());
588         }
589       }
590     }
591   
592 #else 
593
594     myHBuilder->MergeSolids(myS1,St1,myS2,St2);
595     TopTools_ListIteratorOfListOfShape its;
596   
597     BB.MakeCompound(TopoDS::Compound(myShape));
598     its = myHBuilder->Merged(myS1,St1);
599     while (its.More()) {
600       BB.Add(myShape,its.Value());
601       its.Next();
602     }
603
604 #endif
605 // #if MODIF
606
607   }
608
609   // Creation of the Map used in IsDeleted.
610   TopExp_Explorer ex;
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());
615   
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));
626       if (eTol<cTol) {
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()));
630           if (eTol<cTol) {
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);
634           }
635         }
636       }
637     }
638   }
639
640   Standard_Real maxTol = RealLast();    // MSV: unlimit tolerance
641   TopOpeBRepBuild_Tools::CorrectTolerances(myShape,maxTol);
642
643   TopExp_Explorer ex1, ex2, ex3;
644   TopTools_ListOfShape theOldShell, theNewShell;
645   Standard_Boolean modif =Standard_False;
646
647 #ifdef DEB
648   Standard_Boolean nosew = TopOpeBRepTool_GetcontextNOSEW();
649   if (nosew) sewing = Standard_False;
650 #endif
651
652   if (sewing) {
653     topToSew.Clear();
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());
661         }
662         brts.Perform();
663         ex2.Init(brts.SewedShape(), TopAbs_SHELL);
664         if (ex2.More()) {
665           ex2.Next();
666           if (!ex2.More()) {
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)));
677                 }
678               }
679             }
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()));
683               }
684             }
685           }
686         }
687       }
688     }
689   } // sewing
690
691   if (modif) {
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();
699       forSub.Clear();
700     }
701     bsub.Build(myShape);
702     if (bsub.IsCopied(myShape)) {
703       myShape=(bsub.Copy(myShape)).First();
704     }
705   }
706   
707   Done();
708 }
709
710
711
712 //=======================================================================
713 //function : Builder
714 //purpose  : 
715 //=======================================================================
716   Handle(TopOpeBRepBuild_HBuilder) BRepAlgo_BooleanOperation::Builder()const 
717 {
718   return myHBuilder;
719 }
720
721
722 //=======================================================================
723 //function : TopoDS_Shape&
724 //purpose  : 
725 //=======================================================================
726   const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape1() const 
727 {
728   return myS1;
729 }
730
731
732 //=======================================================================
733 //function : TopoDS_Shape&
734 //purpose  : 
735 //=======================================================================
736   const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape2() const 
737 {
738   return myS2;
739 }
740
741 //=======================================================================
742 //function : BuilderCanWork
743 //purpose  : 
744 //=======================================================================
745   void BRepAlgo_BooleanOperation::BuilderCanWork(const Standard_Boolean Val)
746 {
747   myBuilderCanWork = Val;
748 }
749
750 //=======================================================================
751 //function : BuilderCanWork
752 //purpose  : 
753 //=======================================================================
754   Standard_Boolean BRepAlgo_BooleanOperation::BuilderCanWork() const
755 {
756   return myBuilderCanWork;
757 }
758
759
760 void Sub_Classify(TopExp_Explorer& Ex,
761                   const TopAbs_State St1,
762                   TopTools_ListOfShape& Solids2,
763                   BRep_Builder& BB,
764                   TopTools_ListIteratorOfListOfShape& LIter,
765                   TopoDS_Shape& myShape) { 
766   Ex.Init(LIter.Value(),TopAbs_VERTEX);
767   if(Ex.More()) { 
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;
777           SIter.Next()) {         
778         BRepClass3d_SolidClassifier SolClass(SIter.Value());
779         SolClass.Perform(P,Tol);
780         if(SolClass.State() == TopAbs_IN) {
781           ok=Standard_False;
782           keep = Standard_True;
783         }
784       }
785       if(keep) { 
786         BB.Add(myShape,LIter.Value());
787       }
788     }
789     else { 
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;
799             SIter.Next()) {       
800           BRepClass3d_SolidClassifier SolClass(SIter.Value());
801           SolClass.Perform(P,Tol);
802           if(SolClass.State() != TopAbs_OUT) {
803             keep = Standard_False;
804             ok   = Standard_False;
805           }
806         }
807         if(keep) { 
808           BB.Add(myShape,LIter.Value());
809         }
810       }
811     }
812   }
813 }
814
815
816 //=======================================================================
817 //function : InitParameters
818 //purpose  : Info on geometry : PCurve, Approx, ...
819 //=======================================================================
820 void BRepAlgo_BooleanOperation::InitParameters()
821 {
822   TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
823   TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
824
825   GTofBTofBuilder.Define(TopOpeBRepTool_APPROX);
826   GTofBTofBuilder.DefineCurves(Standard_True);
827   GTofBTofBuilder.DefinePCurves1(Standard_True);
828   GTofBTofBuilder.DefinePCurves2(Standard_True);
829 }
830
831 //=======================================================================
832 //function : Modified
833 //purpose  : 
834 //=======================================================================
835 const TopTools_ListOfShape& BRepAlgo_BooleanOperation::Modified(const TopoDS_Shape& S) 
836 {
837   myGenerated.Clear();
838   TopTools_MapOfShape aMap; // to check if shape can be added in list more then one time
839   aMap.Clear();
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()));}
845       else
846         {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
847     }
848   }
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()));}
854       else
855         {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
856     }
857   }
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()));}
863       else
864         {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
865     }
866   }
867
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()));}
873       else
874         {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
875     }
876   }
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()));}
882       else
883         {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
884     }
885   }
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()));}
891       else
892         {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
893     }
894   }
895   return myGenerated;
896 }
897
898
899 //=======================================================================
900 //function : IsDeleted
901 //purpose  : 
902 //=======================================================================
903 Standard_Boolean BRepAlgo_BooleanOperation::IsDeleted(const TopoDS_Shape& S) 
904 {
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;
914
915   return Deleted;    
916 }