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