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