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