0024624: Lost word in license statement in source files
[occt.git] / src / BRepAlgoAPI / BRepAlgoAPI_BooleanOperation.cxx
CommitLineData
b311480e 1// Created on: 1993-10-15
2// Created by: Remi LEQUETTE
3// Copyright (c) 1993-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.
b311480e 16
7fd59977 17#include <BRepAlgoAPI_BooleanOperation.ixx>
18
da219023 19#include <BRepAlgoAPI.hxx>
20#include <BRepAlgoAPI_Check.hxx>
21
7fd59977 22#include <BRepLib_FuseEdges.hxx>
23#include <TopExp.hxx>
24#include <TopTools_MapOfShape.hxx>
25#include <TopTools_ListIteratorOfListOfShape.hxx>
26
4e57c75e 27#include <BOPAlgo_PaveFiller.hxx>
28#include <BOPAlgo_BOP.hxx>
29#include <BOPDS_DS.hxx>
7fd59977 30
31//=======================================================================
32//function : BRepAlgoAPI_BooleanOperation
33//purpose :
34//=======================================================================
35 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation(const TopoDS_Shape& aS1,
4e57c75e 36 const TopoDS_Shape& aS2,
37 const BOPAlgo_Operation anOp)
7fd59977 38:
39 myS1(aS1),
40 myS2(aS2),
41 myBuilderCanWork(Standard_False),
42 myOperation(anOp),
43 myErrorStatus(1),
44 myDSFiller(NULL),
45 myBuilder(NULL),
46 myEntryType(1),
47 myFuseEdges(Standard_False)
48{
49}
50//=======================================================================
51//function : BRepAlgoAPI_BooleanOperation
52//purpose :
53//=======================================================================
54 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation(const TopoDS_Shape& aS1,
4e57c75e 55 const TopoDS_Shape& aS2,
56 const BOPAlgo_PaveFiller& aDSFiller,
57 const BOPAlgo_Operation anOp)
7fd59977 58:
59 myS1(aS1),
60 myS2(aS2),
61 myBuilderCanWork(Standard_False),
62 myOperation(anOp),
63 myErrorStatus(1),
64 myDSFiller(NULL),
65 myBuilder(NULL),
66 myEntryType(0),
67 myFuseEdges(Standard_False)
68{
69 if ((Standard_Address) &aDSFiller!=NULL) {
4e57c75e 70 myDSFiller=(BOPAlgo_PaveFiller*)&aDSFiller;
7fd59977 71 }
72}
73//=======================================================================
74//function : Destroy
75//purpose :
76//=======================================================================
77 void BRepAlgoAPI_BooleanOperation::Destroy()
78{
79 if (myBuilder!=NULL) {
80 delete myBuilder;
81 myBuilder=NULL;
82 }
83 if (myDSFiller!=NULL && myEntryType) {
84 delete myDSFiller;
85 myDSFiller=NULL;
86 }
4e57c75e 87
88 //
89 myModifFaces.Clear();
90 myEdgeMap.Clear();
7fd59977 91}
92//=======================================================================
93//function : SetOperation
94//purpose :
95//=======================================================================
4e57c75e 96 void BRepAlgoAPI_BooleanOperation::SetOperation (const BOPAlgo_Operation anOp)
7fd59977 97{
98 myOperation=anOp;
99}
100//=======================================================================
101//function : Operation
102//purpose :
103//=======================================================================
4e57c75e 104 BOPAlgo_Operation BRepAlgoAPI_BooleanOperation::Operation ()const
7fd59977 105{
106 return myOperation;
107}
108
109//=======================================================================
110//function : FuseEdges
111//purpose :
112//=======================================================================
113 Standard_Boolean BRepAlgoAPI_BooleanOperation::FuseEdges ()const
114{
115 return myFuseEdges;
116}
117
118//=======================================================================
119//function : Shape1
120//purpose :
121//=======================================================================
122 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape1() const
123{
124 return myS1;
125}
126
127//=======================================================================
128//function : Shape2
129//purpose :
130//=======================================================================
131 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape2() const
132{
133 return myS2;
134}
135
136//=======================================================================
137//function : BuilderCanWork
138//purpose :
139//=======================================================================
140 Standard_Boolean BRepAlgoAPI_BooleanOperation::BuilderCanWork() const
141{
142 return myBuilderCanWork;
143}
144//=======================================================================
145//function : ErrorStatus
146//purpose :
147//=======================================================================
148 Standard_Integer BRepAlgoAPI_BooleanOperation::ErrorStatus()const
149{
150 return myErrorStatus;
151}
152//=======================================================================
153//function : Modified
154//purpose :
155//=======================================================================
156const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Modified(const TopoDS_Shape& aS)
157{
158 if (myBuilder==NULL) {
159 myGenerated.Clear();
160 return myGenerated;
161 }
162 else {
4e57c75e 163 myGenerated = myBuilder->Modified(aS);
7fd59977 164
165 if(myFuseEdges) {
4e57c75e 166 TopTools_ListOfShape theLS;
167 theLS.Assign(myGenerated);
168 //
169 RefinedList(theLS);
7fd59977 170 }
4e57c75e 171 return myGenerated;
7fd59977 172 }
173}
174
175//=======================================================================
176//function : IsDeleted
177//purpose :
178//=======================================================================
179 Standard_Boolean BRepAlgoAPI_BooleanOperation::IsDeleted(const TopoDS_Shape& aS)
180{
4e57c75e 181 Standard_Boolean bDeleted = Standard_True;
182 if (myBuilder != NULL) {
183 bDeleted=myBuilder->IsDeleted(aS);
7fd59977 184 }
4e57c75e 185 return bDeleted;
7fd59977 186}
4e57c75e 187
7fd59977 188//=======================================================================
189//function : PrepareFiller
190//purpose :
191//=======================================================================
192 Standard_Boolean BRepAlgoAPI_BooleanOperation::PrepareFiller()
193{
194 Standard_Boolean bIsNewFiller=Standard_False;
195 myErrorStatus=1;
196 //
197 if (myS1.IsNull() || myS2.IsNull()) {
198 myErrorStatus=2;
199 return bIsNewFiller;
200 }
201 //
4e57c75e 202 if (myOperation==BOPAlgo_UNKNOWN) {
7fd59977 203 myErrorStatus=6;
204 return bIsNewFiller;
205 }
206 //
207 if (myDSFiller==NULL) {
208 bIsNewFiller=!bIsNewFiller;
209
4e57c75e 210 myDSFiller=new BOPAlgo_PaveFiller;
7fd59977 211 //
212 if (myDSFiller==NULL) {
213 myErrorStatus=4;
214 return bIsNewFiller;
215 }
216 //
4e57c75e 217 BOPCol_ListOfShape aLS;
218 aLS.Append(myS1);
219 aLS.Append(myS2);
220 //
221 myDSFiller->SetArguments(aLS);
7fd59977 222 }
223
224 return bIsNewFiller;
225}
226//=======================================================================
227//function : Build
228//purpose :
229//=======================================================================
230 void BRepAlgoAPI_BooleanOperation::Build()
231{
4e57c75e 232 Standard_Boolean bIsNewFiller;
233 Standard_Integer iErr;
7fd59977 234 //
da219023 235 //dump arguments and result of boolean operation in tcl script
236 char *pathdump = getenv("CSF_DEBUG_BOP");
237 Standard_Boolean isDump = (pathdump != NULL),
238 isDumpArgs = Standard_False,
239 isDumpRes = Standard_False;
240 Standard_CString aPath = pathdump;
241 //
7fd59977 242 myBuilderCanWork=Standard_False;
243 NotDone();
244 //
245 bIsNewFiller=PrepareFiller();
246 //
247 if (myErrorStatus!=1) {
248 // there was errors during the preparation
249 return;
250 }
251 //
252 if (bIsNewFiller) {
253 //Prepare the DS
254 myDSFiller->Perform();
255 }
256 //
257 if (myBuilder!=NULL) {
258 delete myBuilder;
259 myBuilder=NULL;
260 }
261 //
4e57c75e 262 const TopoDS_Shape& aS1 = myS1;
263 const TopoDS_Shape& aS2 = myS2;
7fd59977 264 //
da219023 265 if (isDump) {
266 BRepAlgoAPI_Check aChekArgs(aS1, aS2, myOperation);
267 isDumpArgs = !aChekArgs.IsValid();
268 }
269 //
7fd59977 270 myShape.Nullify();
7fd59977 271
4e57c75e 272 myBuilder=new BOPAlgo_BOP;
273 myBuilder->AddArgument(aS1);
274 myBuilder->AddTool(aS2);
275 myBuilder->SetOperation(myOperation);
7fd59977 276 //
4e57c75e 277 myBuilder->PerformWithFiller(*myDSFiller);
278 iErr = myBuilder->ErrorStatus();
279 if (!iErr) {
7fd59977 280 myErrorStatus=0;
281 myBuilderCanWork=Standard_True;
4e57c75e 282 myShape=myBuilder->Shape();
da219023 283 //
284 if (isDump) {
285 BRepAlgoAPI_Check aCheckRes(myShape);
286 isDumpRes = !aCheckRes.IsValid();
287 if (isDumpArgs || isDumpRes) {
288 BRepAlgoAPI::DumpOper(aPath, aS1, aS2, myShape, myOperation, isDumpArgs);
289 }
290 }
291 //
7fd59977 292 Done();
4e57c75e 293 }
7fd59977 294 else {
4e57c75e 295 myErrorStatus=100+iErr;
7fd59977 296 NotDone();
297 }
298}
299
300//
301//=======================================================================
302//function : SectionEdges
303//purpose :
304//=======================================================================
305const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::SectionEdges()
306{
307 if (myBuilder==NULL) {
308 myGenerated.Clear();
309 return myGenerated;
310 }
4e57c75e 311 //
312 Standard_Integer aNb, i, j, aNbCurves, nE;
313 BOPDS_ListIteratorOfListOfPaveBlock anIt;
314 //
315 const BOPDS_PDS& pDS = myDSFiller->PDS();
316 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
317 myGenerated.Clear();
318 //
319 aNb=aFFs.Extent();
320 for (i = 0; i < aNb; i++) {
321 BOPDS_InterfFF& aFFi=aFFs(i);
322 const BOPDS_VectorOfCurve& aSeqOfCurve=aFFi.Curves();
323 //
324 aNbCurves=aSeqOfCurve.Extent();
325 for (j=0; j<aNbCurves; j++) {
326 const BOPDS_Curve& aCurve=aSeqOfCurve(j);
327 const BOPDS_ListOfPaveBlock& aSectEdges = aCurve.PaveBlocks();
328 //
329 anIt.Initialize(aSectEdges);
330 for(; anIt.More(); anIt.Next()) {
331 const Handle(BOPDS_PaveBlock)& aPB = anIt.Value();
332 nE = aPB->Edge();
333 const TopoDS_Shape& aE = pDS->Shape(nE);
334 myGenerated.Append(aE);
335 }
7fd59977 336 }
7fd59977 337 }
4e57c75e 338 //
339 if(myFuseEdges) {
340 TopTools_ListOfShape theLS;
341 theLS.Assign(myGenerated);
342 //
343 RefinedList(theLS);
344 }
345 //
346 return myGenerated;
7fd59977 347}
7fd59977 348
349// ================================================================================================
7fd59977 350// function: Generated
351// purpose:
352// ================================================================================================
353const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Generated(const TopoDS_Shape& S)
354{
4e57c75e 355 if (myBuilder==NULL) {
7fd59977 356 myGenerated.Clear();
357 return myGenerated;
358 }
4e57c75e 359 //
7fd59977 360 if(myFuseEdges) {
4e57c75e 361 const TopTools_ListOfShape& aL = myBuilder->Generated(S);
7fd59977 362 return RefinedList(aL);
363 }
4e57c75e 364
365 return myBuilder->Generated(S);
7fd59977 366}
367
368// ================================================================================================
369// function: HasModified
370// purpose:
371// ================================================================================================
372Standard_Boolean BRepAlgoAPI_BooleanOperation::HasModified() const
373{
4e57c75e 374 if (myBuilder==NULL) {
7fd59977 375 return Standard_False;
376 }
4e57c75e 377 return myBuilder->HasModified();
7fd59977 378}
379
380// ================================================================================================
381// function: HasGenerated
382// purpose:
383// ================================================================================================
384Standard_Boolean BRepAlgoAPI_BooleanOperation::HasGenerated() const
385{
4e57c75e 386 if (myBuilder==NULL) {
7fd59977 387 return Standard_False;
388 }
4e57c75e 389 return myBuilder->HasGenerated();
7fd59977 390}
391
392// ================================================================================================
393// function: HasDeleted
394// purpose:
395// ================================================================================================
396Standard_Boolean BRepAlgoAPI_BooleanOperation::HasDeleted() const
397{
4e57c75e 398 if (myBuilder==NULL) {
7fd59977 399 return Standard_False;
400 }
4e57c75e 401 return myBuilder->HasDeleted();
7fd59977 402}
403//=======================================================================
404//function : RefineEdges
405//purpose :
406//=======================================================================
407
408 void BRepAlgoAPI_BooleanOperation::RefineEdges ()
409{
7fd59977 410 if(myFuseEdges) return; //Edges have been refined yet
411
412 BRepLib_FuseEdges FE(myShape);
413 FE.SetConcatBSpl(Standard_True);
414
415 // avoid fusing old edges
416 TopTools_IndexedMapOfShape mapOldEdges;
417 TopExp::MapShapes (myS1, TopAbs_EDGE, mapOldEdges);
418 TopExp::MapShapes (myS2, TopAbs_EDGE, mapOldEdges);
419 FE.AvoidEdges (mapOldEdges);
420
421 // Get List of edges that have been fused
422 myFuseEdges = Standard_False;
423 myModifFaces.Clear();
424 myEdgeMap.Clear();
425 TopTools_DataMapOfIntegerListOfShape aFusedEdges;
426
427 FE.Edges(aFusedEdges);
428 Standard_Integer nle = aFusedEdges.Extent();
429 if (nle != 0) {
430 FE.Perform();
431 myShape = FE.Shape();
432
433 TopTools_DataMapOfIntegerShape aResultEdges;
434
435 FE.ResultEdges(aResultEdges);
436 FE.Faces(myModifFaces);
437 myFuseEdges = Standard_True;
7fd59977 438
439 Standard_Integer i;
440 for(i = 1; i <= nle; ++i) {
441 const TopoDS_Shape& aNewE = aResultEdges(i);
442 const TopTools_ListOfShape& aListOfOldEdges = aFusedEdges(i);
443 TopTools_ListIteratorOfListOfShape anIter(aListOfOldEdges);
444 for(; anIter.More(); anIter.Next()) {
4e57c75e 445 myEdgeMap.Bind(anIter.Value(), aNewE);
7fd59977 446 }
447 }
448 }
7fd59977 449}
450
451//=======================================================================
452//function : RefinedList
453//purpose :
454//=======================================================================
455const TopTools_ListOfShape&
456 BRepAlgoAPI_BooleanOperation::RefinedList(const TopTools_ListOfShape& theL)
457{
458 myGenerated.Clear();
459 TopTools_MapOfShape aMap;
460
461 TopTools_ListIteratorOfListOfShape anIter(theL);
462
463 for(; anIter.More(); anIter.Next()) {
464 const TopoDS_Shape& anS = anIter.Value();
465
466 if(anS.ShapeType() == TopAbs_EDGE) {
467 if(myEdgeMap.IsBound(anS)) {
4e57c75e 468 const TopoDS_Shape& aNewEdge = myEdgeMap.Find(anS);
469 if(aMap.Add(aNewEdge)) {
470 myGenerated.Append(aNewEdge);
471 }
7fd59977 472 }
473 else {
4e57c75e 474 myGenerated.Append(anS);
7fd59977 475 }
476 }
477 else if (anS.ShapeType() == TopAbs_FACE) {
478 if(myModifFaces.IsBound(anS)) {
4e57c75e 479 myGenerated.Append(myModifFaces.Find(anS));
7fd59977 480 }
481 else {
4e57c75e 482 myGenerated.Append(anS);
7fd59977 483 }
484 }
485 else {
486 myGenerated.Append(anS);
487 }
488 }
489
490 return myGenerated;
491
492}