]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx
Salome HOME
Fix bug 13058: 'Remove webs' functionality works incorrectly.
[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       aMaterials->Init(0);
255       aCI.SetMaterials(aMaterials);
256     } else {
257       aCI.SetMaterials(theMaterials);
258     }
259   }
260
261   //Compute the Partition
262   try {
263     if (!GetSolver()->ComputeFunction(aFunction)) {
264       SetErrorCode("Partition driver failed");
265       return NULL;
266     }
267   }
268   catch (Standard_Failure) {
269     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
270     SetErrorCode(aFail->GetMessageString());
271     return NULL;
272   }
273
274   //Make a Python command 
275   GEOM::TPythonDump pd (aFunction);
276   pd << aPartition << " = geompy.MakePartition([";
277   // Shapes, Tools
278   pd << aShapesDescr.ToCString() << "], [" << aToolsDescr.ToCString() << "], [";
279   // Keep Ins, Remove Ins
280   pd << aKeepInsDescr.ToCString() << "], [" << aRemoveInsDescr.ToCString() << "], ";
281   // Limit, Remove Webs
282   pd << theLimit << ", " << (int)theRemoveWebs << ", [";
283   // Materials
284   if (!theMaterials.IsNull() && theMaterials->Length() > 0) {
285     int i = theMaterials->Lower();
286     pd << theMaterials->Value(i);
287     i++;
288     for (; i <= theMaterials->Upper(); i++) {
289       pd << ", " << theMaterials->Value(i);
290     }
291   }
292   pd << "])";
293
294   SetErrorCode(OK);
295   return aPartition; 
296 }
297
298 //=============================================================================
299 /*!
300  *  MakeHalfPartition
301  */
302 //=============================================================================
303 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeHalfPartition
304        (Handle(GEOM_Object) theShape, Handle(GEOM_Object) thePlane)
305 {
306   SetErrorCode(KO);
307
308   if (theShape.IsNull() || thePlane.IsNull()) return NULL;
309  
310   //Add a new Boolean object  
311   Handle(GEOM_Object) aPart = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
312  
313   //Add a new Partition function
314   Handle(GEOM_Function) aFunction =
315     aPart->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_HALF);
316   if (aFunction.IsNull()) return NULL;
317
318   //Check if the function is set correctly
319   if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL; 
320
321   GEOMImpl_IPartition aCI (aFunction);
322   
323   Handle(GEOM_Function) aRef1 = theShape->GetLastFunction();
324   Handle(GEOM_Function) aRef2 = thePlane->GetLastFunction();
325
326   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
327
328   aCI.SetShape(aRef1);
329   aCI.SetPlane(aRef2);
330
331   //Compute the Partition value
332   try {
333     if (!GetSolver()->ComputeFunction(aFunction)) {
334       SetErrorCode("Partition driver failed");
335       return NULL;
336     }
337   }
338   catch (Standard_Failure) {
339     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
340     SetErrorCode(aFail->GetMessageString());
341     return NULL;
342   }
343
344   //Make a Python command 
345   GEOM::TPythonDump(aFunction) << aPart << " = geompy.MakeHalfPartition("
346                                << theShape << ", " << thePlane << ")";
347
348   SetErrorCode(OK);
349   return aPart; 
350 }