9d86a61ae3c18e9322c760510b6bdb3bcb3d7462
[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
18 #include <BRepAlgoAPI_BooleanOperation.hxx>
19
20 #include <BOPAlgo_Alerts.hxx>
21 #include <BOPAlgo_BOP.hxx>
22 #include <BOPAlgo_PaveFiller.hxx>
23 #include <BOPAlgo_Section.hxx>
24 #include <BRepAlgoAPI_Check.hxx>
25 #include <BRepTools.hxx>
26
27 #include <OSD_Environment.hxx>
28 #include <OSD_File.hxx>
29 #include <TCollection_AsciiString.hxx>
30
31 #include <stdio.h>
32
33 //=======================================================================
34 //class : BRepAlgoAPI_DumpOper
35 //purpose : Dumps the arguments ad script to perform operation in DRAW
36 //=======================================================================
37 class BRepAlgoAPI_DumpOper {
38  public:
39   BRepAlgoAPI_DumpOper() :
40     myIsDump(Standard_False),
41     myIsDumpArgs(Standard_False),
42     myIsDumpRes(Standard_False)  {
43       OSD_Environment env("CSF_DEBUG_BOP");
44       TCollection_AsciiString pathdump = env.Value();
45       myIsDump = (!pathdump.IsEmpty() ? Standard_True: Standard_False);
46       myPath=pathdump.ToCString();
47   };
48   //
49   virtual ~BRepAlgoAPI_DumpOper() {
50   };
51   //
52   Standard_Boolean IsDump()const {
53     return myIsDump;
54   };
55   //
56   void SetIsDumpArgs(const Standard_Boolean bFlag) {
57     myIsDumpArgs=bFlag;
58   }
59   //
60   Standard_Boolean IsDumpArgs()const {
61     return myIsDumpArgs;
62   };
63   //
64   void SetIsDumpRes(const Standard_Boolean bFlag) {
65     myIsDumpRes=bFlag;
66   };
67   //
68   Standard_Boolean IsDumpRes()const {
69     return myIsDumpRes;
70   };
71   //
72   void Dump(
73             const TopoDS_Shape& theShape1,
74             const TopoDS_Shape& theShape2,
75             const TopoDS_Shape& theResult,
76             BOPAlgo_Operation theOperation);
77   //
78  protected:
79   Standard_Boolean myIsDump;
80   Standard_Boolean myIsDumpArgs;
81   Standard_Boolean myIsDumpRes;
82   Standard_CString myPath;
83 };
84
85 //=======================================================================
86 //function : BRepAlgoAPI_BooleanOperation
87 //purpose  : 
88 //=======================================================================
89 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation()
90 :
91   BRepAlgoAPI_BuilderAlgo(),
92   myOperation(BOPAlgo_UNKNOWN)
93 {
94 }
95 //=======================================================================
96 //function : BRepAlgoAPI_BooleanOperation
97 //purpose  : 
98 //=======================================================================
99 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
100   (const BOPAlgo_PaveFiller& thePF)
101 :
102   BRepAlgoAPI_BuilderAlgo(thePF),
103   myOperation(BOPAlgo_UNKNOWN)
104 {
105 }
106 //=======================================================================
107 //function : BRepAlgoAPI_BooleanOperation
108 //purpose  : obsolete
109 //=======================================================================
110 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
111   (const TopoDS_Shape& theS1,
112    const TopoDS_Shape& theS2,
113    const BOPAlgo_Operation theOp)
114 :
115   BRepAlgoAPI_BuilderAlgo(),
116   myOperation(theOp)
117 {
118   myArguments.Append(theS1);
119   myTools.Append(theS2);
120 }
121 //=======================================================================
122 //function : BRepAlgoAPI_BooleanOperation
123 //purpose  : 
124 //=======================================================================
125 BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation
126   (const TopoDS_Shape& theS1,
127    const TopoDS_Shape& theS2,
128    const BOPAlgo_PaveFiller& thePF,
129    const BOPAlgo_Operation theOp)
130 :
131   BRepAlgoAPI_BuilderAlgo(thePF),
132   myOperation(theOp)
133 {
134   myArguments.Append(theS1);
135   myTools.Append(theS2);
136 }
137 //=======================================================================
138 //function : Build
139 //purpose  :
140 //=======================================================================
141 void BRepAlgoAPI_BooleanOperation::Build()
142 {
143   // Set Not Done status by default
144   NotDone();
145   // Clear from previous runs
146   Clear();
147   // Check for availability of arguments and tools
148   // Both should be present
149   if (myArguments.IsEmpty() || myTools.IsEmpty())
150   {
151     AddError (new BOPAlgo_AlertTooFewArguments);
152     return;
153   }
154   // Check if the operation is set
155   if (myOperation == BOPAlgo_UNKNOWN)
156   {
157     AddError (new BOPAlgo_AlertBOPNotSet);
158     return;
159   }
160
161   // DEBUG option for dumping shapes and scripts
162   BRepAlgoAPI_DumpOper aDumpOper;
163   {
164     if (aDumpOper.IsDump()) {
165       BRepAlgoAPI_Check aChekArgs(myArguments.First(), myTools.First(), myOperation);
166       aDumpOper.SetIsDumpArgs(!aChekArgs.IsValid());
167     }
168   }
169
170   // If necessary perform intersection of the argument shapes
171   if (myIsIntersectionNeeded)
172   {
173     // Combine Objects and Tools into a single list for intersection
174     TopTools_ListOfShape aLArgs = myArguments;
175     for (TopTools_ListOfShape::Iterator it(myTools); it.More(); it.Next())
176       aLArgs.Append(it.Value());
177
178     // Perform intersection
179     IntersectShapes(aLArgs);
180     if (HasErrors())
181     {
182       if (aDumpOper.IsDump())
183       {
184         aDumpOper.SetIsDumpRes(Standard_False);
185         aDumpOper.Dump(myArguments.First(), myTools.First(), TopoDS_Shape(), myOperation);
186       }
187       return;
188     }
189   }
190
191   // Builder Initialization
192   if (myOperation == BOPAlgo_SECTION)
193   {
194     myBuilder = new BOPAlgo_Section(myAllocator);
195     myBuilder->SetArguments(myDSFiller->Arguments());
196   }
197   else
198   {
199     myBuilder = new BOPAlgo_BOP(myAllocator);
200     myBuilder->SetArguments(myArguments);
201     ((BOPAlgo_BOP*)myBuilder)->SetTools(myTools);
202     ((BOPAlgo_BOP*)myBuilder)->SetOperation(myOperation);
203   }
204
205   // Build the result
206   BuildResult();
207
208   if (aDumpOper.IsDump()) {
209     Standard_Boolean isDumpRes = myShape.IsNull() ||
210                                  !BRepAlgoAPI_Check(myShape).IsValid();
211     aDumpOper.SetIsDumpRes(isDumpRes);
212     aDumpOper.Dump(myArguments.First(), myTools.First(), myShape, myOperation);
213   }
214 }
215
216 //=======================================================================
217 //function : Dump
218 //purpose  : DEBUG: Dumping the shapes and script of the operation
219 //=======================================================================
220 void BRepAlgoAPI_DumpOper::Dump(const TopoDS_Shape& theShape1,
221                                 const TopoDS_Shape& theShape2,
222                                 const TopoDS_Shape& theResult,
223                                 BOPAlgo_Operation theOperation)
224 {
225   if (!(myIsDumpArgs && myIsDumpRes)) {
226     return;
227   }
228   //
229   TCollection_AsciiString aPath(myPath);
230   aPath += "/";
231   Standard_Integer aNumOper = 1;
232   Standard_Boolean isExist = Standard_True;
233   TCollection_AsciiString aFileName;
234  
235   while(isExist)
236   {
237     aFileName = aPath + "BO_" + TCollection_AsciiString(aNumOper) +".tcl";
238     OSD_File aScript(aFileName);
239     isExist = aScript.Exists();
240     if(isExist)
241       aNumOper++;
242   }
243
244   FILE* afile = fopen(aFileName.ToCString(), "w+");
245   if(!afile)
246     return;
247   if(myIsDumpArgs)
248     fprintf(afile,"%s\n","# Arguments are invalid");
249
250   TCollection_AsciiString aName1;
251   TCollection_AsciiString aName2;
252   TCollection_AsciiString aNameRes;
253   if(!theShape1.IsNull())
254   {
255     aName1 = aPath +
256       "Arg1_" + TCollection_AsciiString(aNumOper) + ".brep";
257     BRepTools::Write(theShape1, aName1.ToCString());
258   }
259   else
260     fprintf(afile,"%s\n","# First argument is Null ");
261    
262   if(!theShape2.IsNull())
263   {
264     aName2 =  aPath +
265       "Arg2_"+ TCollection_AsciiString(aNumOper) + ".brep";
266
267     BRepTools::Write(theShape2, aName2.ToCString());
268   }
269   else
270     fprintf(afile,"%s\n","# Second argument is Null ");
271    
272    if(!theResult.IsNull())
273   {
274     aNameRes =  aPath +
275       "Result_"+ TCollection_AsciiString(aNumOper) + ".brep";
276
277     BRepTools::Write(theResult, aNameRes.ToCString());
278   }
279   else
280     fprintf(afile,"%s\n","# Result is Null ");
281   
282   fprintf(afile, "%s %s %s\n","restore",  aName1.ToCString(), "arg1");
283   fprintf(afile, "%s %s %s\n","restore",  aName2.ToCString(), "arg2");;
284   TCollection_AsciiString aBopString;
285   switch (theOperation)
286   {
287     case BOPAlgo_COMMON : aBopString += "bcommon Res "; break;
288     case BOPAlgo_FUSE   : aBopString += "bfuse Res "; break;
289     case BOPAlgo_CUT    : 
290     case BOPAlgo_CUT21  : aBopString += "bcut Res "; break;
291     case BOPAlgo_SECTION : aBopString += "bsection Res "; break;
292     default : break;
293   };
294   aBopString += ("arg1 arg2");
295   if(theOperation == BOPAlgo_CUT21)
296     aBopString += " 1";
297
298   fprintf(afile, "%s\n",aBopString.ToCString());
299   fclose(afile);
300 }