b311480e |
1 | // Created on: 1997-11-20 |
2 | // Created by: Prestataire Mary FABIEN |
3 | // Copyright (c) 1997-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
42cf5bc1 |
17 | |
18 | #include <Bnd_Box.hxx> |
7fd59977 |
19 | #include <BRep_Builder.hxx> |
42cf5bc1 |
20 | #include <BRep_Tool.hxx> |
21 | #include <BRepAlgo_BooleanOperations.hxx> |
22 | #include <BRepAlgo_DSAccess.hxx> |
23 | #include <BRepBndLib.hxx> |
7fd59977 |
24 | #include <BRepTools_Substitution.hxx> |
42cf5bc1 |
25 | #include <Geom_Surface.hxx> |
26 | #include <TopLoc_Location.hxx> |
7fd59977 |
27 | #include <TopoDS.hxx> |
28 | #include <TopoDS_Compound.hxx> |
42cf5bc1 |
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> |
7fd59977 |
35 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
42cf5bc1 |
36 | #include <TopTools_ListOfShape.hxx> |
7fd59977 |
37 | |
38 | //======================================================================= |
39 | //function : Create |
40 | //purpose : |
41 | //======================================================================= |
b311480e |
42 | BRepAlgo_BooleanOperations::BRepAlgo_BooleanOperations() : |
7fd59977 |
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 | |