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>
21 #include <TCollection_AsciiString.hxx>
22 #include <BRepTools.hxx>
23 #include <OSD_File.hxx>
28 #include <TopTools_IndexedMapOfShape.hxx>
29 #include <TopTools_DataMapOfIntegerListOfShape.hxx>
30 #include <TopTools_DataMapOfIntegerShape.hxx>
31 #include <TopTools_MapOfShape.hxx>
32 #include <TopTools_ListOfShape.hxx>
33 #include <TopTools_ListIteratorOfListOfShape.hxx>
35 #include <BRepAlgoAPI_Check.hxx>
37 #include <BRepLib_FuseEdges.hxx>
39 #include <BOPDS_PDS.hxx>
40 #include <BOPDS_DS.hxx>
41 #include <BOPDS_VectorOfCurve.hxx>
42 #include <BOPDS_Interf.hxx>
43 #include <BOPDS_Curve.hxx>
44 #include <BOPDS_ListOfPaveBlock.hxx>
46 #include <BOPAlgo_PaveFiller.hxx>
47 #include <BOPAlgo_BOP.hxx>
48 #include <BOPAlgo_Section.hxx>
51 //=======================================================================
52 //class : BRepAlgoAPI_DumpOper
54 //=======================================================================
55 class BRepAlgoAPI_DumpOper {
57 BRepAlgoAPI_DumpOper() :
58 myIsDump(Standard_False),
59 myIsDumpArgs(Standard_False),
60 myIsDumpRes(Standard_False) {
61 char *pathdump = getenv("CSF_DEBUG_BOP");
62 myIsDump=(pathdump!=NULL);
66 virtual ~BRepAlgoAPI_DumpOper() {
69 Standard_Boolean IsDump()const {
73 void SetIsDumpArgs(const Standard_Boolean bFlag) {
77 Standard_Boolean IsDumpArgs()const {
81 void SetIsDumpRes(const Standard_Boolean bFlag) {
85 Standard_Boolean IsDumpRes()const {
90 const TopoDS_Shape& theShape1,
91 const TopoDS_Shape& theShape2,
92 const TopoDS_Shape& theResult,
93 BOPAlgo_Operation theOperation);
96 Standard_Boolean myIsDump;
97 Standard_Boolean myIsDumpArgs;
98 Standard_Boolean myIsDumpRes;
99 Standard_CString myPath;
102 //=======================================================================
103 //function : BRepAlgoAPI_BooleanOperation
105 //=======================================================================
106 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation()
108 BRepAlgoAPI_BuilderAlgo(),
109 myOperation(BOPAlgo_UNKNOWN),
110 myBuilderCanWork(Standard_False),
111 myFuseEdges(Standard_False)
115 //=======================================================================
116 //function : BRepAlgoAPI_BooleanOperation
118 //=======================================================================
119 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
120 (const BOPAlgo_PaveFiller& aPF)
122 BRepAlgoAPI_BuilderAlgo(aPF),
123 myOperation(BOPAlgo_UNKNOWN),
124 myBuilderCanWork(Standard_False),
125 myFuseEdges(Standard_False)
129 //=======================================================================
130 //function : BRepAlgoAPI_BooleanOperation
132 //=======================================================================
133 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
134 (const TopoDS_Shape& aS1,
135 const TopoDS_Shape& aS2,
136 const BOPAlgo_Operation anOp)
138 BRepAlgoAPI_BuilderAlgo(),
140 myBuilderCanWork(Standard_False),
141 myFuseEdges(Standard_False)
145 myArguments.Append(aS1);
148 //=======================================================================
149 //function : BRepAlgoAPI_BooleanOperation
151 //=======================================================================
152 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
153 (const TopoDS_Shape& aS1,
154 const TopoDS_Shape& aS2,
155 const BOPAlgo_PaveFiller& aPF,
156 const BOPAlgo_Operation anOp)
158 BRepAlgoAPI_BuilderAlgo(aPF),
160 myBuilderCanWork(Standard_False),
161 myFuseEdges(Standard_False)
165 myArguments.Append(aS1);
168 myDSFiller=(BOPAlgo_PaveFiller*)&aPF;
170 //=======================================================================
173 //=======================================================================
174 BRepAlgoAPI_BooleanOperation::~BRepAlgoAPI_BooleanOperation()
178 //=======================================================================
181 //=======================================================================
182 void BRepAlgoAPI_BooleanOperation::Clear()
184 BRepAlgoAPI_BuilderAlgo::Clear();
186 myModifFaces.Clear();
189 //=======================================================================
190 //function : SetTools
192 //=======================================================================
193 void BRepAlgoAPI_BooleanOperation::SetTools
194 (const TopTools_ListOfShape& theLS)
198 //=======================================================================
201 //=======================================================================
202 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Tools()const
206 //=======================================================================
207 //function : SetOperation
209 //=======================================================================
210 void BRepAlgoAPI_BooleanOperation::SetOperation
211 (const BOPAlgo_Operation anOp)
215 //=======================================================================
216 //function : Operation
218 //=======================================================================
219 BOPAlgo_Operation BRepAlgoAPI_BooleanOperation::Operation()const
223 //=======================================================================
226 //=======================================================================
227 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape1() const
229 return myArguments.First();
231 //=======================================================================
234 //=======================================================================
235 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape2() const
237 return myTools.First();
239 //=======================================================================
240 //function : BuilderCanWork
242 //=======================================================================
243 Standard_Boolean BRepAlgoAPI_BooleanOperation::BuilderCanWork() const
245 return myBuilderCanWork;
247 //=======================================================================
248 //function : FuseEdges
250 //=======================================================================
251 Standard_Boolean BRepAlgoAPI_BooleanOperation::FuseEdges ()const
255 //=======================================================================
256 //function : SetAttributes
258 //=======================================================================
259 void BRepAlgoAPI_BooleanOperation::SetAttributes()
262 //=======================================================================
265 //=======================================================================
266 void BRepAlgoAPI_BooleanOperation::Build()
268 Standard_Integer iErr, aNbArgs, aNbTools;
269 BRepAlgoAPI_DumpOper aDumpOper;
271 myBuilderCanWork=Standard_False;
275 aNbArgs=myArguments.Extent();
276 aNbTools=myTools.Extent();
277 if (aNbArgs<1 && aNbTools<1) {
281 if (myOperation==BOPAlgo_UNKNOWN) {
286 //-----------------------------------------------
287 TopTools_ListOfShape aLS;
288 TopTools_ListIteratorOfListOfShape aIt;
290 aIt.Initialize(myArguments);
291 for (; aIt.More(); aIt.Next()) {
292 const TopoDS_Shape& aS = aIt.Value();
295 aIt.Initialize(myTools);
296 for (; aIt.More(); aIt.Next()) {
297 const TopoDS_Shape& aS = aIt.Value();
300 //-----------------------------------------------
306 myDSFiller=new BOPAlgo_PaveFiller(myAllocator);
308 myDSFiller->SetArguments(aLS);
310 myDSFiller->SetRunParallel(myRunParallel);
311 myDSFiller->SetProgressIndicator(myProgressIndicator);
312 myDSFiller->SetFuzzyValue(myFuzzyValue);
316 myDSFiller->Perform();
317 iErr=myDSFiller->ErrorStatus();
319 myErrorStatus=100+iErr;
322 }// if (myEntryType) {
325 const TopoDS_Shape& aS1 = myArguments.First();
326 const TopoDS_Shape& aS2 = myTools.First();
327 if (aDumpOper.IsDump()) {
328 BRepAlgoAPI_Check aChekArgs(aS1, aS2, myOperation);
329 aDumpOper.SetIsDumpArgs(!aChekArgs.IsValid());
339 if(myOperation==BOPAlgo_SECTION) {
340 myBuilder=new BOPAlgo_Section(myAllocator);
341 myBuilder->SetArguments(aLS);
344 pBOP=new BOPAlgo_BOP(myAllocator);
345 pBOP->SetArguments(myArguments);
346 pBOP->SetTools(myTools);
347 pBOP->SetOperation(myOperation);
351 myBuilder->SetRunParallel(myRunParallel);
352 myBuilder->SetProgressIndicator(myProgressIndicator);
354 myBuilder->PerformWithFiller(*myDSFiller);
355 iErr = myBuilder->ErrorStatus();
357 myErrorStatus=200+iErr;
361 myShape=myBuilder->Shape();
363 myBuilderCanWork=Standard_True;
367 if (aDumpOper.IsDump()) {
368 BRepAlgoAPI_Check aCheckRes(myShape);
369 aDumpOper.SetIsDumpRes(!aCheckRes.IsValid());
370 aDumpOper.Dump(aS1, aS2, myShape,myOperation);
374 //=======================================================================
375 //function : RefineEdges
377 //=======================================================================
378 void BRepAlgoAPI_BooleanOperation::RefineEdges ()
381 return; //Edges have been refined
384 TopTools_IndexedMapOfShape mapOldEdges;
385 TopTools_ListOfShape aLS;
386 TopTools_ListIteratorOfListOfShape aIt;
388 aIt.Initialize(myArguments);
389 for (; aIt.More(); aIt.Next()) {
390 const TopoDS_Shape& aS = aIt.Value();
393 aIt.Initialize(myTools);
394 for (; aIt.More(); aIt.Next()) {
395 const TopoDS_Shape& aS = aIt.Value();
400 for (; aIt.More(); aIt.Next()) {
401 const TopoDS_Shape& aS = aIt.Value();
402 TopExp::MapShapes (aS, TopAbs_EDGE, mapOldEdges);
404 //----------------------------------------------
405 BRepLib_FuseEdges FE(myShape);
406 FE.SetConcatBSpl(Standard_True);
407 FE.AvoidEdges (mapOldEdges);
409 // Get List of edges that have been fused
410 myFuseEdges = Standard_False;
411 myModifFaces.Clear();
413 TopTools_DataMapOfIntegerListOfShape aFusedEdges;
415 FE.Edges(aFusedEdges);
416 Standard_Integer nle = aFusedEdges.Extent();
419 myShape = FE.Shape();
421 TopTools_DataMapOfIntegerShape aResultEdges;
423 FE.ResultEdges(aResultEdges);
424 FE.Faces(myModifFaces);
425 myFuseEdges = Standard_True;
428 for(i = 1; i <= nle; ++i) {
429 const TopoDS_Shape& aNewE = aResultEdges(i);
430 const TopTools_ListOfShape& aListOfOldEdges = aFusedEdges(i);
431 TopTools_ListIteratorOfListOfShape anIter(aListOfOldEdges);
432 for(; anIter.More(); anIter.Next()) {
433 myEdgeMap.Bind(anIter.Value(), aNewE);
438 //=======================================================================
439 //function : RefinedList
441 //=======================================================================
442 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::RefinedList
443 (const TopTools_ListOfShape& theL)
446 TopTools_MapOfShape aMap;
448 TopTools_ListIteratorOfListOfShape anIter(theL);
450 for(; anIter.More(); anIter.Next()) {
451 const TopoDS_Shape& anS = anIter.Value();
453 if(anS.ShapeType() == TopAbs_EDGE) {
454 if(myEdgeMap.IsBound(anS)) {
455 const TopoDS_Shape& aNewEdge = myEdgeMap.Find(anS);
456 if(aMap.Add(aNewEdge)) {
457 myGenerated.Append(aNewEdge);
461 myGenerated.Append(anS);
464 else if (anS.ShapeType() == TopAbs_FACE) {
465 if(myModifFaces.IsBound(anS)) {
466 myGenerated.Append(myModifFaces.Find(anS));
469 myGenerated.Append(anS);
473 myGenerated.Append(anS);
480 //=======================================================================
481 //function : SectionEdges
483 //=======================================================================
484 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::SectionEdges()
486 if (myBuilder==NULL) {
491 Standard_Integer aNb, i, j, aNbCurves, nE;
492 BOPDS_ListIteratorOfListOfPaveBlock anIt;
494 const BOPDS_PDS& pDS = myDSFiller->PDS();
495 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
499 for (i = 0; i < aNb; i++) {
500 BOPDS_InterfFF& aFFi=aFFs(i);
501 const BOPDS_VectorOfCurve& aSeqOfCurve=aFFi.Curves();
503 aNbCurves=aSeqOfCurve.Extent();
504 for (j=0; j<aNbCurves; j++) {
505 const BOPDS_Curve& aCurve=aSeqOfCurve(j);
506 const BOPDS_ListOfPaveBlock& aSectEdges = aCurve.PaveBlocks();
508 anIt.Initialize(aSectEdges);
509 for(; anIt.More(); anIt.Next()) {
510 const Handle(BOPDS_PaveBlock)& aPB = anIt.Value();
512 const TopoDS_Shape& aE = pDS->Shape(nE);
513 myGenerated.Append(aE);
519 TopTools_ListOfShape theLS;
520 theLS.Assign(myGenerated);
527 //=======================================================================
528 //function : Generated
530 //=======================================================================
531 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Generated
532 (const TopoDS_Shape& S)
534 if (myBuilder==NULL) {
540 const TopTools_ListOfShape& aL = myBuilder->Generated(S);
541 return RefinedList(aL);
544 return myBuilder->Generated(S);
547 //=======================================================================
548 //function : Modified
550 //=======================================================================
551 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Modified
552 (const TopoDS_Shape& aS)
554 if (myBuilder==NULL) {
559 myGenerated = myBuilder->Modified(aS);
562 TopTools_ListOfShape theLS;
563 theLS.Assign(myGenerated);
570 //=======================================================================
571 //function : IsDeleted
573 //=======================================================================
574 Standard_Boolean BRepAlgoAPI_BooleanOperation::IsDeleted
575 (const TopoDS_Shape& aS)
577 Standard_Boolean bDeleted = Standard_True;
578 if (myBuilder != NULL) {
579 bDeleted=myBuilder->IsDeleted(aS);
583 //=======================================================================
584 //function : HasModified
586 //=======================================================================
587 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasModified() const
589 if (myBuilder==NULL) {
590 return Standard_False;
592 return myBuilder->HasModified();
594 //=======================================================================
595 //function : HasGenerated
597 //=======================================================================
598 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasGenerated() const
600 if (myBuilder==NULL) {
601 return Standard_False;
603 return myBuilder->HasGenerated();
605 //=======================================================================
606 //function : HasDeleted
608 //=======================================================================
609 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasDeleted() const
611 if (myBuilder==NULL) {
612 return Standard_False;
614 return myBuilder->HasDeleted();
617 //=======================================================================
620 //=======================================================================
621 void BRepAlgoAPI_DumpOper::Dump (const TopoDS_Shape& theShape1,
622 const TopoDS_Shape& theShape2,
623 const TopoDS_Shape& theResult,
624 BOPAlgo_Operation theOperation)
626 if (!(myIsDumpArgs && myIsDumpRes)) {
630 TCollection_AsciiString aPath(myPath);
632 Standard_Integer aNumOper = 1;
633 Standard_Boolean isExist = Standard_True;
634 TCollection_AsciiString aFileName;
638 aFileName = aPath + "BO_" + TCollection_AsciiString(aNumOper) +".tcl";
639 OSD_File aScript(aFileName);
640 isExist = aScript.Exists();
645 FILE* afile = fopen(aFileName.ToCString(), "w+");
649 fprintf(afile,"%s\n","# Arguments are invalid");
651 TCollection_AsciiString aName1;
652 TCollection_AsciiString aName2;
653 TCollection_AsciiString aNameRes;
654 if(!theShape1.IsNull())
657 "Arg1_" + TCollection_AsciiString(aNumOper) + ".brep";
658 BRepTools::Write(theShape1, aName1.ToCString());
661 fprintf(afile,"%s\n","# First argument is Null ");
663 if(!theShape2.IsNull())
666 "Arg2_"+ TCollection_AsciiString(aNumOper) + ".brep";
668 BRepTools::Write(theShape2, aName2.ToCString());
671 fprintf(afile,"%s\n","# Second argument is Null ");
673 if(!theResult.IsNull())
676 "Result_"+ TCollection_AsciiString(aNumOper) + ".brep";
678 BRepTools::Write(theResult, aNameRes.ToCString());
681 fprintf(afile,"%s\n","# Result is Null ");
683 fprintf(afile, "%s %s %s\n","restore", aName1.ToCString(), "arg1");
684 fprintf(afile, "%s %s %s\n","restore", aName2.ToCString(), "arg2");;
685 TCollection_AsciiString aBopString;
686 switch (theOperation)
688 case BOPAlgo_COMMON : aBopString += "bcommon Res "; break;
689 case BOPAlgo_FUSE : aBopString += "bfuse Res "; break;
691 case BOPAlgo_CUT21 : aBopString += "bcut Res "; break;
692 case BOPAlgo_SECTION : aBopString += "bsection Res "; break;
695 aBopString += ("arg1 arg2");
696 if(theOperation == BOPAlgo_CUT21)
699 fprintf(afile, "%s\n",aBopString.ToCString());