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