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 <BOPAlgo_Alerts.hxx>
22 #include <BOPDS_Curve.hxx>
23 #include <BOPDS_DS.hxx>
24 #include <BOPDS_Interf.hxx>
25 #include <BOPDS_ListOfPaveBlock.hxx>
26 #include <BOPDS_PDS.hxx>
27 #include <BOPDS_VectorOfCurve.hxx>
28 #include <BRepAlgoAPI_BooleanOperation.hxx>
29 #include <BRepAlgoAPI_Check.hxx>
30 #include <BRepLib_FuseEdges.hxx>
31 #include <BRepTools.hxx>
32 #include <OSD_Environment.hxx>
33 #include <OSD_File.hxx>
34 #include <TCollection_AsciiString.hxx>
36 #include <TopoDS_Shape.hxx>
37 #include <TopTools_DataMapOfIntegerListOfShape.hxx>
38 #include <TopTools_DataMapOfIntegerShape.hxx>
39 #include <TopTools_IndexedMapOfShape.hxx>
40 #include <TopTools_ListIteratorOfListOfShape.hxx>
41 #include <TopTools_ListOfShape.hxx>
42 #include <TopTools_MapOfShape.hxx>
48 //=======================================================================
49 //class : BRepAlgoAPI_DumpOper
51 //=======================================================================
52 class BRepAlgoAPI_DumpOper {
54 BRepAlgoAPI_DumpOper() :
55 myIsDump(Standard_False),
56 myIsDumpArgs(Standard_False),
57 myIsDumpRes(Standard_False) {
58 OSD_Environment env("CSF_DEBUG_BOP");
59 TCollection_AsciiString pathdump = env.Value();
60 myIsDump = (!pathdump.IsEmpty() ? Standard_True: Standard_False);
61 myPath=pathdump.ToCString();
64 virtual ~BRepAlgoAPI_DumpOper() {
67 Standard_Boolean IsDump()const {
71 void SetIsDumpArgs(const Standard_Boolean bFlag) {
75 Standard_Boolean IsDumpArgs()const {
79 void SetIsDumpRes(const Standard_Boolean bFlag) {
83 Standard_Boolean IsDumpRes()const {
88 const TopoDS_Shape& theShape1,
89 const TopoDS_Shape& theShape2,
90 const TopoDS_Shape& theResult,
91 BOPAlgo_Operation theOperation);
94 Standard_Boolean myIsDump;
95 Standard_Boolean myIsDumpArgs;
96 Standard_Boolean myIsDumpRes;
97 Standard_CString myPath;
100 //=======================================================================
101 //function : BRepAlgoAPI_BooleanOperation
103 //=======================================================================
104 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation()
106 BRepAlgoAPI_BuilderAlgo(),
107 myOperation(BOPAlgo_UNKNOWN),
108 myBuilderCanWork(Standard_False),
109 myFuseEdges(Standard_False)
113 //=======================================================================
114 //function : BRepAlgoAPI_BooleanOperation
116 //=======================================================================
117 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
118 (const BOPAlgo_PaveFiller& aPF)
120 BRepAlgoAPI_BuilderAlgo(aPF),
121 myOperation(BOPAlgo_UNKNOWN),
122 myBuilderCanWork(Standard_False),
123 myFuseEdges(Standard_False)
127 //=======================================================================
128 //function : BRepAlgoAPI_BooleanOperation
130 //=======================================================================
131 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
132 (const TopoDS_Shape& aS1,
133 const TopoDS_Shape& aS2,
134 const BOPAlgo_Operation anOp)
136 BRepAlgoAPI_BuilderAlgo(),
138 myBuilderCanWork(Standard_False),
139 myFuseEdges(Standard_False)
143 myArguments.Append(aS1);
146 //=======================================================================
147 //function : BRepAlgoAPI_BooleanOperation
149 //=======================================================================
150 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
151 (const TopoDS_Shape& aS1,
152 const TopoDS_Shape& aS2,
153 const BOPAlgo_PaveFiller& aPF,
154 const BOPAlgo_Operation anOp)
156 BRepAlgoAPI_BuilderAlgo(aPF),
158 myBuilderCanWork(Standard_False),
159 myFuseEdges(Standard_False)
163 myArguments.Append(aS1);
166 myDSFiller=(BOPAlgo_PaveFiller*)&aPF;
168 //=======================================================================
171 //=======================================================================
172 BRepAlgoAPI_BooleanOperation::~BRepAlgoAPI_BooleanOperation()
176 //=======================================================================
179 //=======================================================================
180 void BRepAlgoAPI_BooleanOperation::Clear()
182 BRepAlgoAPI_BuilderAlgo::Clear();
184 myModifFaces.Clear();
187 //=======================================================================
188 //function : SetTools
190 //=======================================================================
191 void BRepAlgoAPI_BooleanOperation::SetTools
192 (const TopTools_ListOfShape& theLS)
196 //=======================================================================
199 //=======================================================================
200 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Tools()const
204 //=======================================================================
205 //function : SetOperation
207 //=======================================================================
208 void BRepAlgoAPI_BooleanOperation::SetOperation
209 (const BOPAlgo_Operation anOp)
213 //=======================================================================
214 //function : Operation
216 //=======================================================================
217 BOPAlgo_Operation BRepAlgoAPI_BooleanOperation::Operation()const
221 //=======================================================================
224 //=======================================================================
225 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape1() const
227 return myArguments.First();
229 //=======================================================================
232 //=======================================================================
233 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape2() const
235 return myTools.First();
237 //=======================================================================
238 //function : BuilderCanWork
240 //=======================================================================
241 Standard_Boolean BRepAlgoAPI_BooleanOperation::BuilderCanWork() const
243 return myBuilderCanWork;
245 //=======================================================================
246 //function : FuseEdges
248 //=======================================================================
249 Standard_Boolean BRepAlgoAPI_BooleanOperation::FuseEdges ()const
253 //=======================================================================
254 //function : SetAttributes
256 //=======================================================================
257 void BRepAlgoAPI_BooleanOperation::SetAttributes()
260 //=======================================================================
263 //=======================================================================
264 void BRepAlgoAPI_BooleanOperation::Build()
266 GetReport()->Clear();
268 Standard_Integer aNbArgs, aNbTools;
269 BRepAlgoAPI_DumpOper aDumpOper;
271 myBuilderCanWork=Standard_False;
274 aNbArgs=myArguments.Extent();
275 aNbTools=myTools.Extent();
276 if (aNbArgs<1 && aNbTools<1) {
277 AddError (new BOPAlgo_AlertTooFewArguments);
280 if (myOperation==BOPAlgo_UNKNOWN) {
281 AddError (new BOPAlgo_AlertBOPNotSet);
285 //-----------------------------------------------
286 TopTools_ListOfShape aLS;
287 TopTools_ListIteratorOfListOfShape aIt;
289 aIt.Initialize(myArguments);
290 for (; aIt.More(); aIt.Next()) {
291 const TopoDS_Shape& aS = aIt.Value();
294 aIt.Initialize(myTools);
295 for (; aIt.More(); aIt.Next()) {
296 const TopoDS_Shape& aS = aIt.Value();
299 //-----------------------------------------------
305 myDSFiller=new BOPAlgo_PaveFiller(myAllocator);
307 myDSFiller->SetArguments(aLS);
309 myDSFiller->SetRunParallel(myRunParallel);
310 myDSFiller->SetProgressIndicator(myProgressIndicator);
311 myDSFiller->SetFuzzyValue(myFuzzyValue);
312 myDSFiller->SetNonDestructive(myNonDestructive);
313 myDSFiller->SetGlue(myGlue);
317 myDSFiller->Perform();
319 GetReport()->Merge (myDSFiller->GetReport());
324 }// if (myEntryType) {
327 const TopoDS_Shape& aS1 = myArguments.First();
328 const TopoDS_Shape& aS2 = myTools.First();
329 if (aDumpOper.IsDump()) {
330 BRepAlgoAPI_Check aChekArgs(aS1, aS2, myOperation);
331 aDumpOper.SetIsDumpArgs(!aChekArgs.IsValid());
342 if(myOperation==BOPAlgo_SECTION) {
343 myBuilder=new BOPAlgo_Section(myAllocator);
344 myBuilder->SetArguments(aLS);
347 pBOP=new BOPAlgo_BOP(myAllocator);
348 pBOP->SetArguments(myArguments);
349 pBOP->SetTools(myTools);
350 pBOP->SetOperation(myOperation);
354 myBuilder->SetRunParallel(myRunParallel);
355 myBuilder->SetProgressIndicator(myProgressIndicator);
356 myBuilder->SetCheckInverted(myCheckInverted);
358 myBuilder->PerformWithFiller(*myDSFiller);
360 GetReport()->Merge (myBuilder->GetReport());
366 myShape=myBuilder->Shape();
368 myBuilderCanWork=Standard_True;
372 if (aDumpOper.IsDump()) {
373 BRepAlgoAPI_Check aCheckRes(myShape);
374 aDumpOper.SetIsDumpRes(!aCheckRes.IsValid());
375 aDumpOper.Dump(aS1, aS2, myShape,myOperation);
379 //=======================================================================
380 //function : RefineEdges
382 //=======================================================================
383 void BRepAlgoAPI_BooleanOperation::RefineEdges ()
386 return; //Edges have been refined
389 TopTools_IndexedMapOfShape mapOldEdges;
390 TopTools_ListOfShape aLS;
391 TopTools_ListIteratorOfListOfShape aIt;
393 aIt.Initialize(myArguments);
394 for (; aIt.More(); aIt.Next()) {
395 const TopoDS_Shape& aS = aIt.Value();
398 aIt.Initialize(myTools);
399 for (; aIt.More(); aIt.Next()) {
400 const TopoDS_Shape& aS = aIt.Value();
405 for (; aIt.More(); aIt.Next()) {
406 const TopoDS_Shape& aS = aIt.Value();
407 TopExp::MapShapes (aS, TopAbs_EDGE, mapOldEdges);
409 //----------------------------------------------
410 BRepLib_FuseEdges FE(myShape);
411 FE.SetConcatBSpl(Standard_True);
412 FE.AvoidEdges (mapOldEdges);
414 // Get List of edges that have been fused
415 myFuseEdges = Standard_False;
416 myModifFaces.Clear();
418 TopTools_DataMapOfIntegerListOfShape aFusedEdges;
420 FE.Edges(aFusedEdges);
421 Standard_Integer nle = aFusedEdges.Extent();
424 myShape = FE.Shape();
426 TopTools_DataMapOfIntegerShape aResultEdges;
428 FE.ResultEdges(aResultEdges);
429 FE.Faces(myModifFaces);
430 myFuseEdges = Standard_True;
433 for(i = 1; i <= nle; ++i) {
434 const TopoDS_Shape& aNewE = aResultEdges(i);
435 const TopTools_ListOfShape& aListOfOldEdges = aFusedEdges(i);
436 TopTools_ListIteratorOfListOfShape anIter(aListOfOldEdges);
437 for(; anIter.More(); anIter.Next()) {
438 myEdgeMap.Bind(anIter.Value(), aNewE);
443 //=======================================================================
444 //function : RefinedList
446 //=======================================================================
447 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::RefinedList
448 (const TopTools_ListOfShape& theL)
451 TopTools_MapOfShape aMap;
453 TopTools_ListIteratorOfListOfShape anIter(theL);
455 for(; anIter.More(); anIter.Next()) {
456 const TopoDS_Shape& anS = anIter.Value();
458 if(anS.ShapeType() == TopAbs_EDGE) {
459 if(myEdgeMap.IsBound(anS)) {
460 const TopoDS_Shape& aNewEdge = myEdgeMap.Find(anS);
461 if(aMap.Add(aNewEdge)) {
462 myGenerated.Append(aNewEdge);
466 myGenerated.Append(anS);
469 else if (anS.ShapeType() == TopAbs_FACE) {
470 if(myModifFaces.IsBound(anS)) {
471 myGenerated.Append(myModifFaces.Find(anS));
474 myGenerated.Append(anS);
478 myGenerated.Append(anS);
485 //=======================================================================
486 //function : SectionEdges
488 //=======================================================================
489 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::SectionEdges()
491 if (myBuilder==NULL) {
496 Standard_Integer aNb, i, j, aNbCurves, nE;
497 BOPDS_ListIteratorOfListOfPaveBlock anIt;
499 const BOPDS_PDS& pDS = myDSFiller->PDS();
500 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
504 for (i = 0; i < aNb; i++) {
505 BOPDS_InterfFF& aFFi=aFFs(i);
506 const BOPDS_VectorOfCurve& aSeqOfCurve=aFFi.Curves();
508 aNbCurves=aSeqOfCurve.Extent();
509 for (j=0; j<aNbCurves; j++) {
510 const BOPDS_Curve& aCurve=aSeqOfCurve(j);
511 const BOPDS_ListOfPaveBlock& aSectEdges = aCurve.PaveBlocks();
513 anIt.Initialize(aSectEdges);
514 for(; anIt.More(); anIt.Next()) {
515 const Handle(BOPDS_PaveBlock)& aPB = anIt.Value();
517 const TopoDS_Shape& aE = pDS->Shape(nE);
518 myGenerated.Append(aE);
524 TopTools_ListOfShape theLS;
525 theLS.Assign(myGenerated);
532 //=======================================================================
533 //function : Generated
535 //=======================================================================
536 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Generated
537 (const TopoDS_Shape& S)
539 if (myBuilder==NULL) {
545 const TopTools_ListOfShape& aL = myBuilder->Generated(S);
546 return RefinedList(aL);
549 return myBuilder->Generated(S);
552 //=======================================================================
553 //function : Modified
555 //=======================================================================
556 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Modified
557 (const TopoDS_Shape& aS)
559 if (myBuilder==NULL) {
564 myGenerated = myBuilder->Modified(aS);
567 TopTools_ListOfShape theLS;
568 theLS.Assign(myGenerated);
575 //=======================================================================
576 //function : IsDeleted
578 //=======================================================================
579 Standard_Boolean BRepAlgoAPI_BooleanOperation::IsDeleted
580 (const TopoDS_Shape& aS)
582 Standard_Boolean bDeleted = Standard_True;
583 if (myBuilder != NULL) {
584 bDeleted=myBuilder->IsDeleted(aS);
588 //=======================================================================
589 //function : HasModified
591 //=======================================================================
592 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasModified() const
594 if (myBuilder==NULL) {
595 return Standard_False;
597 return myBuilder->HasModified();
599 //=======================================================================
600 //function : HasGenerated
602 //=======================================================================
603 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasGenerated() const
605 if (myBuilder==NULL) {
606 return Standard_False;
608 return myBuilder->HasGenerated();
610 //=======================================================================
611 //function : HasDeleted
613 //=======================================================================
614 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasDeleted() const
616 if (myBuilder==NULL) {
617 return Standard_False;
619 return myBuilder->HasDeleted();
622 //=======================================================================
625 //=======================================================================
626 void BRepAlgoAPI_DumpOper::Dump (const TopoDS_Shape& theShape1,
627 const TopoDS_Shape& theShape2,
628 const TopoDS_Shape& theResult,
629 BOPAlgo_Operation theOperation)
631 if (!(myIsDumpArgs && myIsDumpRes)) {
635 TCollection_AsciiString aPath(myPath);
637 Standard_Integer aNumOper = 1;
638 Standard_Boolean isExist = Standard_True;
639 TCollection_AsciiString aFileName;
643 aFileName = aPath + "BO_" + TCollection_AsciiString(aNumOper) +".tcl";
644 OSD_File aScript(aFileName);
645 isExist = aScript.Exists();
650 FILE* afile = fopen(aFileName.ToCString(), "w+");
654 fprintf(afile,"%s\n","# Arguments are invalid");
656 TCollection_AsciiString aName1;
657 TCollection_AsciiString aName2;
658 TCollection_AsciiString aNameRes;
659 if(!theShape1.IsNull())
662 "Arg1_" + TCollection_AsciiString(aNumOper) + ".brep";
663 BRepTools::Write(theShape1, aName1.ToCString());
666 fprintf(afile,"%s\n","# First argument is Null ");
668 if(!theShape2.IsNull())
671 "Arg2_"+ TCollection_AsciiString(aNumOper) + ".brep";
673 BRepTools::Write(theShape2, aName2.ToCString());
676 fprintf(afile,"%s\n","# Second argument is Null ");
678 if(!theResult.IsNull())
681 "Result_"+ TCollection_AsciiString(aNumOper) + ".brep";
683 BRepTools::Write(theResult, aNameRes.ToCString());
686 fprintf(afile,"%s\n","# Result is Null ");
688 fprintf(afile, "%s %s %s\n","restore", aName1.ToCString(), "arg1");
689 fprintf(afile, "%s %s %s\n","restore", aName2.ToCString(), "arg2");;
690 TCollection_AsciiString aBopString;
691 switch (theOperation)
693 case BOPAlgo_COMMON : aBopString += "bcommon Res "; break;
694 case BOPAlgo_FUSE : aBopString += "bfuse Res "; break;
696 case BOPAlgo_CUT21 : aBopString += "bcut Res "; break;
697 case BOPAlgo_SECTION : aBopString += "bsection Res "; break;
700 aBopString += ("arg1 arg2");
701 if(theOperation == BOPAlgo_CUT21)
704 fprintf(afile, "%s\n",aBopString.ToCString());