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