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