Salome HOME
Added a method to disable waiting cursor in the preview operation
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IBooleanOperations.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22 #include <Standard_Stream.hxx>
23
24 #include <GEOMImpl_IBooleanOperations.hxx>
25
26 #include <GEOM_Function.hxx>
27 #include <GEOM_PythonDump.hxx>
28
29 #include <GEOMImpl_Types.hxx>
30
31 #include <GEOMImpl_BooleanDriver.hxx>
32 #include <GEOMImpl_IBoolean.hxx>
33
34 #include <GEOMImpl_PartitionDriver.hxx>
35 #include <GEOMImpl_IPartition.hxx>
36
37 #include <Basics_OCCTVersion.hxx>
38
39 #include <TDF_Tool.hxx>
40
41 #include "utilities.h"
42
43 #include <Standard_Failure.hxx>
44 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
45
46 //=============================================================================
47 /*!
48  *   constructor:
49  */
50 //=============================================================================
51 GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations (GEOM_Engine* theEngine, int theDocID)
52 : GEOM_IOperations(theEngine, theDocID)
53 {
54   MESSAGE("GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations");
55 }
56
57 //=============================================================================
58 /*!
59  *  destructor
60  */
61 //=============================================================================
62 GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations()
63 {
64   MESSAGE("GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations");
65 }
66
67
68 //=============================================================================
69 /*!
70  *  MakeBoolean
71  */
72 //=============================================================================
73 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeBoolean (Handle(GEOM_Object) theShape1,
74                                                               Handle(GEOM_Object) theShape2,
75                                                               Standard_Integer    theOp)
76 {
77   SetErrorCode(KO);
78
79   if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
80
81   //Add a new Boolean object
82   Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
83
84   //Add a new Boolean function
85   Handle(GEOM_Function) aFunction;
86   if (theOp == 1) {
87     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_COMMON);
88   } else if (theOp == 2) {
89     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_CUT);
90   } else if (theOp == 3) {
91     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_FUSE);
92   } else if (theOp == 4) {
93     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_SECTION);
94   } else {
95   }
96   if (aFunction.IsNull()) return NULL;
97
98   //Check if the function is set correctly
99   if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
100
101   GEOMImpl_IBoolean aCI (aFunction);
102
103   Handle(GEOM_Function) aRef1 = theShape1->GetLastFunction();
104   Handle(GEOM_Function) aRef2 = theShape2->GetLastFunction();
105
106   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
107
108   aCI.SetShape1(aRef1);
109   aCI.SetShape2(aRef2);
110
111   //Compute the Boolean value
112   try {
113 #if OCC_VERSION_LARGE > 0x06010000
114     OCC_CATCH_SIGNALS;
115 #endif
116     if (!GetSolver()->ComputeFunction(aFunction)) {
117       SetErrorCode("Boolean driver failed");
118       return NULL;
119     }
120   }
121   catch (Standard_Failure) {
122     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
123     SetErrorCode(aFail->GetMessageString());
124     return NULL;
125   }
126
127   //Make a Python command
128   GEOM::TPythonDump pd (aFunction);
129   pd << aBool;
130   if      (theOp == 1) pd << " = geompy.MakeCommon(";
131   else if (theOp == 2) pd << " = geompy.MakeCut(";
132   else if (theOp == 3) pd << " = geompy.MakeFuse(";
133   else if (theOp == 4) pd << " = geompy.MakeSection(";
134   else {}
135   pd << theShape1 << ", " << theShape2 << ")";
136
137   SetErrorCode(OK);
138   return aBool;
139 }
140
141 //=============================================================================
142 /*!
143  *  MakePartition
144  */
145 //=============================================================================
146 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakePartition
147                              (const Handle(TColStd_HSequenceOfTransient)& theShapes,
148                               const Handle(TColStd_HSequenceOfTransient)& theTools,
149                               const Handle(TColStd_HSequenceOfTransient)& theKeepIns,
150                               const Handle(TColStd_HSequenceOfTransient)& theRemoveIns,
151                               const Standard_Integer                      theLimit,
152                               const Standard_Boolean                      theRemoveWebs,
153                               const Handle(TColStd_HArray1OfInteger)&     theMaterials,
154                               const Standard_Integer theKeepNonlimitShapes,
155                               const Standard_Boolean thePerformSelfIntersections)
156 {
157   SetErrorCode(KO);
158
159   //Add a new Partition object
160   Handle(GEOM_Object) aPartition = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
161
162   //Add a new Partition function
163   Handle(GEOM_Function) aFunction;
164   if (thePerformSelfIntersections)
165     aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_PARTITION);
166   else
167     aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_NO_SELF_INTERSECTIONS);
168   if (aFunction.IsNull()) return NULL;
169
170   //Check if the function is set correctly
171   if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
172
173   GEOMImpl_IPartition aCI (aFunction);
174
175   Handle(TColStd_HSequenceOfTransient) aShapesSeq  = new TColStd_HSequenceOfTransient;
176   Handle(TColStd_HSequenceOfTransient) aToolsSeq   = new TColStd_HSequenceOfTransient;
177   Handle(TColStd_HSequenceOfTransient) aKeepInsSeq = new TColStd_HSequenceOfTransient;
178   Handle(TColStd_HSequenceOfTransient) aRemInsSeq  = new TColStd_HSequenceOfTransient;
179
180   Standard_Integer ind, aLen;
181   TCollection_AsciiString anEntry;
182   TCollection_AsciiString aShapesDescr, aToolsDescr, aKeepInsDescr, aRemoveInsDescr;
183
184   // Shapes
185   aLen = theShapes->Length();
186   for (ind = 1; ind <= aLen; ind++) {
187     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theShapes->Value(ind));
188     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
189     if (aRefSh.IsNull()) {
190       SetErrorCode("NULL shape for Partition");
191       return NULL;
192     }
193     aShapesSeq->Append(aRefSh);
194
195     // For Python command
196     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
197     if (ind > 1) aShapesDescr += ", ";
198     aShapesDescr += anEntry;
199   }
200   aCI.SetShapes(aShapesSeq);
201
202   // Tools
203   aLen = theTools->Length();
204   for (ind = 1; ind <= aLen; ind++) {
205     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theTools->Value(ind));
206     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
207     if (aRefSh.IsNull()) {
208       SetErrorCode("NULL tool shape for Partition");
209       return NULL;
210     }
211     aToolsSeq->Append(aRefSh);
212
213     // For Python command
214     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
215     if (ind > 1) aToolsDescr += ", ";
216     aToolsDescr += anEntry;
217   }
218   aCI.SetTools(aToolsSeq);
219
220   // Keep Inside
221   aLen = theKeepIns->Length();
222   for (ind = 1; ind <= aLen; ind++) {
223     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theKeepIns->Value(ind));
224     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
225     if (aRefSh.IsNull()) {
226       SetErrorCode("NULL <keep inside> shape for Partition");
227       return NULL;
228     }
229     aKeepInsSeq->Append(aRefSh);
230
231     // For Python command
232     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
233     if (ind > 1) aKeepInsDescr += ", ";
234     aKeepInsDescr += anEntry;
235   }
236   aCI.SetKeepIns(aKeepInsSeq);
237
238   // Remove Inside
239   aLen = theRemoveIns->Length();
240   for (ind = 1; ind <= aLen; ind++) {
241     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theRemoveIns->Value(ind));
242     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
243     if (aRefSh.IsNull()) {
244       SetErrorCode("NULL <remove inside> shape for Partition");
245       return NULL;
246     }
247     aRemInsSeq->Append(aRefSh);
248
249     // For Python command
250     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
251     if (ind > 1) aRemoveInsDescr += ", ";
252     aRemoveInsDescr += anEntry;
253   }
254   aCI.SetRemoveIns(aRemInsSeq);
255
256   // Limit
257   aCI.SetLimit(theLimit);
258   aCI.SetKeepNonlimitShapes(theKeepNonlimitShapes);
259
260   // Materials
261   if (theRemoveWebs) {
262     if (theMaterials.IsNull()) {
263       Handle(TColStd_HArray1OfInteger) aMaterials =
264         new TColStd_HArray1OfInteger (1, aShapesSeq->Length());
265       aMaterials->Init(0);
266       aCI.SetMaterials(aMaterials);
267     } else {
268       aCI.SetMaterials(theMaterials);
269     }
270   }
271
272   //Compute the Partition
273   try {
274 #if OCC_VERSION_LARGE > 0x06010000
275     OCC_CATCH_SIGNALS;
276 #endif
277     if (!GetSolver()->ComputeFunction(aFunction)) {
278       SetErrorCode("Partition driver failed");
279       return NULL;
280     }
281   }
282   catch (Standard_Failure) {
283     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
284     SetErrorCode(aFail->GetMessageString());
285     return NULL;
286   }
287
288   //Make a Python command
289   GEOM::TPythonDump pd (aFunction);
290   if (thePerformSelfIntersections)
291     pd << aPartition << " = geompy.MakePartition([";
292   else
293     pd << aPartition << " = geompy.MakePartitionNonSelfIntersectedShape([";
294
295   // Shapes, Tools
296   pd << aShapesDescr.ToCString() << "], [" << aToolsDescr.ToCString() << "], [";
297   // Keep Ins, Remove Ins
298   pd << aKeepInsDescr.ToCString() << "], [" << aRemoveInsDescr.ToCString() << "], ";
299   // Limit, Remove Webs
300   pd << TopAbs_ShapeEnum(theLimit) << ", " << (int)theRemoveWebs << ", [";
301   // Materials
302   if (!theMaterials.IsNull() && theMaterials->Length() > 0) {
303     int i = theMaterials->Lower();
304     pd << theMaterials->Value(i);
305     i++;
306     for (; i <= theMaterials->Upper(); i++) {
307       pd << ", " << theMaterials->Value(i);
308     }
309   }
310   pd << "], " << theKeepNonlimitShapes <<")";
311
312   SetErrorCode(OK);
313   return aPartition;
314 }
315
316 //=============================================================================
317 /*!
318  *  MakeHalfPartition
319  */
320 //=============================================================================
321 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeHalfPartition
322        (Handle(GEOM_Object) theShape, Handle(GEOM_Object) thePlane)
323 {
324   SetErrorCode(KO);
325
326   if (theShape.IsNull() || thePlane.IsNull()) return NULL;
327
328   //Add a new Boolean object
329   Handle(GEOM_Object) aPart = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
330
331   //Add a new Partition function
332   Handle(GEOM_Function) aFunction =
333     aPart->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_HALF);
334   if (aFunction.IsNull()) return NULL;
335
336   //Check if the function is set correctly
337   if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
338
339   GEOMImpl_IPartition aCI (aFunction);
340
341   Handle(GEOM_Function) aRef1 = theShape->GetLastFunction();
342   Handle(GEOM_Function) aRef2 = thePlane->GetLastFunction();
343
344   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
345
346   aCI.SetShape(aRef1);
347   aCI.SetPlane(aRef2);
348
349   //Compute the Partition value
350   try {
351 #if OCC_VERSION_LARGE > 0x06010000
352     OCC_CATCH_SIGNALS;
353 #endif
354     if (!GetSolver()->ComputeFunction(aFunction)) {
355       SetErrorCode("Partition driver failed");
356       return NULL;
357     }
358   }
359   catch (Standard_Failure) {
360     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
361     SetErrorCode(aFail->GetMessageString());
362     return NULL;
363   }
364
365   //Make a Python command
366   GEOM::TPythonDump(aFunction) << aPart << " = geompy.MakeHalfPartition("
367                                << theShape << ", " << thePlane << ")";
368
369   SetErrorCode(OK);
370   return aPart;
371 }