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