0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[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(const Message_ProgressRange& theRange)
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   TCollection_AsciiString aPSName;
171   switch (myOperation)
172   {
173     case BOPAlgo_COMMON:
174       aPSName = "Performing COMMON operation";
175       break;
176     case BOPAlgo_FUSE:
177       aPSName = "Performing FUSE operation";
178       break;
179     case BOPAlgo_CUT:
180     case BOPAlgo_CUT21:
181       aPSName = "Performing CUT operation";
182       break;
183     case BOPAlgo_SECTION:
184       aPSName = "Performing SECTION operation";
185       break;
186     default:
187       return;
188   }
189
190   Message_ProgressScope aPS(theRange, aPSName, myIsIntersectionNeeded ? 100 : 30);
191   // If necessary perform intersection of the argument shapes
192   if (myIsIntersectionNeeded)
193   {
194     // Combine Objects and Tools into a single list for intersection
195     TopTools_ListOfShape aLArgs = myArguments;
196     for (TopTools_ListOfShape::Iterator it(myTools); it.More(); it.Next())
197       aLArgs.Append(it.Value());
198
199     // Perform intersection
200     IntersectShapes(aLArgs, aPS.Next(70));
201     if (HasErrors())
202     {
203       if (aDumpOper.IsDump())
204       {
205         aDumpOper.SetIsDumpRes(Standard_False);
206         aDumpOper.Dump(myArguments.First(), myTools.First(), TopoDS_Shape(), myOperation);
207       }
208       return;
209     }
210   }
211
212   // Builder Initialization
213   if (myOperation == BOPAlgo_SECTION)
214   {
215     myBuilder = new BOPAlgo_Section(myAllocator);
216     myBuilder->SetArguments(myDSFiller->Arguments());
217   }
218   else
219   {
220     myBuilder = new BOPAlgo_BOP(myAllocator);
221     myBuilder->SetArguments(myArguments);
222     ((BOPAlgo_BOP*)myBuilder)->SetTools(myTools);
223     ((BOPAlgo_BOP*)myBuilder)->SetOperation(myOperation);
224   }
225
226   // Build the result
227   BuildResult(aPS.Next(30));
228   if (HasErrors())
229   {
230     return;
231   }
232
233   if (aDumpOper.IsDump()) {
234     Standard_Boolean isDumpRes = myShape.IsNull() ||
235                                  !BRepAlgoAPI_Check(myShape).IsValid();
236     aDumpOper.SetIsDumpRes(isDumpRes);
237     aDumpOper.Dump(myArguments.First(), myTools.First(), myShape, myOperation);
238   }
239 }
240
241 //=======================================================================
242 //function : Dump
243 //purpose  : DEBUG: Dumping the shapes and script of the operation
244 //=======================================================================
245 void BRepAlgoAPI_DumpOper::Dump(const TopoDS_Shape& theShape1,
246                                 const TopoDS_Shape& theShape2,
247                                 const TopoDS_Shape& theResult,
248                                 BOPAlgo_Operation theOperation)
249 {
250   if (!(myIsDumpArgs && myIsDumpRes)) {
251     return;
252   }
253   //
254   TCollection_AsciiString aPath(myPath);
255   aPath += "/";
256   Standard_Integer aNumOper = 1;
257   Standard_Boolean isExist = Standard_True;
258   TCollection_AsciiString aFileName;
259  
260   while(isExist)
261   {
262     aFileName = aPath + "BO_" + TCollection_AsciiString(aNumOper) +".tcl";
263     OSD_File aScript(aFileName);
264     isExist = aScript.Exists();
265     if(isExist)
266       aNumOper++;
267   }
268
269   FILE* afile = fopen(aFileName.ToCString(), "w+");
270   if(!afile)
271     return;
272   if(myIsDumpArgs)
273     fprintf(afile,"%s\n","# Arguments are invalid");
274
275   TCollection_AsciiString aName1;
276   TCollection_AsciiString aName2;
277   TCollection_AsciiString aNameRes;
278   if(!theShape1.IsNull())
279   {
280     aName1 = aPath +
281       "Arg1_" + TCollection_AsciiString(aNumOper) + ".brep";
282     BRepTools::Write(theShape1, aName1.ToCString());
283   }
284   else
285     fprintf(afile,"%s\n","# First argument is Null ");
286    
287   if(!theShape2.IsNull())
288   {
289     aName2 =  aPath +
290       "Arg2_"+ TCollection_AsciiString(aNumOper) + ".brep";
291
292     BRepTools::Write(theShape2, aName2.ToCString());
293   }
294   else
295     fprintf(afile,"%s\n","# Second argument is Null ");
296    
297    if(!theResult.IsNull())
298   {
299     aNameRes =  aPath +
300       "Result_"+ TCollection_AsciiString(aNumOper) + ".brep";
301
302     BRepTools::Write(theResult, aNameRes.ToCString());
303   }
304   else
305     fprintf(afile,"%s\n","# Result is Null ");
306   
307   fprintf(afile, "%s %s %s\n","restore",  aName1.ToCString(), "arg1");
308   fprintf(afile, "%s %s %s\n","restore",  aName2.ToCString(), "arg2");
309   TCollection_AsciiString aBopString;
310   switch (theOperation)
311   {
312     case BOPAlgo_COMMON : aBopString += "bcommon Res "; break;
313     case BOPAlgo_FUSE   : aBopString += "bfuse Res "; break;
314     case BOPAlgo_CUT    : 
315     case BOPAlgo_CUT21  : aBopString += "bcut Res "; break;
316     case BOPAlgo_SECTION : aBopString += "bsection Res "; break;
317     default : break;
318   };
319   aBopString += ("arg1 arg2");
320   if(theOperation == BOPAlgo_CUT21)
321     aBopString += " 1";
322
323   fprintf(afile, "%s\n",aBopString.ToCString());
324   fclose(afile);
325 }