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