1 // Created on: 1993-10-15
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <BRepAlgoAPI_BooleanOperation.ixx>
19 #include <BRepAlgoAPI.hxx>
20 #include <BRepAlgoAPI_Check.hxx>
22 #include <BRepLib_FuseEdges.hxx>
24 #include <TopTools_MapOfShape.hxx>
25 #include <TopTools_ListIteratorOfListOfShape.hxx>
27 #include <BOPDS_DS.hxx>
29 #include <BOPAlgo_PaveFiller.hxx>
30 #include <BOPAlgo_BOP.hxx>
31 #include <BOPAlgo_Section.hxx>
34 //=======================================================================
35 //function : BRepAlgoAPI_BooleanOperation
37 //=======================================================================
38 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
39 (const TopoDS_Shape& aS1,
40 const TopoDS_Shape& aS2,
41 const BOPAlgo_Operation anOp)
45 myBuilderCanWork(Standard_False),
51 myFuseEdges(Standard_False)
54 //=======================================================================
55 //function : BRepAlgoAPI_BooleanOperation
57 //=======================================================================
58 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation(const TopoDS_Shape& aS1,
59 const TopoDS_Shape& aS2,
60 const BOPAlgo_PaveFiller& aDSFiller,
61 const BOPAlgo_Operation anOp)
65 myBuilderCanWork(Standard_False),
71 myFuseEdges(Standard_False)
73 if ((Standard_Address) &aDSFiller!=NULL) {
74 myDSFiller=(BOPAlgo_PaveFiller*)&aDSFiller;
77 //=======================================================================
80 //=======================================================================
81 void BRepAlgoAPI_BooleanOperation::Destroy()
83 if (myBuilder!=NULL) {
87 if (myDSFiller!=NULL && myEntryType) {
96 //=======================================================================
97 //function : SetOperation
99 //=======================================================================
100 void BRepAlgoAPI_BooleanOperation::SetOperation (const BOPAlgo_Operation anOp)
104 //=======================================================================
105 //function : Operation
107 //=======================================================================
108 BOPAlgo_Operation BRepAlgoAPI_BooleanOperation::Operation ()const
113 //=======================================================================
114 //function : FuseEdges
116 //=======================================================================
117 Standard_Boolean BRepAlgoAPI_BooleanOperation::FuseEdges ()const
122 //=======================================================================
125 //=======================================================================
126 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape1() const
131 //=======================================================================
134 //=======================================================================
135 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape2() const
140 //=======================================================================
141 //function : BuilderCanWork
143 //=======================================================================
144 Standard_Boolean BRepAlgoAPI_BooleanOperation::BuilderCanWork() const
146 return myBuilderCanWork;
148 //=======================================================================
149 //function : ErrorStatus
151 //=======================================================================
152 Standard_Integer BRepAlgoAPI_BooleanOperation::ErrorStatus()const
154 return myErrorStatus;
156 //=======================================================================
157 //function : Modified
159 //=======================================================================
160 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Modified(const TopoDS_Shape& aS)
162 if (myBuilder==NULL) {
167 myGenerated = myBuilder->Modified(aS);
170 TopTools_ListOfShape theLS;
171 theLS.Assign(myGenerated);
179 //=======================================================================
180 //function : IsDeleted
182 //=======================================================================
183 Standard_Boolean BRepAlgoAPI_BooleanOperation::IsDeleted(const TopoDS_Shape& aS)
185 Standard_Boolean bDeleted = Standard_True;
186 if (myBuilder != NULL) {
187 bDeleted=myBuilder->IsDeleted(aS);
192 //=======================================================================
193 //function : PrepareFiller
195 //=======================================================================
196 Standard_Boolean BRepAlgoAPI_BooleanOperation::PrepareFiller()
198 Standard_Boolean bIsNewFiller=Standard_False;
201 if (myS1.IsNull() || myS2.IsNull()) {
206 if (myOperation==BOPAlgo_UNKNOWN) {
211 if (myDSFiller==NULL) {
212 bIsNewFiller=!bIsNewFiller;
214 myDSFiller=new BOPAlgo_PaveFiller;
216 if (myDSFiller==NULL) {
221 BOPCol_ListOfShape aLS;
225 myDSFiller->SetArguments(aLS);
230 //=======================================================================
233 //=======================================================================
234 void BRepAlgoAPI_BooleanOperation::Build()
236 Standard_Boolean bIsNewFiller;
237 Standard_Integer iErr;
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;
246 myBuilderCanWork=Standard_False;
249 bIsNewFiller=PrepareFiller();
251 if (myErrorStatus!=1) {
252 // there was errors during the preparation
258 myDSFiller->Perform();
261 if (myBuilder!=NULL) {
266 const TopoDS_Shape& aS1 = myS1;
267 const TopoDS_Shape& aS2 = myS2;
270 BRepAlgoAPI_Check aChekArgs(aS1, aS2, myOperation);
271 isDumpArgs = !aChekArgs.IsValid();
276 if (myOperation==BOPAlgo_SECTION) {
277 myBuilder=new BOPAlgo_Section;
278 myBuilder->AddArgument(aS1);
279 myBuilder->AddArgument(aS2);
284 pBOP=new BOPAlgo_BOP;
286 pBOP->AddArgument(aS1);
288 pBOP->SetOperation(myOperation);
291 myBuilder->PerformWithFiller(*myDSFiller);
292 iErr = myBuilder->ErrorStatus();
295 myBuilderCanWork=Standard_True;
296 myShape=myBuilder->Shape();
299 BRepAlgoAPI_Check aCheckRes(myShape);
300 isDumpRes = !aCheckRes.IsValid();
301 if (isDumpArgs || isDumpRes) {
302 BRepAlgoAPI::DumpOper(aPath,
314 myErrorStatus=100+iErr;
320 //=======================================================================
321 //function : SectionEdges
323 //=======================================================================
324 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::SectionEdges()
326 if (myBuilder==NULL) {
331 Standard_Integer aNb, i, j, aNbCurves, nE;
332 BOPDS_ListIteratorOfListOfPaveBlock anIt;
334 const BOPDS_PDS& pDS = myDSFiller->PDS();
335 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
339 for (i = 0; i < aNb; i++) {
340 BOPDS_InterfFF& aFFi=aFFs(i);
341 const BOPDS_VectorOfCurve& aSeqOfCurve=aFFi.Curves();
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();
348 anIt.Initialize(aSectEdges);
349 for(; anIt.More(); anIt.Next()) {
350 const Handle(BOPDS_PaveBlock)& aPB = anIt.Value();
352 const TopoDS_Shape& aE = pDS->Shape(nE);
353 myGenerated.Append(aE);
359 TopTools_ListOfShape theLS;
360 theLS.Assign(myGenerated);
368 // ================================================================================================
369 // function: Generated
371 // ================================================================================================
372 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Generated(const TopoDS_Shape& S)
374 if (myBuilder==NULL) {
380 const TopTools_ListOfShape& aL = myBuilder->Generated(S);
381 return RefinedList(aL);
384 return myBuilder->Generated(S);
387 // ================================================================================================
388 // function: HasModified
390 // ================================================================================================
391 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasModified() const
393 if (myBuilder==NULL) {
394 return Standard_False;
396 return myBuilder->HasModified();
399 // ================================================================================================
400 // function: HasGenerated
402 // ================================================================================================
403 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasGenerated() const
405 if (myBuilder==NULL) {
406 return Standard_False;
408 return myBuilder->HasGenerated();
411 // ================================================================================================
412 // function: HasDeleted
414 // ================================================================================================
415 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasDeleted() const
417 if (myBuilder==NULL) {
418 return Standard_False;
420 return myBuilder->HasDeleted();
422 //=======================================================================
423 //function : RefineEdges
425 //=======================================================================
427 void BRepAlgoAPI_BooleanOperation::RefineEdges ()
429 if(myFuseEdges) return; //Edges have been refined yet
431 BRepLib_FuseEdges FE(myShape);
432 FE.SetConcatBSpl(Standard_True);
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);
440 // Get List of edges that have been fused
441 myFuseEdges = Standard_False;
442 myModifFaces.Clear();
444 TopTools_DataMapOfIntegerListOfShape aFusedEdges;
446 FE.Edges(aFusedEdges);
447 Standard_Integer nle = aFusedEdges.Extent();
450 myShape = FE.Shape();
452 TopTools_DataMapOfIntegerShape aResultEdges;
454 FE.ResultEdges(aResultEdges);
455 FE.Faces(myModifFaces);
456 myFuseEdges = Standard_True;
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()) {
464 myEdgeMap.Bind(anIter.Value(), aNewE);
470 //=======================================================================
471 //function : RefinedList
473 //=======================================================================
474 const TopTools_ListOfShape&
475 BRepAlgoAPI_BooleanOperation::RefinedList(const TopTools_ListOfShape& theL)
478 TopTools_MapOfShape aMap;
480 TopTools_ListIteratorOfListOfShape anIter(theL);
482 for(; anIter.More(); anIter.Next()) {
483 const TopoDS_Shape& anS = anIter.Value();
485 if(anS.ShapeType() == TopAbs_EDGE) {
486 if(myEdgeMap.IsBound(anS)) {
487 const TopoDS_Shape& aNewEdge = myEdgeMap.Find(anS);
488 if(aMap.Add(aNewEdge)) {
489 myGenerated.Append(aNewEdge);
493 myGenerated.Append(anS);
496 else if (anS.ShapeType() == TopAbs_FACE) {
497 if(myModifFaces.IsBound(anS)) {
498 myGenerated.Append(myModifFaces.Find(anS));
501 myGenerated.Append(anS);
505 myGenerated.Append(anS);