0026431: Can't cut a sphere from a cylinder
[occt.git] / src / BRepAlgo / BRepAlgo_BooleanOperations.cxx
CommitLineData
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 42BRepAlgo_BooleanOperations::BRepAlgo_BooleanOperations() :
7fd59977 43myApproxNbPntMax (30) ,
44myApproxTol3D (1.e-7) ,
4e14c88f 45myApproxTol2D (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