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