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_Environment.hxx>
32 #include <OSD_File.hxx>
33 #include <TCollection_AsciiString.hxx>
35 #include <TopoDS_Shape.hxx>
36 #include <TopTools_DataMapOfIntegerListOfShape.hxx>
37 #include <TopTools_DataMapOfIntegerShape.hxx>
38 #include <TopTools_IndexedMapOfShape.hxx>
39 #include <TopTools_ListIteratorOfListOfShape.hxx>
40 #include <TopTools_ListOfShape.hxx>
41 #include <TopTools_MapOfShape.hxx>
47 //=======================================================================
48 //class : BRepAlgoAPI_DumpOper
50 //=======================================================================
51 class BRepAlgoAPI_DumpOper {
53 BRepAlgoAPI_DumpOper() :
54 myIsDump(Standard_False),
55 myIsDumpArgs(Standard_False),
56 myIsDumpRes(Standard_False) {
57 OSD_Environment env("CSF_DEBUG_BOP");
58 TCollection_AsciiString pathdump = env.Value();
59 myIsDump = (!pathdump.IsEmpty() ? Standard_True: Standard_False);
60 myPath=pathdump.ToCString();
63 virtual ~BRepAlgoAPI_DumpOper() {
66 Standard_Boolean IsDump()const {
70 void SetIsDumpArgs(const Standard_Boolean bFlag) {
74 Standard_Boolean IsDumpArgs()const {
78 void SetIsDumpRes(const Standard_Boolean bFlag) {
82 Standard_Boolean IsDumpRes()const {
87 const TopoDS_Shape& theShape1,
88 const TopoDS_Shape& theShape2,
89 const TopoDS_Shape& theResult,
90 BOPAlgo_Operation theOperation);
93 Standard_Boolean myIsDump;
94 Standard_Boolean myIsDumpArgs;
95 Standard_Boolean myIsDumpRes;
96 Standard_CString myPath;
99 //=======================================================================
100 //function : BRepAlgoAPI_BooleanOperation
102 //=======================================================================
103 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation()
105 BRepAlgoAPI_BuilderAlgo(),
106 myOperation(BOPAlgo_UNKNOWN),
107 myBuilderCanWork(Standard_False),
108 myFuseEdges(Standard_False)
112 //=======================================================================
113 //function : BRepAlgoAPI_BooleanOperation
115 //=======================================================================
116 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
117 (const BOPAlgo_PaveFiller& aPF)
119 BRepAlgoAPI_BuilderAlgo(aPF),
120 myOperation(BOPAlgo_UNKNOWN),
121 myBuilderCanWork(Standard_False),
122 myFuseEdges(Standard_False)
126 //=======================================================================
127 //function : BRepAlgoAPI_BooleanOperation
129 //=======================================================================
130 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
131 (const TopoDS_Shape& aS1,
132 const TopoDS_Shape& aS2,
133 const BOPAlgo_Operation anOp)
135 BRepAlgoAPI_BuilderAlgo(),
137 myBuilderCanWork(Standard_False),
138 myFuseEdges(Standard_False)
142 myArguments.Append(aS1);
145 //=======================================================================
146 //function : BRepAlgoAPI_BooleanOperation
148 //=======================================================================
149 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
150 (const TopoDS_Shape& aS1,
151 const TopoDS_Shape& aS2,
152 const BOPAlgo_PaveFiller& aPF,
153 const BOPAlgo_Operation anOp)
155 BRepAlgoAPI_BuilderAlgo(aPF),
157 myBuilderCanWork(Standard_False),
158 myFuseEdges(Standard_False)
162 myArguments.Append(aS1);
165 myDSFiller=(BOPAlgo_PaveFiller*)&aPF;
167 //=======================================================================
170 //=======================================================================
171 BRepAlgoAPI_BooleanOperation::~BRepAlgoAPI_BooleanOperation()
175 //=======================================================================
178 //=======================================================================
179 void BRepAlgoAPI_BooleanOperation::Clear()
181 BRepAlgoAPI_BuilderAlgo::Clear();
183 myModifFaces.Clear();
186 //=======================================================================
187 //function : SetTools
189 //=======================================================================
190 void BRepAlgoAPI_BooleanOperation::SetTools
191 (const TopTools_ListOfShape& theLS)
195 //=======================================================================
198 //=======================================================================
199 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Tools()const
203 //=======================================================================
204 //function : SetOperation
206 //=======================================================================
207 void BRepAlgoAPI_BooleanOperation::SetOperation
208 (const BOPAlgo_Operation anOp)
212 //=======================================================================
213 //function : Operation
215 //=======================================================================
216 BOPAlgo_Operation BRepAlgoAPI_BooleanOperation::Operation()const
220 //=======================================================================
223 //=======================================================================
224 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape1() const
226 return myArguments.First();
228 //=======================================================================
231 //=======================================================================
232 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape2() const
234 return myTools.First();
236 //=======================================================================
237 //function : BuilderCanWork
239 //=======================================================================
240 Standard_Boolean BRepAlgoAPI_BooleanOperation::BuilderCanWork() const
242 return myBuilderCanWork;
244 //=======================================================================
245 //function : FuseEdges
247 //=======================================================================
248 Standard_Boolean BRepAlgoAPI_BooleanOperation::FuseEdges ()const
252 //=======================================================================
253 //function : SetAttributes
255 //=======================================================================
256 void BRepAlgoAPI_BooleanOperation::SetAttributes()
259 //=======================================================================
262 //=======================================================================
263 void BRepAlgoAPI_BooleanOperation::Build()
265 Standard_Integer iErr, aNbArgs, aNbTools;
266 BRepAlgoAPI_DumpOper aDumpOper;
268 myBuilderCanWork=Standard_False;
272 aNbArgs=myArguments.Extent();
273 aNbTools=myTools.Extent();
274 if (aNbArgs<1 && aNbTools<1) {
278 if (myOperation==BOPAlgo_UNKNOWN) {
283 //-----------------------------------------------
284 TopTools_ListOfShape aLS;
285 TopTools_ListIteratorOfListOfShape aIt;
287 aIt.Initialize(myArguments);
288 for (; aIt.More(); aIt.Next()) {
289 const TopoDS_Shape& aS = aIt.Value();
292 aIt.Initialize(myTools);
293 for (; aIt.More(); aIt.Next()) {
294 const TopoDS_Shape& aS = aIt.Value();
297 //-----------------------------------------------
303 myDSFiller=new BOPAlgo_PaveFiller(myAllocator);
305 myDSFiller->SetArguments(aLS);
307 myDSFiller->SetRunParallel(myRunParallel);
308 myDSFiller->SetProgressIndicator(myProgressIndicator);
309 myDSFiller->SetFuzzyValue(myFuzzyValue);
310 myDSFiller->SetNonDestructive(myNonDestructive);
311 myDSFiller->SetGlue(myGlue);
315 myDSFiller->Perform();
316 iErr=myDSFiller->ErrorStatus();
318 myErrorStatus=100+iErr;
321 }// if (myEntryType) {
324 const TopoDS_Shape& aS1 = myArguments.First();
325 const TopoDS_Shape& aS2 = myTools.First();
326 if (aDumpOper.IsDump()) {
327 BRepAlgoAPI_Check aChekArgs(aS1, aS2, myOperation);
328 aDumpOper.SetIsDumpArgs(!aChekArgs.IsValid());
338 if(myOperation==BOPAlgo_SECTION) {
339 myBuilder=new BOPAlgo_Section(myAllocator);
340 myBuilder->SetArguments(aLS);
343 pBOP=new BOPAlgo_BOP(myAllocator);
344 pBOP->SetArguments(myArguments);
345 pBOP->SetTools(myTools);
346 pBOP->SetOperation(myOperation);
350 myBuilder->SetRunParallel(myRunParallel);
351 myBuilder->SetProgressIndicator(myProgressIndicator);
353 myBuilder->PerformWithFiller(*myDSFiller);
354 iErr = myBuilder->ErrorStatus();
356 myErrorStatus=200+iErr;
360 myShape=myBuilder->Shape();
362 myBuilderCanWork=Standard_True;
366 if (aDumpOper.IsDump()) {
367 BRepAlgoAPI_Check aCheckRes(myShape);
368 aDumpOper.SetIsDumpRes(!aCheckRes.IsValid());
369 aDumpOper.Dump(aS1, aS2, myShape,myOperation);
373 //=======================================================================
374 //function : RefineEdges
376 //=======================================================================
377 void BRepAlgoAPI_BooleanOperation::RefineEdges ()
380 return; //Edges have been refined
383 TopTools_IndexedMapOfShape mapOldEdges;
384 TopTools_ListOfShape aLS;
385 TopTools_ListIteratorOfListOfShape aIt;
387 aIt.Initialize(myArguments);
388 for (; aIt.More(); aIt.Next()) {
389 const TopoDS_Shape& aS = aIt.Value();
392 aIt.Initialize(myTools);
393 for (; aIt.More(); aIt.Next()) {
394 const TopoDS_Shape& aS = aIt.Value();
399 for (; aIt.More(); aIt.Next()) {
400 const TopoDS_Shape& aS = aIt.Value();
401 TopExp::MapShapes (aS, TopAbs_EDGE, mapOldEdges);
403 //----------------------------------------------
404 BRepLib_FuseEdges FE(myShape);
405 FE.SetConcatBSpl(Standard_True);
406 FE.AvoidEdges (mapOldEdges);
408 // Get List of edges that have been fused
409 myFuseEdges = Standard_False;
410 myModifFaces.Clear();
412 TopTools_DataMapOfIntegerListOfShape aFusedEdges;
414 FE.Edges(aFusedEdges);
415 Standard_Integer nle = aFusedEdges.Extent();
418 myShape = FE.Shape();
420 TopTools_DataMapOfIntegerShape aResultEdges;
422 FE.ResultEdges(aResultEdges);
423 FE.Faces(myModifFaces);
424 myFuseEdges = Standard_True;
427 for(i = 1; i <= nle; ++i) {
428 const TopoDS_Shape& aNewE = aResultEdges(i);
429 const TopTools_ListOfShape& aListOfOldEdges = aFusedEdges(i);
430 TopTools_ListIteratorOfListOfShape anIter(aListOfOldEdges);
431 for(; anIter.More(); anIter.Next()) {
432 myEdgeMap.Bind(anIter.Value(), aNewE);
437 //=======================================================================
438 //function : RefinedList
440 //=======================================================================
441 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::RefinedList
442 (const TopTools_ListOfShape& theL)
445 TopTools_MapOfShape aMap;
447 TopTools_ListIteratorOfListOfShape anIter(theL);
449 for(; anIter.More(); anIter.Next()) {
450 const TopoDS_Shape& anS = anIter.Value();
452 if(anS.ShapeType() == TopAbs_EDGE) {
453 if(myEdgeMap.IsBound(anS)) {
454 const TopoDS_Shape& aNewEdge = myEdgeMap.Find(anS);
455 if(aMap.Add(aNewEdge)) {
456 myGenerated.Append(aNewEdge);
460 myGenerated.Append(anS);
463 else if (anS.ShapeType() == TopAbs_FACE) {
464 if(myModifFaces.IsBound(anS)) {
465 myGenerated.Append(myModifFaces.Find(anS));
468 myGenerated.Append(anS);
472 myGenerated.Append(anS);
479 //=======================================================================
480 //function : SectionEdges
482 //=======================================================================
483 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::SectionEdges()
485 if (myBuilder==NULL) {
490 Standard_Integer aNb, i, j, aNbCurves, nE;
491 BOPDS_ListIteratorOfListOfPaveBlock anIt;
493 const BOPDS_PDS& pDS = myDSFiller->PDS();
494 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
498 for (i = 0; i < aNb; i++) {
499 BOPDS_InterfFF& aFFi=aFFs(i);
500 const BOPDS_VectorOfCurve& aSeqOfCurve=aFFi.Curves();
502 aNbCurves=aSeqOfCurve.Extent();
503 for (j=0; j<aNbCurves; j++) {
504 const BOPDS_Curve& aCurve=aSeqOfCurve(j);
505 const BOPDS_ListOfPaveBlock& aSectEdges = aCurve.PaveBlocks();
507 anIt.Initialize(aSectEdges);
508 for(; anIt.More(); anIt.Next()) {
509 const Handle(BOPDS_PaveBlock)& aPB = anIt.Value();
511 const TopoDS_Shape& aE = pDS->Shape(nE);
512 myGenerated.Append(aE);
518 TopTools_ListOfShape theLS;
519 theLS.Assign(myGenerated);
526 //=======================================================================
527 //function : Generated
529 //=======================================================================
530 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Generated
531 (const TopoDS_Shape& S)
533 if (myBuilder==NULL) {
539 const TopTools_ListOfShape& aL = myBuilder->Generated(S);
540 return RefinedList(aL);
543 return myBuilder->Generated(S);
546 //=======================================================================
547 //function : Modified
549 //=======================================================================
550 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Modified
551 (const TopoDS_Shape& aS)
553 if (myBuilder==NULL) {
558 myGenerated = myBuilder->Modified(aS);
561 TopTools_ListOfShape theLS;
562 theLS.Assign(myGenerated);
569 //=======================================================================
570 //function : IsDeleted
572 //=======================================================================
573 Standard_Boolean BRepAlgoAPI_BooleanOperation::IsDeleted
574 (const TopoDS_Shape& aS)
576 Standard_Boolean bDeleted = Standard_True;
577 if (myBuilder != NULL) {
578 bDeleted=myBuilder->IsDeleted(aS);
582 //=======================================================================
583 //function : HasModified
585 //=======================================================================
586 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasModified() const
588 if (myBuilder==NULL) {
589 return Standard_False;
591 return myBuilder->HasModified();
593 //=======================================================================
594 //function : HasGenerated
596 //=======================================================================
597 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasGenerated() const
599 if (myBuilder==NULL) {
600 return Standard_False;
602 return myBuilder->HasGenerated();
604 //=======================================================================
605 //function : HasDeleted
607 //=======================================================================
608 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasDeleted() const
610 if (myBuilder==NULL) {
611 return Standard_False;
613 return myBuilder->HasDeleted();
616 //=======================================================================
619 //=======================================================================
620 void BRepAlgoAPI_DumpOper::Dump (const TopoDS_Shape& theShape1,
621 const TopoDS_Shape& theShape2,
622 const TopoDS_Shape& theResult,
623 BOPAlgo_Operation theOperation)
625 if (!(myIsDumpArgs && myIsDumpRes)) {
629 TCollection_AsciiString aPath(myPath);
631 Standard_Integer aNumOper = 1;
632 Standard_Boolean isExist = Standard_True;
633 TCollection_AsciiString aFileName;
637 aFileName = aPath + "BO_" + TCollection_AsciiString(aNumOper) +".tcl";
638 OSD_File aScript(aFileName);
639 isExist = aScript.Exists();
644 FILE* afile = fopen(aFileName.ToCString(), "w+");
648 fprintf(afile,"%s\n","# Arguments are invalid");
650 TCollection_AsciiString aName1;
651 TCollection_AsciiString aName2;
652 TCollection_AsciiString aNameRes;
653 if(!theShape1.IsNull())
656 "Arg1_" + TCollection_AsciiString(aNumOper) + ".brep";
657 BRepTools::Write(theShape1, aName1.ToCString());
660 fprintf(afile,"%s\n","# First argument is Null ");
662 if(!theShape2.IsNull())
665 "Arg2_"+ TCollection_AsciiString(aNumOper) + ".brep";
667 BRepTools::Write(theShape2, aName2.ToCString());
670 fprintf(afile,"%s\n","# Second argument is Null ");
672 if(!theResult.IsNull())
675 "Result_"+ TCollection_AsciiString(aNumOper) + ".brep";
677 BRepTools::Write(theResult, aNameRes.ToCString());
680 fprintf(afile,"%s\n","# Result is Null ");
682 fprintf(afile, "%s %s %s\n","restore", aName1.ToCString(), "arg1");
683 fprintf(afile, "%s %s %s\n","restore", aName2.ToCString(), "arg2");;
684 TCollection_AsciiString aBopString;
685 switch (theOperation)
687 case BOPAlgo_COMMON : aBopString += "bcommon Res "; break;
688 case BOPAlgo_FUSE : aBopString += "bfuse Res "; break;
690 case BOPAlgo_CUT21 : aBopString += "bcut Res "; break;
691 case BOPAlgo_SECTION : aBopString += "bsection Res "; break;
694 aBopString += ("arg1 arg2");
695 if(theOperation == BOPAlgo_CUT21)
698 fprintf(afile, "%s\n",aBopString.ToCString());