]> OCCT Git - occt.git/blob - src/BRepAlgoAPI/BRepAlgoAPI_BooleanOperation.cxx
0025614: Provide API access to the new fuctionalities of Boolean Components
[occt.git] / src / BRepAlgoAPI / BRepAlgoAPI_BooleanOperation.cxx
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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <BRepAlgoAPI_BooleanOperation.ixx>
18
19 ///XXXXXXXXXX
20 #include <stdio.h>
21 #include <TCollection_AsciiString.hxx>
22 #include <BRepTools.hxx>
23 #include <OSD_File.hxx>
24 //XXXXXXXXXX
25
26 #include <TopExp.hxx>
27
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>
34
35 #include <BRepAlgoAPI_Check.hxx>
36
37 #include <BRepLib_FuseEdges.hxx>
38
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>
45
46 #include <BOPAlgo_PaveFiller.hxx>
47 #include <BOPAlgo_BOP.hxx>
48 #include <BOPAlgo_Section.hxx>
49
50 //XXXX
51 //=======================================================================
52 //class : BRepAlgoAPI_DumpOper
53 //purpose  : 
54 //=======================================================================
55 class BRepAlgoAPI_DumpOper {
56  public:
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);
63       myPath=pathdump;
64   };
65   //
66   virtual ~BRepAlgoAPI_DumpOper() {
67   };
68   //
69   Standard_Boolean IsDump()const {
70     return myIsDump;
71   };
72   //
73   void SetIsDumpArgs(const Standard_Boolean bFlag) {
74     myIsDumpArgs=bFlag;
75   }
76   //
77   Standard_Boolean IsDumpArgs()const {
78     return myIsDumpArgs;
79   };
80   //
81   void SetIsDumpRes(const Standard_Boolean bFlag) {
82     myIsDumpRes=bFlag;
83   };
84   //
85   Standard_Boolean IsDumpRes()const {
86     return myIsDumpRes;
87   };
88   //
89   void Dump(
90             const TopoDS_Shape& theShape1,
91             const TopoDS_Shape& theShape2,
92             const TopoDS_Shape& theResult,
93             BOPAlgo_Operation theOperation);
94   //
95  protected:
96   Standard_Boolean myIsDump;
97   Standard_Boolean myIsDumpArgs;
98   Standard_Boolean myIsDumpRes;
99   Standard_CString myPath;
100 };
101 //XXXX
102 //=======================================================================
103 //function : BRepAlgoAPI_BooleanOperation
104 //purpose  : 
105 //=======================================================================
106 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation()
107 :
108   BRepAlgoAPI_BuilderAlgo(),  
109   myOperation(BOPAlgo_UNKNOWN),
110   myBuilderCanWork(Standard_False),
111   myFuseEdges(Standard_False)
112
113   myEntryType=1;
114 }
115 //=======================================================================
116 //function : BRepAlgoAPI_BooleanOperation
117 //purpose  : 
118 //=======================================================================
119 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
120   (const BOPAlgo_PaveFiller& aPF)
121 :
122   BRepAlgoAPI_BuilderAlgo(aPF),  
123   myOperation(BOPAlgo_UNKNOWN),
124   myBuilderCanWork(Standard_False),
125   myFuseEdges(Standard_False)
126
127   myEntryType=0;
128 }
129 //=======================================================================
130 //function : BRepAlgoAPI_BooleanOperation
131 //purpose  : 
132 //=======================================================================
133 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
134   (const TopoDS_Shape& aS1, 
135    const TopoDS_Shape& aS2,
136    const BOPAlgo_Operation anOp)
137
138   BRepAlgoAPI_BuilderAlgo(),
139   myOperation(anOp),
140   myBuilderCanWork(Standard_False),
141   myFuseEdges(Standard_False)
142 {
143   myEntryType=1;
144   //
145   myArguments.Append(aS1);
146   myTools.Append(aS2);
147 }
148 //=======================================================================
149 //function : BRepAlgoAPI_BooleanOperation
150 //purpose  : 
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)
157
158   BRepAlgoAPI_BuilderAlgo(aPF),
159   myOperation(anOp),
160   myBuilderCanWork(Standard_False),
161   myFuseEdges(Standard_False)
162
163   myEntryType=0;
164   //
165   myArguments.Append(aS1);
166   myTools.Append(aS2);
167   //
168   myDSFiller=(BOPAlgo_PaveFiller*)&aPF;
169 }
170 //=======================================================================
171 //function : ~
172 //purpose  : 
173 //=======================================================================
174 BRepAlgoAPI_BooleanOperation::~BRepAlgoAPI_BooleanOperation()
175 {
176   Clear();
177 }
178 //=======================================================================
179 //function : Clear
180 //purpose  : 
181 //=======================================================================
182 void BRepAlgoAPI_BooleanOperation::Clear()
183 {
184   BRepAlgoAPI_BuilderAlgo::Clear();
185  
186   myModifFaces.Clear();
187   myEdgeMap.Clear();
188 }
189 //=======================================================================
190 //function : SetTools
191 //purpose  : 
192 //=======================================================================
193 void BRepAlgoAPI_BooleanOperation::SetTools
194   (const TopTools_ListOfShape& theLS)
195 {
196   myTools=theLS;
197 }
198 //=======================================================================
199 //function : Tools
200 //purpose  : 
201 //=======================================================================
202 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Tools()const
203 {
204   return myTools;
205 }
206 //=======================================================================
207 //function : SetOperation
208 //purpose  : 
209 //=======================================================================
210 void BRepAlgoAPI_BooleanOperation::SetOperation 
211   (const BOPAlgo_Operation anOp)
212 {
213   myOperation=anOp;
214 }
215 //=======================================================================
216 //function : Operation
217 //purpose  : 
218 //=======================================================================
219 BOPAlgo_Operation BRepAlgoAPI_BooleanOperation::Operation()const
220 {
221   return myOperation;
222 }
223 //=======================================================================
224 //function : Shape1
225 //purpose  : 
226 //=======================================================================
227 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape1() const 
228 {
229   return myArguments.First();
230 }
231 //=======================================================================
232 //function : Shape2
233 //purpose  : 
234 //=======================================================================
235 const TopoDS_Shape& BRepAlgoAPI_BooleanOperation::Shape2() const 
236 {
237   return myTools.First();
238 }
239 //=======================================================================
240 //function : BuilderCanWork
241 //purpose  : 
242 //=======================================================================
243 Standard_Boolean BRepAlgoAPI_BooleanOperation::BuilderCanWork() const
244 {
245   return myBuilderCanWork;
246 }
247 //=======================================================================
248 //function : FuseEdges
249 //purpose  : 
250 //=======================================================================
251 Standard_Boolean BRepAlgoAPI_BooleanOperation::FuseEdges ()const
252 {
253   return myFuseEdges;
254 }
255 //=======================================================================
256 //function : SetAttributes
257 //purpose  : 
258 //=======================================================================
259 void BRepAlgoAPI_BooleanOperation::SetAttributes()
260 {
261 }
262 //=======================================================================
263 //function : Build2
264 //purpose  : 
265 //=======================================================================
266 void BRepAlgoAPI_BooleanOperation::Build()
267 {
268   Standard_Integer iErr, aNbArgs, aNbTools;  
269   BRepAlgoAPI_DumpOper aDumpOper;
270   //
271   myBuilderCanWork=Standard_False;
272   myErrorStatus=0;
273   NotDone();
274   //
275   aNbArgs=myArguments.Extent();
276   aNbTools=myTools.Extent();
277   if (aNbArgs<1 && aNbTools<1) {
278     myErrorStatus=2;
279     return;
280   }
281   if (myOperation==BOPAlgo_UNKNOWN) {
282     myErrorStatus=6;
283     return;
284   }
285   //
286   //-----------------------------------------------
287   TopTools_ListOfShape aLS;
288   TopTools_ListIteratorOfListOfShape aIt;
289   //
290   aIt.Initialize(myArguments);
291   for (; aIt.More(); aIt.Next()) {
292     const TopoDS_Shape& aS = aIt.Value();
293     aLS.Append(aS);
294   }
295   aIt.Initialize(myTools);
296   for (; aIt.More(); aIt.Next()) {
297     const TopoDS_Shape& aS = aIt.Value();
298     aLS.Append(aS);
299   }
300   //-----------------------------------------------
301   //
302   if (myEntryType) {
303     if (myDSFiller) {
304       delete myDSFiller;
305     }
306     myDSFiller=new BOPAlgo_PaveFiller(myAllocator);
307     //
308     myDSFiller->SetArguments(aLS);
309     //
310     myDSFiller->SetRunParallel(myRunParallel);
311     myDSFiller->SetProgressIndicator(myProgressIndicator);
312     myDSFiller->SetFuzzyValue(myFuzzyValue);
313     //
314     SetAttributes();
315     //
316     myDSFiller->Perform(); 
317     iErr=myDSFiller->ErrorStatus();
318     if (iErr) {
319       myErrorStatus=100+iErr;
320       return;
321     }
322   }// if (myEntryType) {
323   //
324   //XXXX
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());
330   }
331   //XXXX
332   // 
333   if (myBuilder) {
334     delete myBuilder;
335   }
336   //
337   BOPAlgo_BOP *pBOP;
338   //
339   if(myOperation==BOPAlgo_SECTION) {
340     myBuilder=new BOPAlgo_Section(myAllocator);
341     myBuilder->SetArguments(aLS);
342   }
343   else{
344     pBOP=new BOPAlgo_BOP(myAllocator); 
345     pBOP->SetArguments(myArguments);
346     pBOP->SetTools(myTools); 
347     pBOP->SetOperation(myOperation);
348     myBuilder=pBOP;
349   }
350   //
351   myBuilder->SetRunParallel(myRunParallel);
352   myBuilder->SetProgressIndicator(myProgressIndicator);
353   //
354   myBuilder->PerformWithFiller(*myDSFiller);
355   iErr = myBuilder->ErrorStatus();
356   if (iErr) {
357     myErrorStatus=200+iErr;
358     return;
359   }
360   //
361   myShape=myBuilder->Shape();
362   //
363   myBuilderCanWork=Standard_True;
364   Done(); 
365   //
366   //XXXX
367   if (aDumpOper.IsDump()) {
368     BRepAlgoAPI_Check aCheckRes(myShape);
369     aDumpOper.SetIsDumpRes(!aCheckRes.IsValid());
370     aDumpOper.Dump(aS1, aS2, myShape,myOperation);
371   }
372   //XXXX
373 }
374 //=======================================================================
375 //function : RefineEdges
376 //purpose  : 
377 //=======================================================================
378 void BRepAlgoAPI_BooleanOperation::RefineEdges ()
379 {
380   if(myFuseEdges) { 
381     return; //Edges have been refined
382   }
383   //
384   TopTools_IndexedMapOfShape mapOldEdges;
385   TopTools_ListOfShape aLS;
386   TopTools_ListIteratorOfListOfShape aIt;
387   //
388   aIt.Initialize(myArguments);
389   for (; aIt.More(); aIt.Next()) {
390     const TopoDS_Shape& aS = aIt.Value();
391     aLS.Append(aS);
392   }
393   aIt.Initialize(myTools);
394   for (; aIt.More(); aIt.Next()) {
395     const TopoDS_Shape& aS = aIt.Value();
396     aLS.Append(aS);
397   }
398   //
399   aIt.Initialize(aLS);
400   for (; aIt.More(); aIt.Next()) {
401     const TopoDS_Shape& aS = aIt.Value();
402     TopExp::MapShapes (aS, TopAbs_EDGE, mapOldEdges);
403   }
404   //----------------------------------------------
405   BRepLib_FuseEdges FE(myShape);
406   FE.SetConcatBSpl(Standard_True);
407   FE.AvoidEdges (mapOldEdges);
408   //
409   // Get List of edges that have been fused
410   myFuseEdges = Standard_False;
411   myModifFaces.Clear();
412   myEdgeMap.Clear();
413   TopTools_DataMapOfIntegerListOfShape aFusedEdges;
414
415   FE.Edges(aFusedEdges);
416   Standard_Integer nle = aFusedEdges.Extent();
417   if (nle != 0) {
418     FE.Perform();
419     myShape = FE.Shape();
420
421     TopTools_DataMapOfIntegerShape aResultEdges;
422
423     FE.ResultEdges(aResultEdges);
424     FE.Faces(myModifFaces);
425     myFuseEdges = Standard_True;
426     
427     Standard_Integer i;
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);
434       }
435     }
436   }
437 }
438 //=======================================================================
439 //function : RefinedList
440 //purpose  : 
441 //=======================================================================
442 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::RefinedList
443   (const TopTools_ListOfShape& theL) 
444 {
445   myGenerated.Clear();
446   TopTools_MapOfShape aMap;
447
448   TopTools_ListIteratorOfListOfShape anIter(theL);
449
450   for(; anIter.More(); anIter.Next()) {
451     const TopoDS_Shape& anS = anIter.Value();
452
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);
458         }
459       }
460       else {
461         myGenerated.Append(anS);
462       }
463     }
464     else if (anS.ShapeType() == TopAbs_FACE) {
465       if(myModifFaces.IsBound(anS)) {
466         myGenerated.Append(myModifFaces.Find(anS));
467       }
468       else {
469         myGenerated.Append(anS);
470       }
471     }
472     else {
473       myGenerated.Append(anS);
474     }
475   }
476
477   return myGenerated;
478
479 }
480 //=======================================================================
481 //function : SectionEdges
482 //purpose  : 
483 //=======================================================================
484 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::SectionEdges()
485 {
486   if (myBuilder==NULL) {
487     myGenerated.Clear();
488     return myGenerated;
489   }
490   //
491   Standard_Integer aNb, i, j, aNbCurves, nE;
492   BOPDS_ListIteratorOfListOfPaveBlock anIt;
493   //
494   const BOPDS_PDS& pDS = myDSFiller->PDS();
495   BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
496   myGenerated.Clear();
497   //
498   aNb=aFFs.Extent();
499   for (i = 0; i < aNb; i++) {
500     BOPDS_InterfFF& aFFi=aFFs(i);
501     const BOPDS_VectorOfCurve& aSeqOfCurve=aFFi.Curves();
502     //
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();
507       //
508       anIt.Initialize(aSectEdges);
509       for(; anIt.More(); anIt.Next()) {
510         const Handle(BOPDS_PaveBlock)& aPB = anIt.Value();
511         nE = aPB->Edge();
512         const TopoDS_Shape& aE = pDS->Shape(nE);
513         myGenerated.Append(aE);
514       }
515     }
516   }
517   //
518   if(myFuseEdges) {
519     TopTools_ListOfShape theLS;
520     theLS.Assign(myGenerated);
521     //
522     RefinedList(theLS);
523   }
524   //
525   return myGenerated;
526 }
527 //=======================================================================
528 //function : Generated
529 //purpose  : 
530 //=======================================================================
531 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Generated
532   (const TopoDS_Shape& S) 
533 {
534   if (myBuilder==NULL) {
535     myGenerated.Clear();
536     return myGenerated;
537   }
538   //
539   if(myFuseEdges) {
540     const TopTools_ListOfShape& aL = myBuilder->Generated(S);
541     return RefinedList(aL);
542   }
543   
544   return myBuilder->Generated(S);
545 }
546
547 //=======================================================================
548 //function : Modified
549 //purpose  : 
550 //=======================================================================
551 const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Modified
552   (const TopoDS_Shape& aS) 
553 {
554   if (myBuilder==NULL) {
555     myGenerated.Clear();
556     return myGenerated;
557   }
558   else {
559     myGenerated = myBuilder->Modified(aS);
560
561     if(myFuseEdges) {
562       TopTools_ListOfShape theLS;
563       theLS.Assign(myGenerated);
564       //
565       RefinedList(theLS);
566     }
567     return myGenerated;
568   }
569 }
570 //=======================================================================
571 //function : IsDeleted
572 //purpose  : 
573 //=======================================================================
574 Standard_Boolean BRepAlgoAPI_BooleanOperation::IsDeleted
575   (const TopoDS_Shape& aS) 
576 {
577   Standard_Boolean bDeleted = Standard_True; 
578   if (myBuilder != NULL) {
579     bDeleted=myBuilder->IsDeleted(aS);
580   }
581   return bDeleted; 
582 }
583 //=======================================================================
584 //function : HasModified
585 //purpose  : 
586 //=======================================================================
587 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasModified() const
588 {
589   if (myBuilder==NULL) {
590     return Standard_False;
591   }
592   return myBuilder->HasModified();
593 }
594 //=======================================================================
595 //function : HasGenerated
596 //purpose  : 
597 //=======================================================================
598 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasGenerated() const
599 {
600   if (myBuilder==NULL) {
601     return Standard_False;
602   }
603   return myBuilder->HasGenerated();
604 }
605 //=======================================================================
606 //function : HasDeleted
607 //purpose  : 
608 //=======================================================================
609 Standard_Boolean BRepAlgoAPI_BooleanOperation::HasDeleted() const
610 {
611   if (myBuilder==NULL) {
612     return Standard_False;
613   }
614   return myBuilder->HasDeleted();
615 }
616 //XXXX
617 //=======================================================================
618 //function : Dump
619 //purpose  : 
620 //=======================================================================
621 void BRepAlgoAPI_DumpOper::Dump (const TopoDS_Shape& theShape1,
622                                  const TopoDS_Shape& theShape2,
623                                  const TopoDS_Shape& theResult,
624                                  BOPAlgo_Operation theOperation)
625 {
626   if (!(myIsDumpArgs && myIsDumpRes)) {
627     return;
628   }
629   //
630   TCollection_AsciiString aPath(myPath);
631   aPath += "/";
632   Standard_Integer aNumOper = 1;
633   Standard_Boolean isExist = Standard_True;
634   TCollection_AsciiString aFileName;
635  
636   while(isExist)
637   {
638     aFileName = aPath + "BO_" + TCollection_AsciiString(aNumOper) +".tcl";
639     OSD_File aScript(aFileName);
640     isExist = aScript.Exists();
641     if(isExist)
642       aNumOper++;
643   }
644
645   FILE* afile = fopen(aFileName.ToCString(), "w+");
646   if(!afile)
647     return;
648   if(myIsDumpArgs)
649     fprintf(afile,"%s\n","# Arguments are invalid");
650
651   TCollection_AsciiString aName1;
652   TCollection_AsciiString aName2;
653   TCollection_AsciiString aNameRes;
654   if(!theShape1.IsNull())
655   {
656     aName1 = aPath +
657       "Arg1_" + TCollection_AsciiString(aNumOper) + ".brep";
658     BRepTools::Write(theShape1, aName1.ToCString());
659   }
660   else
661     fprintf(afile,"%s\n","# First argument is Null ");
662    
663   if(!theShape2.IsNull())
664   {
665     aName2 =  aPath +
666       "Arg2_"+ TCollection_AsciiString(aNumOper) + ".brep";
667
668     BRepTools::Write(theShape2, aName2.ToCString());
669   }
670   else
671     fprintf(afile,"%s\n","# Second argument is Null ");
672    
673    if(!theResult.IsNull())
674   {
675     aNameRes =  aPath +
676       "Result_"+ TCollection_AsciiString(aNumOper) + ".brep";
677
678     BRepTools::Write(theResult, aNameRes.ToCString());
679   }
680   else
681     fprintf(afile,"%s\n","# Result is Null ");
682   
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)
687   {
688     case BOPAlgo_COMMON : aBopString += "bcommon Res "; break;
689     case BOPAlgo_FUSE   : aBopString += "bfuse Res "; break;
690     case BOPAlgo_CUT    : 
691     case BOPAlgo_CUT21  : aBopString += "bcut Res "; break;
692     case BOPAlgo_SECTION : aBopString += "bsection Res "; break;
693     default : break;
694   };
695   aBopString += ("arg1 arg2");
696   if(theOperation == BOPAlgo_CUT21)
697     aBopString += " 1";
698
699   fprintf(afile, "%s\n",aBopString.ToCString());
700   fclose(afile);
701 }
702 //XXXX