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.
18 #include <BOPAlgo_BOP.hxx>
19 #include <BOPAlgo_PaveFiller.hxx>
20 #include <BOPAlgo_Section.hxx>
21 #include <BOPDS_Curve.hxx>
22 #include <BOPDS_DS.hxx>
23 #include <BOPDS_Interf.hxx>
24 #include <BOPDS_ListOfPaveBlock.hxx>
25 #include <BOPDS_PDS.hxx>
26 #include <BOPDS_VectorOfCurve.hxx>
27 #include <BRepAlgoAPI_BooleanOperation.hxx>
28 #include <BRepAlgoAPI_Check.hxx>
29 #include <BRepLib_FuseEdges.hxx>
30 #include <BRepTools.hxx>
31 #include <OSD_File.hxx>
32 #include <TCollection_AsciiString.hxx>
34 #include <TopoDS_Shape.hxx>
35 #include <TopTools_DataMapOfIntegerListOfShape.hxx>
36 #include <TopTools_DataMapOfIntegerShape.hxx>
37 #include <TopTools_IndexedMapOfShape.hxx>
38 #include <TopTools_ListIteratorOfListOfShape.hxx>
39 #include <TopTools_ListOfShape.hxx>
40 #include <TopTools_MapOfShape.hxx>
46 //=======================================================================
47 //class : BRepAlgoAPI_DumpOper
49 //=======================================================================
50 class BRepAlgoAPI_DumpOper {
52 BRepAlgoAPI_DumpOper() :
53 myIsDump(Standard_False),
54 myIsDumpArgs(Standard_False),
55 myIsDumpRes(Standard_False) {
56 char *pathdump = getenv("CSF_DEBUG_BOP");
57 myIsDump=(pathdump!=NULL);
61 virtual ~BRepAlgoAPI_DumpOper() {
64 Standard_Boolean IsDump()const {
68 void SetIsDumpArgs(const Standard_Boolean bFlag) {
72 Standard_Boolean IsDumpArgs()const {
76 void SetIsDumpRes(const Standard_Boolean bFlag) {
80 Standard_Boolean IsDumpRes()const {
85 const TopoDS_Shape& theShape1,
86 const TopoDS_Shape& theShape2,
87 const TopoDS_Shape& theResult,
88 BOPAlgo_Operation theOperation);
91 Standard_Boolean myIsDump;
92 Standard_Boolean myIsDumpArgs;
93 Standard_Boolean myIsDumpRes;
94 Standard_CString myPath;
97 //=======================================================================
98 //function : BRepAlgoAPI_BooleanOperation
100 //=======================================================================
101 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation()
103 BRepAlgoAPI_BuilderAlgo(),
104 myOperation(BOPAlgo_UNKNOWN),
105 myBuilderCanWork(Standard_False),
106 myFuseEdges(Standard_False)
110 //=======================================================================
111 //function : BRepAlgoAPI_BooleanOperation
113 //=======================================================================
114 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
115 (const BOPAlgo_PaveFiller& aPF)
117 BRepAlgoAPI_BuilderAlgo(aPF),
118 myOperation(BOPAlgo_UNKNOWN),
119 myBuilderCanWork(Standard_False),
120 myFuseEdges(Standard_False)
124 //=======================================================================
125 //function : BRepAlgoAPI_BooleanOperation
127 //=======================================================================
128 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
129 (const TopoDS_Shape& aS1,
130 const TopoDS_Shape& aS2,
131 const BOPAlgo_Operation anOp)
133 BRepAlgoAPI_BuilderAlgo(),
135 myBuilderCanWork(Standard_False),
136 myFuseEdges(Standard_False)
140 myArguments.Append(aS1);
143 //=======================================================================
144 //function : BRepAlgoAPI_BooleanOperation
146 //=======================================================================
147 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
148 (const TopoDS_Shape& aS1,
149 const TopoDS_Shape& aS2,
150 const BOPAlgo_PaveFiller& aPF,
151 const BOPAlgo_Operation anOp)
153 BRepAlgoAPI_BuilderAlgo(aPF),
155 myBuilderCanWork(Standard_False),
156 myFuseEdges(Standard_False)
160 myArguments.Append(aS1);
163 myDSFiller=(BOPAlgo_PaveFiller*)&aPF;
165 //=======================================================================
168 //=======================================================================
169 BRepAlgoAPI_BooleanOperation::~BRepAlgoAPI_BooleanOperation()
173 //=======================================================================
176 //=======================================================================
177 void BRepAlgoAPI_BooleanOperation::Clear()
179 BRepAlgoAPI_BuilderAlgo::Clear();
181 myModifFaces.Clear();
184 //=======================================================================
185 //function : SetTools
187 //=======================================================================
188 void BRepAlgoAPI_BooleanOperation::SetTools
189 (const TopTools_ListOfShape& theLS)
193 //=======================================================================
196 //=======================================================================
197 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Tools()const
201 //=======================================================================
202 //function : SetOperation
204 //=======================================================================
205 void BRepAlgoAPI_BooleanOperation::SetOperation
206 (const BOPAlgo_Operation anOp)
210 //=======================================================================
211 //function : Operation
213 //=======================================================================
214 BOPAlgo_Operation BRepAlgoAPI_BooleanOperation::Operation()const
218 //=======================================================================
221 //=======================================================================
222 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape1() const
224 return myArguments.First();
226 //=======================================================================
229 //=======================================================================
230 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape2() const
232 return myTools.First();
234 //=======================================================================
235 //function : BuilderCanWork
237 //=======================================================================
238 Standard_Boolean BRepAlgoAPI_BooleanOperation::BuilderCanWork() const
240 return myBuilderCanWork;
242 //=======================================================================
243 //function : FuseEdges
245 //=======================================================================
246 Standard_Boolean BRepAlgoAPI_BooleanOperation::FuseEdges ()const
250 //=======================================================================
251 //function : SetAttributes
253 //=======================================================================
254 void BRepAlgoAPI_BooleanOperation::SetAttributes()
257 //=======================================================================
260 //=======================================================================
261 void BRepAlgoAPI_BooleanOperation::Build()
263 Standard_Integer iErr, aNbArgs, aNbTools;
264 BRepAlgoAPI_DumpOper aDumpOper;
266 myBuilderCanWork=Standard_False;
270 aNbArgs=myArguments.Extent();
271 aNbTools=myTools.Extent();
272 if (aNbArgs<1 && aNbTools<1) {
276 if (myOperation==BOPAlgo_UNKNOWN) {
281 //-----------------------------------------------
282 TopTools_ListOfShape aLS;
283 TopTools_ListIteratorOfListOfShape aIt;
285 aIt.Initialize(myArguments);
286 for (; aIt.More(); aIt.Next()) {
287 const TopoDS_Shape& aS = aIt.Value();
290 aIt.Initialize(myTools);
291 for (; aIt.More(); aIt.Next()) {
292 const TopoDS_Shape& aS = aIt.Value();
295 //-----------------------------------------------
301 myDSFiller=new BOPAlgo_PaveFiller(myAllocator);
303 myDSFiller->SetArguments(aLS);
305 myDSFiller->SetRunParallel(myRunParallel);
306 myDSFiller->SetProgressIndicator(myProgressIndicator);
307 myDSFiller->SetFuzzyValue(myFuzzyValue);
311 myDSFiller->Perform();
312 iErr=myDSFiller->ErrorStatus();
314 myErrorStatus=100+iErr;
317 }// if (myEntryType) {
320 const TopoDS_Shape& aS1 = myArguments.First();
321 const TopoDS_Shape& aS2 = myTools.First();
322 if (aDumpOper.IsDump()) {
323 BRepAlgoAPI_Check aChekArgs(aS1, aS2, myOperation);
324 aDumpOper.SetIsDumpArgs(!aChekArgs.IsValid());
334 if(myOperation==BOPAlgo_SECTION) {
335 myBuilder=new BOPAlgo_Section(myAllocator);
336 myBuilder->SetArguments(aLS);
339 pBOP=new BOPAlgo_BOP(myAllocator);
340 pBOP->SetArguments(myArguments);
341 pBOP->SetTools(myTools);
342 pBOP->SetOperation(myOperation);
346 myBuilder->SetRunParallel(myRunParallel);
347 myBuilder->SetProgressIndicator(myProgressIndicator);
349 myBuilder->PerformWithFiller(*myDSFiller);
350 iErr = myBuilder->ErrorStatus();
352 myErrorStatus=200+iErr;
356 myShape=myBuilder->Shape();
358 myBuilderCanWork=Standard_True;
362 if (aDumpOper.IsDump()) {
363 BRepAlgoAPI_Check aCheckRes(myShape);
364 aDumpOper.SetIsDumpRes(!aCheckRes.IsValid());
365 aDumpOper.Dump(aS1, aS2, myShape,myOperation);
369 //=======================================================================
370 //function : RefineEdges
372 //=======================================================================
373 void BRepAlgoAPI_BooleanOperation::RefineEdges ()
376 return; //Edges have been refined
379 TopTools_IndexedMapOfShape mapOldEdges;
380 TopTools_ListOfShape aLS;
381 TopTools_ListIteratorOfListOfShape aIt;
383 aIt.Initialize(myArguments);
384 for (; aIt.More(); aIt.Next()) {
385 const TopoDS_Shape& aS = aIt.Value();
388 aIt.Initialize(myTools);
389 for (; aIt.More(); aIt.Next()) {
390 const TopoDS_Shape& aS = aIt.Value();
395 for (; aIt.More(); aIt.Next()) {
396 const TopoDS_Shape& aS = aIt.Value();
397 TopExp::MapShapes (aS, TopAbs_EDGE, mapOldEdges);
399 //----------------------------------------------
400 BRepLib_FuseEdges FE(myShape);
401 FE.SetConcatBSpl(Standard_True);
402 FE.AvoidEdges (mapOldEdges);
404 // Get List of edges that have been fused
405 myFuseEdges = Standard_False;
406 myModifFaces.Clear();
408 TopTools_DataMapOfIntegerListOfShape aFusedEdges;
410 FE.Edges(aFusedEdges);
411 Standard_Integer nle = aFusedEdges.Extent();
414 myShape = FE.Shape();
416 TopTools_DataMapOfIntegerShape aResultEdges;
418 FE.ResultEdges(aResultEdges);
419 FE.Faces(myModifFaces);
420 myFuseEdges = Standard_True;
423 for(i = 1; i <= nle; ++i) {
424 const TopoDS_Shape& aNewE = aResultEdges(i);
425 const TopTools_ListOfShape& aListOfOldEdges = aFusedEdges(i);
426 TopTools_ListIteratorOfListOfShape anIter(aListOfOldEdges);
427 for(; anIter.More(); anIter.Next()) {
428 myEdgeMap.Bind(anIter.Value(), aNewE);
433 //=======================================================================
434 //function : RefinedList
436 //=======================================================================
437 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::RefinedList
438 (const TopTools_ListOfShape& theL)
441 TopTools_MapOfShape aMap;
443 TopTools_ListIteratorOfListOfShape anIter(theL);
445 for(; anIter.More(); anIter.Next()) {
446 const TopoDS_Shape& anS = anIter.Value();
448 if(anS.ShapeType() == TopAbs_EDGE) {
449 if(myEdgeMap.IsBound(anS)) {
450 const TopoDS_Shape& aNewEdge = myEdgeMap.Find(anS);
451 if(aMap.Add(aNewEdge)) {
452 myGenerated.Append(aNewEdge);
456 myGenerated.Append(anS);
459 else if (anS.ShapeType() == TopAbs_FACE) {
460 if(myModifFaces.IsBound(anS)) {
461 myGenerated.Append(myModifFaces.Find(anS));
464 myGenerated.Append(anS);
468 myGenerated.Append(anS);
475 //=======================================================================
476 //function : SectionEdges
478 //=======================================================================
479 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::SectionEdges()
481 if (myBuilder==NULL) {
486 Standard_Integer aNb, i, j, aNbCurves, nE;
487 BOPDS_ListIteratorOfListOfPaveBlock anIt;
489 const BOPDS_PDS& pDS = myDSFiller->PDS();
490 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
494 for (i = 0; i < aNb; i++) {
495 BOPDS_InterfFF& aFFi=aFFs(i);
496 const BOPDS_VectorOfCurve& aSeqOfCurve=aFFi.Curves();
498 aNbCurves=aSeqOfCurve.Extent();
499 for (j=0; j<aNbCurves; j++) {
500 const BOPDS_Curve& aCurve=aSeqOfCurve(j);
501 const BOPDS_ListOfPaveBlock& aSectEdges = aCurve.PaveBlocks();
503 anIt.Initialize(aSectEdges);
504 for(; anIt.More(); anIt.Next()) {
505 const Handle(BOPDS_PaveBlock)& aPB = anIt.Value();
507 const TopoDS_Shape& aE = pDS->Shape(nE);
508 myGenerated.Append(aE);
514 TopTools_ListOfShape theLS;
515 theLS.Assign(myGenerated);
522 //=======================================================================
523 //function : Generated
525 //=======================================================================
526 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Generated
527 (const TopoDS_Shape& S)
529 if (myBuilder==NULL) {
535 const TopTools_ListOfShape& aL = myBuilder->Generated(S);
536 return RefinedList(aL);
539 return myBuilder->Generated(S);
542 //=======================================================================
543 //function : Modified
545 //=======================================================================
546 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Modified
547 (const TopoDS_Shape& aS)
549 if (myBuilder==NULL) {
554 myGenerated = myBuilder->Modified(aS);
557 TopTools_ListOfShape theLS;
558 theLS.Assign(myGenerated);
565 //=======================================================================
566 //function : IsDeleted
568 //=======================================================================
569 Standard_Boolean BRepAlgoAPI_BooleanOperation::IsDeleted
570 (const TopoDS_Shape& aS)
572 Standard_Boolean bDeleted = Standard_True;
573 if (myBuilder != NULL) {
574 bDeleted=myBuilder->IsDeleted(aS);
578 //=======================================================================
579 //function : HasModified
581 //=======================================================================
582 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasModified() const
584 if (myBuilder==NULL) {
585 return Standard_False;
587 return myBuilder->HasModified();
589 //=======================================================================
590 //function : HasGenerated
592 //=======================================================================
593 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasGenerated() const
595 if (myBuilder==NULL) {
596 return Standard_False;
598 return myBuilder->HasGenerated();
600 //=======================================================================
601 //function : HasDeleted
603 //=======================================================================
604 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasDeleted() const
606 if (myBuilder==NULL) {
607 return Standard_False;
609 return myBuilder->HasDeleted();
612 //=======================================================================
615 //=======================================================================
616 void BRepAlgoAPI_DumpOper::Dump (const TopoDS_Shape& theShape1,
617 const TopoDS_Shape& theShape2,
618 const TopoDS_Shape& theResult,
619 BOPAlgo_Operation theOperation)
621 if (!(myIsDumpArgs && myIsDumpRes)) {
625 TCollection_AsciiString aPath(myPath);
627 Standard_Integer aNumOper = 1;
628 Standard_Boolean isExist = Standard_True;
629 TCollection_AsciiString aFileName;
633 aFileName = aPath + "BO_" + TCollection_AsciiString(aNumOper) +".tcl";
634 OSD_File aScript(aFileName);
635 isExist = aScript.Exists();
640 FILE* afile = fopen(aFileName.ToCString(), "w+");
644 fprintf(afile,"%s\n","# Arguments are invalid");
646 TCollection_AsciiString aName1;
647 TCollection_AsciiString aName2;
648 TCollection_AsciiString aNameRes;
649 if(!theShape1.IsNull())
652 "Arg1_" + TCollection_AsciiString(aNumOper) + ".brep";
653 BRepTools::Write(theShape1, aName1.ToCString());
656 fprintf(afile,"%s\n","# First argument is Null ");
658 if(!theShape2.IsNull())
661 "Arg2_"+ TCollection_AsciiString(aNumOper) + ".brep";
663 BRepTools::Write(theShape2, aName2.ToCString());
666 fprintf(afile,"%s\n","# Second argument is Null ");
668 if(!theResult.IsNull())
671 "Result_"+ TCollection_AsciiString(aNumOper) + ".brep";
673 BRepTools::Write(theResult, aNameRes.ToCString());
676 fprintf(afile,"%s\n","# Result is Null ");
678 fprintf(afile, "%s %s %s\n","restore", aName1.ToCString(), "arg1");
679 fprintf(afile, "%s %s %s\n","restore", aName2.ToCString(), "arg2");;
680 TCollection_AsciiString aBopString;
681 switch (theOperation)
683 case BOPAlgo_COMMON : aBopString += "bcommon Res "; break;
684 case BOPAlgo_FUSE : aBopString += "bfuse Res "; break;
686 case BOPAlgo_CUT21 : aBopString += "bcut Res "; break;
687 case BOPAlgo_SECTION : aBopString += "bsection Res "; break;
690 aBopString += ("arg1 arg2");
691 if(theOperation == BOPAlgo_CUT21)
694 fprintf(afile, "%s\n",aBopString.ToCString());