Salome HOME
Join modifications from branch BR_DEBUG_3_2_0b1
[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_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
40
41 //=============================================================================
42 /*!
43  *   constructor:
44  */
45 //=============================================================================
46 GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations (GEOM_Engine* theEngine, int theDocID) 
47 : GEOM_IOperations(theEngine, theDocID)
48 {
49   MESSAGE("GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations");
50 }
51
52 //=============================================================================
53 /*!
54  *  destructor
55  */
56 //=============================================================================
57 GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations()
58 {
59   MESSAGE("GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations");
60 }
61
62
63 //=============================================================================
64 /*!
65  *  MakeBoolean
66  */
67 //=============================================================================
68 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeBoolean (Handle(GEOM_Object) theShape1,
69                                                               Handle(GEOM_Object) theShape2,
70                                                               Standard_Integer    theOp)
71 {
72   SetErrorCode(KO);
73
74   if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
75  
76   //Add a new Boolean object  
77   Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
78  
79   //Add a new Boolean function
80   Handle(GEOM_Function) aFunction;
81   if (theOp == 1) {
82     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_COMMON);
83   } else if (theOp == 2) {
84     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_CUT);
85   } else if (theOp == 3) {
86     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_FUSE);
87   } else if (theOp == 4) {
88     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_SECTION);
89   } else {
90   }
91   if (aFunction.IsNull()) return NULL;
92
93   //Check if the function is set correctly
94   if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL; 
95
96   GEOMImpl_IBoolean aCI (aFunction);
97   
98   Handle(GEOM_Function) aRef1 = theShape1->GetLastFunction();
99   Handle(GEOM_Function) aRef2 = theShape2->GetLastFunction();
100
101   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
102
103   aCI.SetShape1(aRef1);
104   aCI.SetShape2(aRef2);
105
106   //Compute the Boolean value
107   try {
108     if (!GetSolver()->ComputeFunction(aFunction)) {
109       SetErrorCode("Boolean driver failed");
110       return NULL;
111     }
112   }
113   catch (Standard_Failure) {
114     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
115     SetErrorCode(aFail->GetMessageString());
116     return NULL;
117   }
118
119   //Make a Python command
120   GEOM::TPythonDump pd (aFunction);
121   pd << aBool;
122   if      (theOp == 1) pd << " = geompy.MakeCommon(";
123   else if (theOp == 2) pd << " = geompy.MakeCut(";
124   else if (theOp == 3) pd << " = geompy.MakeFuse(";
125   else if (theOp == 4) pd << " = geompy.MakeSection(";
126   else {}
127   pd << theShape1 << ", " << theShape2 << ")";
128
129   SetErrorCode(OK);
130   return aBool; 
131 }
132
133 //=============================================================================
134 /*!
135  *  MakePartition
136  */
137 //=============================================================================
138 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakePartition
139                              (const Handle(TColStd_HSequenceOfTransient)& theShapes, 
140                               const Handle(TColStd_HSequenceOfTransient)& theTools,
141                               const Handle(TColStd_HSequenceOfTransient)& theKeepIns,
142                               const Handle(TColStd_HSequenceOfTransient)& theRemoveIns,
143                               const Standard_Integer           theLimit,
144                               const Standard_Boolean           theRemoveWebs,
145                               const Handle(TColStd_HArray1OfInteger)& theMaterials)
146 {
147   SetErrorCode(KO);
148
149   //Add a new Partition object  
150   Handle(GEOM_Object) aPartition = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
151  
152   //Add a new Partition function
153   Handle(GEOM_Function) aFunction =
154     aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_PARTITION);
155   if (aFunction.IsNull()) return NULL;
156
157   //Check if the function is set correctly
158   if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL; 
159
160   GEOMImpl_IPartition aCI (aFunction);
161   
162 //  int aLen = theShapes.size();
163 //  aCI.SetLength(aLen);
164
165   Handle(TColStd_HSequenceOfTransient) aShapesSeq  = new TColStd_HSequenceOfTransient;
166   Handle(TColStd_HSequenceOfTransient) aToolsSeq   = new TColStd_HSequenceOfTransient;
167   Handle(TColStd_HSequenceOfTransient) aKeepInsSeq = new TColStd_HSequenceOfTransient;
168   Handle(TColStd_HSequenceOfTransient) aRemInsSeq  = new TColStd_HSequenceOfTransient;
169
170   Standard_Integer ind, aLen;
171   TCollection_AsciiString anEntry;
172   TCollection_AsciiString aShapesDescr, aToolsDescr, aKeepInsDescr, aRemoveInsDescr;
173
174   // Shapes
175   aLen = theShapes->Length();
176   for (ind = 1; ind <= aLen; ind++) {
177     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theShapes->Value(ind));
178     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
179     if (aRefSh.IsNull()) {
180       SetErrorCode("NULL shape for Partition");
181       return NULL;
182     }
183     aShapesSeq->Append(aRefSh);
184
185     // For Python command
186     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
187     if (ind > 1) aShapesDescr += ", ";
188     aShapesDescr += anEntry;
189   }
190   aCI.SetShapes(aShapesSeq);
191
192   // Tools
193   aLen = theTools->Length();
194   for (ind = 1; ind <= aLen; ind++) {
195     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theTools->Value(ind));
196     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
197     if (aRefSh.IsNull()) {
198       SetErrorCode("NULL tool shape for Partition");
199       return NULL;
200     }
201     aToolsSeq->Append(aRefSh);
202
203     // For Python command
204     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
205     if (ind > 1) aToolsDescr += ", ";
206     aToolsDescr += anEntry;
207   }
208   aCI.SetTools(aToolsSeq);
209
210   // Keep Inside
211   aLen = theKeepIns->Length();
212   for (ind = 1; ind <= aLen; ind++) {
213     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theKeepIns->Value(ind));
214     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
215     if (aRefSh.IsNull()) {
216       SetErrorCode("NULL <keep inside> shape for Partition");
217       return NULL;
218     }
219     aKeepInsSeq->Append(aRefSh);
220
221     // For Python command
222     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
223     if (ind > 1) aKeepInsDescr += ", ";
224     aKeepInsDescr += anEntry;
225   }
226   aCI.SetKeepIns(aKeepInsSeq);
227
228   // Remove Inside
229   aLen = theRemoveIns->Length();
230   for (ind = 1; ind <= aLen; ind++) {
231     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theRemoveIns->Value(ind));
232     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
233     if (aRefSh.IsNull()) {
234       SetErrorCode("NULL <remove inside> shape for Partition");
235       return NULL;
236     }
237     aRemInsSeq->Append(aRefSh);
238
239     // For Python command
240     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
241     if (ind > 1) aRemoveInsDescr += ", ";
242     aRemoveInsDescr += anEntry;
243   }
244   aCI.SetRemoveIns(aRemInsSeq);
245
246   // Limit
247   aCI.SetLimit(theLimit);
248
249   // Materials
250   if (theRemoveWebs) {
251     if (theMaterials.IsNull()) {
252       Handle(TColStd_HArray1OfInteger) aMaterials =
253         new TColStd_HArray1OfInteger (1, aShapesSeq->Length());
254       aCI.SetMaterials(aMaterials);
255     } else {
256       aCI.SetMaterials(theMaterials);
257     }
258   }
259
260   //Compute the Partition
261   try {
262     if (!GetSolver()->ComputeFunction(aFunction)) {
263       SetErrorCode("Partition driver failed");
264       return NULL;
265     }
266   }
267   catch (Standard_Failure) {
268     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
269     SetErrorCode(aFail->GetMessageString());
270     return NULL;
271   }
272
273   //Make a Python command 
274   GEOM::TPythonDump pd (aFunction);
275   pd << aPartition << " = geompy.MakePartition([";
276   // Shapes, Tools
277   pd << aShapesDescr.ToCString() << "], [" << aToolsDescr.ToCString() << "], [";
278   // Keep Ins, Remove Ins
279   pd << aKeepInsDescr.ToCString() << "], [" << aRemoveInsDescr.ToCString() << "], ";
280   // Limit, Remove Webs
281   pd << theLimit << ", " << (int)theRemoveWebs << ", [";
282   // Materials
283   if (theMaterials->Length() > 0) {
284     int i = theMaterials->Lower();
285     pd << theMaterials->Value(i);
286     i++;
287     for (; i <= theMaterials->Upper(); i++) {
288       pd << ", " << theMaterials->Value(i);
289     }
290   }
291   pd << "])";
292
293   SetErrorCode(OK);
294   return aPartition; 
295 }
296
297 //=============================================================================
298 /*!
299  *  MakeHalfPartition
300  */
301 //=============================================================================
302 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeHalfPartition
303        (Handle(GEOM_Object) theShape, Handle(GEOM_Object) thePlane)
304 {
305   SetErrorCode(KO);
306
307   if (theShape.IsNull() || thePlane.IsNull()) return NULL;
308  
309   //Add a new Boolean object  
310   Handle(GEOM_Object) aPart = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
311  
312   //Add a new Partition function
313   Handle(GEOM_Function) aFunction =
314     aPart->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_HALF);
315   if (aFunction.IsNull()) return NULL;
316
317   //Check if the function is set correctly
318   if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL; 
319
320   GEOMImpl_IPartition aCI (aFunction);
321   
322   Handle(GEOM_Function) aRef1 = theShape->GetLastFunction();
323   Handle(GEOM_Function) aRef2 = thePlane->GetLastFunction();
324
325   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
326
327   aCI.SetShape(aRef1);
328   aCI.SetPlane(aRef2);
329
330   //Compute the Partition value
331   try {
332     if (!GetSolver()->ComputeFunction(aFunction)) {
333       SetErrorCode("Partition driver failed");
334       return NULL;
335     }
336   }
337   catch (Standard_Failure) {
338     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
339     SetErrorCode(aFail->GetMessageString());
340     return NULL;
341   }
342
343   //Make a Python command 
344   GEOM::TPythonDump(aFunction) << aPart << " = geompy.MakeHalfPartition("
345                                << theShape << ", " << thePlane << ")";
346
347   SetErrorCode(OK);
348   return aPart; 
349 }