0cba54c3f1497b7ac0f2ff245ac8f5abbeafc311
[occt.git] / src / BRepAlgo / BRepAlgo_BooleanOperations.cxx
1 // Created on: 1997-11-20
2 // Created by: Prestataire Mary FABIEN
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Bnd_Box.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAlgo_BooleanOperations.hxx>
22 #include <BRepAlgo_DSAccess.hxx>
23 #include <BRepBndLib.hxx>
24 #include <BRepTools_Substitution.hxx>
25 #include <Geom_Surface.hxx>
26 #include <TopLoc_Location.hxx>
27 #include <TopoDS.hxx>
28 #include <TopoDS_Compound.hxx>
29 #include <TopoDS_Shape.hxx>
30 #include <TopOpeBRep_DSFiller.hxx>
31 #include <TopOpeBRepBuild_HBuilder.hxx>
32 #include <TopOpeBRepDS_BuildTool.hxx>
33 #include <TopOpeBRepDS_HDataStructure.hxx>
34 #include <TopOpeBRepTool_GeomTool.hxx>
35 #include <TopTools_ListIteratorOfListOfShape.hxx>
36 #include <TopTools_ListOfShape.hxx>
37
38 //=======================================================================
39 //function : Create
40 //purpose  : 
41 //=======================================================================
42 BRepAlgo_BooleanOperations::BRepAlgo_BooleanOperations() :
43 myApproxNbPntMax (30) ,
44 myApproxTol3D (1.e-7) ,
45 myApproxTol2D (1.e-7) ,
46 myApproxRelativeTol (Standard_True)
47 {
48 }
49
50 //=======================================================================
51 //function : Shapes2d
52 //purpose  : 
53 //=======================================================================
54   void BRepAlgo_BooleanOperations::Shapes2d (const TopoDS_Shape& S1,
55                                             const TopoDS_Shape& S2) 
56 {
57   // S1 doit etre une face ou un ensemble de faces
58   // S2 doit etre une edge.
59
60   if (S2.ShapeType() != TopAbs_EDGE) return;
61
62   BRep_Builder Builder ;
63   TopoDS_Wire Wire ;
64   Builder.MakeWire (Wire);
65   Builder.Add (Wire, S2);
66   
67   TopExp_Explorer Exp (S1, TopAbs_FACE) ;
68   if (!Exp.More()) return ;
69   const TopoDS_Face& FirstFace = TopoDS::Face (Exp.Current()) ;
70
71   TopLoc_Location Loc;
72   const Handle(Geom_Surface)& Surf = BRep_Tool::Surface (FirstFace, Loc) ; 
73
74   TopoDS_Face Face ;
75   Builder.MakeFace (Face, Surf, Loc, BRep_Tool::Tolerance (FirstFace)) ;
76   Builder.Add (Face, Wire) ;
77   Face.Orientation (FirstFace.Orientation()) ;
78   
79   myS1 = S1 ;
80   myS2 = Face ;
81
82   myDSA.Init() ;
83   myDSA.Load (myS1, myS2) ;
84   Handle (TopOpeBRepDS_HDataStructure)& HDS = myDSA.ChangeDS() ;
85   myDSA.myDSFiller.Insert2d (myS1, myS2, HDS) ;
86 }
87
88 //=======================================================================
89 //function : Shapes
90 //purpose  : Defines the arguments.
91 //=======================================================================
92   void BRepAlgo_BooleanOperations::Shapes (const TopoDS_Shape& S1,
93                                            const TopoDS_Shape& S2)
94 {
95   myS1 = S1;
96   myS2 = S2;
97   myDSA.Init();
98   myDSA.Load(myS1, myS2);
99   Handle(TopOpeBRepDS_HDataStructure)& HDS = myDSA.ChangeDS();
100   myDSA.myDSFiller.Insert(myS1,myS2,HDS);
101   //  const Standard_Boolean CheckShapes = Standard_True;
102   //  Standard_Boolean esp = HDS->EdgesSameParameter();
103   //  Standard_Boolean localcheck = CheckShapes;
104 }
105
106 //=======================================================================
107 //function : SetApproxParameters
108 //purpose  : Sets the parameters for the approximations.
109 //=======================================================================
110   void BRepAlgo_BooleanOperations::SetApproxParameters (const Standard_Integer NbPntMax,
111                                                         const Standard_Real Tol3D,
112                                                         const Standard_Real Tol2D,
113                                                         const Standard_Boolean RelativeTol)
114 {
115   myApproxNbPntMax = NbPntMax ;
116   myApproxTol3D = Tol3D ;
117   myApproxTol2D = Tol2D ;
118   myApproxRelativeTol = RelativeTol ;
119 }
120
121 //=======================================================================
122 //function : Define
123 //purpose  : 
124 //=======================================================================
125   void BRepAlgo_BooleanOperations::Define (const TopoDS_Shape& S1,
126                                            const TopoDS_Shape& S2,
127                                            Handle(TopOpeBRepDS_HDataStructure)& HDS)
128 {
129   ChangeDataStructure() = HDS;
130   myS1 = S1;
131   myS2 = S2;
132 }
133
134 //=======================================================================
135 //function : Perform
136 //purpose  : Performs the global boolean operation.
137 //=======================================================================
138   void BRepAlgo_BooleanOperations::Perform ()
139 {
140   TopOpeBRepDS_BuildTool& BTofBuilder = myDSA.myHB->ChangeBuildTool();
141   TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
142   GTofBTofBuilder.SetNbPntMax(myApproxNbPntMax);
143   GTofBTofBuilder.SetTolerances (myApproxTol3D, myApproxTol2D, myApproxRelativeTol) ;
144   Handle(TopOpeBRepBuild_HBuilder)& HB = myDSA.myHB;
145   Handle(TopOpeBRepDS_HDataStructure)& HDS = myDSA.ChangeDS();
146   HB->Perform(HDS,myS1,myS2);
147 }
148
149 //=======================================================================
150 //function : Perform
151 //purpose  : Performs the global boolean operation in regards of the
152 //           given states.
153 //=======================================================================
154   void BRepAlgo_BooleanOperations::Perform (const TopAbs_State State1,
155                                            const TopAbs_State State2)
156 {
157   Perform() ;
158
159   myShape.Nullify() ;
160   myResult.Nullify() ;
161   myMapShape.Clear() ;
162
163   Handle(TopOpeBRepBuild_HBuilder)& HBuilder = ChangeBuilder() ;
164   HBuilder->MergeShapes (myS1, State1, myS2, State2) ;
165
166   const TopTools_ListOfShape& ListResults = HBuilder->Merged (myS1, State1) ;
167   Standard_Integer NbResults = ListResults.Extent() ;
168   if (NbResults > 0) {
169     if (NbResults == 1) {
170       myShape = ListResults.First() ;
171     } else {
172       BRep_Builder Builder ;
173       Builder.MakeCompound (TopoDS::Compound (myShape)) ;
174       TopTools_ListIteratorOfListOfShape Iter ;
175       for (Iter.Initialize (ListResults) ; Iter.More() ; Iter.Next())
176         Builder.Add (myShape, Iter.Value()) ;
177     }
178     TopExp_Explorer Explorer ;
179     for (Explorer.Init (myShape, TopAbs_FACE) ; Explorer.More() ; Explorer.Next()) {
180       myMapShape.Add (Explorer.Current()) ;
181     }
182     for (Explorer.Init (myShape, TopAbs_EDGE) ; Explorer.More() ; Explorer.Next()) {
183       myMapShape.Add (Explorer.Current()) ;
184     }
185   }
186 }
187
188 //=======================================================================
189 //function : Common
190 //purpose  : 
191 //=======================================================================
192   const TopoDS_Shape& BRepAlgo_BooleanOperations::Common() 
193 {
194   Perform (TopAbs_IN, TopAbs_IN) ;
195   return myShape ;
196 }
197
198 //=======================================================================
199 //function : fus
200 //purpose  : 
201 //=======================================================================
202   const TopoDS_Shape& BRepAlgo_BooleanOperations::Fus() 
203 {
204   Perform (TopAbs_OUT, TopAbs_OUT) ;
205   return myShape ;
206 }
207
208 //=======================================================================
209 //function : cut
210 //purpose  : 
211 //=======================================================================
212   const TopoDS_Shape& BRepAlgo_BooleanOperations::Cut() 
213 {
214   Perform (TopAbs_OUT, TopAbs_IN) ;
215   return myShape ;
216 }
217
218 //=======================================================================
219 //function : Section
220 //purpose  : 
221 //=======================================================================
222   const TopoDS_Shape& BRepAlgo_BooleanOperations::Section() 
223 {
224 //  Standard_Boolean bcw = BuilderCanWork();
225 //  if ( ! bcw || myshapeisnull) return;
226
227   Perform () ;
228
229   myShape.Nullify() ;
230   myResult.Nullify() ;
231   myMapShape.Clear() ;
232   
233   Handle(TopOpeBRepBuild_HBuilder)& HBuilder = myDSA.myHB ;
234
235   const TopTools_ListOfShape& ListResults = HBuilder->Section() ;
236   Standard_Integer NbResults = ListResults.Extent() ;
237   if (NbResults > 0) {
238     if (NbResults == 1) {
239       myShape = ListResults.First() ;
240     } else {
241       BRep_Builder Builder ;
242       Builder.MakeCompound (TopoDS::Compound (myShape)) ;
243       TopTools_ListIteratorOfListOfShape Iter ;
244       for (Iter.Initialize (ListResults) ; Iter.More() ; Iter.Next())
245         Builder.Add (myShape, Iter.Value()) ;
246     }
247     TopExp_Explorer Explorer ;
248     for (Explorer.Init (myShape, TopAbs_EDGE) ; Explorer.More() ; Explorer.Next()) {
249       myMapShape.Add (Explorer.Current()) ;
250     }
251   }
252
253   return myShape ;
254 }
255
256 //=======================================================================
257 //function : Shape
258 //purpose  : 
259 //=======================================================================
260   const TopoDS_Shape& BRepAlgo_BooleanOperations::Shape() 
261 {
262   return myShape;
263 }
264
265 //=======================================================================
266 //function : Shape
267 //purpose  : 
268 //=======================================================================
269   const TopoDS_Shape& BRepAlgo_BooleanOperations::ShapeFrom (const TopoDS_Shape& Shape) 
270 {
271   myResult.Nullify() ;
272
273   if (!myShape.IsNull()) {
274     
275     TopoDS_Shape ShapeToDel ;
276     if (Shape.IsSame (myS1)) {
277       ShapeToDel = myS2 ;
278     } else {
279       ShapeToDel = myS1 ;
280     }
281
282     BRepTools_Substitution Substitute ;
283
284     TopTools_ListOfShape NullFaces ;
285     NullFaces.Clear() ;
286
287     TopExp_Explorer ExpFac ;
288     for (ExpFac.Init (ShapeToDel, TopAbs_FACE) ; ExpFac.More() ; ExpFac.Next()) {
289       const TopoDS_Face& Face = TopoDS::Face (ExpFac.Current()) ;
290       const TopTools_ListOfShape& ListResults = Modified (Face) ;
291       if (ListResults.Extent() == 0) {
292         if (myMapShape.Contains (Face)) Substitute.Substitute (Face, NullFaces) ;
293       } else {
294         TopTools_ListIteratorOfListOfShape ItrFace ;
295         for (ItrFace.Initialize (ListResults) ; ItrFace.More() ; ItrFace.Next()) {
296           Substitute.Substitute (TopoDS::Face (ItrFace.Value()), NullFaces) ;
297         }
298       }
299     }
300
301     Substitute.Build (myShape) ;
302     if (Substitute.IsCopied (myShape)) {
303       const TopTools_ListOfShape& ListResults = Substitute.Copy (myShape) ;
304       Standard_Integer NbResults = ListResults.Extent() ;
305       if (NbResults == 1) {
306         myResult = ListResults.First() ;
307       } else if (NbResults > 1) {
308         BRep_Builder Builder ;
309         Builder.MakeCompound (TopoDS::Compound (myResult)) ;
310         TopTools_ListIteratorOfListOfShape ItrResult ;
311         for (ItrResult.Initialize (ListResults) ; ItrResult.More() ; ItrResult.Next()) {
312           Builder.Add (myResult, ItrResult.Value()) ;
313         }
314       }
315     } else {
316       myResult = myShape ;
317     }
318
319   }  
320   return myResult ;
321 }
322
323 //=======================================================================
324 //function : Modified
325 //purpose  : 
326 //=======================================================================
327   const TopTools_ListOfShape& BRepAlgo_BooleanOperations::Modified (const TopoDS_Shape& Shape) 
328 {
329   return myDSA.Modified(Shape);
330 }
331
332 //=======================================================================
333 //function : IsDeleted
334 //purpose  : 
335 //=======================================================================
336   Standard_Boolean BRepAlgo_BooleanOperations::IsDeleted (const TopoDS_Shape& Shape)
337 {
338   Standard_Boolean Deleted = Standard_True ; 
339
340   Handle(TopOpeBRepBuild_HBuilder)& HBuilder = myDSA.myHB ;
341
342   if (   myMapShape.Contains (Shape)
343       || HBuilder->IsMerged (Shape, TopAbs_OUT)
344       || HBuilder->IsMerged (Shape, TopAbs_IN)
345       || HBuilder->IsMerged (Shape, TopAbs_ON)
346       || HBuilder->IsSplit (Shape, TopAbs_OUT)
347       || HBuilder->IsSplit (Shape, TopAbs_IN)
348       || HBuilder->IsSplit (Shape, TopAbs_ON))
349     Deleted = Standard_False ;
350
351   return Deleted ;    
352 }
353
354 //=======================================================================
355 //function : DataStructure
356 //purpose  : 
357 //=======================================================================
358   const Handle(TopOpeBRepDS_HDataStructure)& BRepAlgo_BooleanOperations::DataStructure() const
359 {
360   return myDSA.DS();
361 }
362
363 //=======================================================================
364 //function : DataStructure
365 //purpose  : 
366 //=======================================================================
367   Handle(TopOpeBRepDS_HDataStructure)& BRepAlgo_BooleanOperations::ChangeDataStructure()
368 {
369   return myDSA.ChangeDS();
370 }
371
372 //=======================================================================
373 //function : Builder
374 //purpose  : 
375 //=======================================================================
376   const Handle(TopOpeBRepBuild_HBuilder)& BRepAlgo_BooleanOperations::Builder() const 
377 {
378   return myDSA.Builder();
379 }
380
381 //=======================================================================
382 //function : Builder
383 //purpose  : 
384 //=======================================================================
385   Handle(TopOpeBRepBuild_HBuilder)& BRepAlgo_BooleanOperations::ChangeBuilder() 
386 {
387   return myDSA.ChangeBuilder();
388 }
389
390 //=======================================================================
391 //function : DataStructureAccess
392 //purpose  : returns the member myDSA.
393 //=======================================================================
394   BRepAlgo_DSAccess& BRepAlgo_BooleanOperations::DataStructureAccess()
395 {
396   return myDSA;
397 }
398