Salome HOME
Bug 0020233: Infinite loop in boolean operation with a sphere with r=0
[modules/geom.git] / src / GEOM_I / GEOM_IBooleanOperations_i.cc
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 #include <Standard_Stream.hxx>
23
24 #include "GEOM_IBooleanOperations_i.hh"
25
26 #include "utilities.h"
27 #include "OpUtil.hxx"
28
29 #include "GEOM_Engine.hxx"
30 #include "GEOM_Object.hxx"
31
32 #include <TColStd_HArray1OfInteger.hxx>
33
34 //=============================================================================
35 /*!
36  *   constructor:
37  */
38 //=============================================================================
39 GEOM_IBooleanOperations_i::GEOM_IBooleanOperations_i (PortableServer::POA_ptr thePOA,
40                                                       GEOM::GEOM_Gen_ptr theEngine,
41                                                       ::GEOMImpl_IBooleanOperations* theImpl)
42 :GEOM_IOperations_i(thePOA, theEngine, theImpl)
43 {
44   MESSAGE("GEOM_IBooleanOperations_i::GEOM_IBooleanOperations_i");
45 }
46
47 //=============================================================================
48 /*!
49  *  destructor
50  */
51 //=============================================================================
52 GEOM_IBooleanOperations_i::~GEOM_IBooleanOperations_i()
53 {
54   MESSAGE("GEOM_IBooleanOperations_i::~GEOM_IBooleanOperations_i");
55 }
56
57
58 //=============================================================================
59 /*!
60  *  MakeBoolean
61  */
62 //=============================================================================
63 GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeBoolean
64                                                  (GEOM::GEOM_Object_ptr theShape1,
65                                                   GEOM::GEOM_Object_ptr theShape2,
66                                                   CORBA::Long           theOp)
67 {
68   GEOM::GEOM_Object_var aGEOMObject;
69
70   //Set a not done flag
71   GetOperations()->SetNotDone();
72
73   if (theShape1 == NULL || theShape2 == NULL) return aGEOMObject._retn();
74
75   //Get the reference shapes
76   CORBA::String_var entry=theShape1->GetEntry();
77   Handle(GEOM_Object) aSh1 = GetOperations()->GetEngine()->GetObject
78     (theShape1->GetStudyID(), entry);
79   entry=theShape2->GetEntry();
80   Handle(GEOM_Object) aSh2 = GetOperations()->GetEngine()->GetObject
81     (theShape2->GetStudyID(), entry);
82
83   if (aSh1.IsNull() || aSh2.IsNull()) return aGEOMObject._retn();
84
85   // Make Boolean
86   Handle(GEOM_Object) anObject = GetOperations()->MakeBoolean(aSh1, aSh2, theOp);
87   if (!GetOperations()->IsDone() || anObject.IsNull())
88     return aGEOMObject._retn();
89
90   return GetObject(anObject);
91 }
92
93 //=============================================================================
94 /*!
95  *  MakePartition
96  */
97 //=============================================================================
98 GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakePartition
99                                       (const GEOM::ListOfGO&   theShapes,
100                                        const GEOM::ListOfGO&   theTools,
101                                        const GEOM::ListOfGO&   theKeepIns,
102                                        const GEOM::ListOfGO&   theRemoveIns,
103                                        CORBA::Short            theLimit,
104                                        CORBA::Boolean          theRemoveWebs,
105                                        const GEOM::ListOfLong& theMaterials,
106                                        CORBA::Short theKeepNonlimitShapes)
107 {
108   GEOM::GEOM_Object_var aGEOMObject;
109
110   //Set a not done flag
111   GetOperations()->SetNotDone();
112
113   int ind, aLen;
114   Handle(TColStd_HSequenceOfTransient) aShapes  = new TColStd_HSequenceOfTransient;
115   Handle(TColStd_HSequenceOfTransient) aTools   = new TColStd_HSequenceOfTransient;
116   Handle(TColStd_HSequenceOfTransient) aKeepIns = new TColStd_HSequenceOfTransient;
117   Handle(TColStd_HSequenceOfTransient) aRemIns  = new TColStd_HSequenceOfTransient;
118   Handle(TColStd_HArray1OfInteger) aMaterials;
119
120   //Get the shapes
121   aLen = theShapes.length();
122   for (ind = 0; ind < aLen; ind++) {
123     if (theShapes[ind] == NULL) return aGEOMObject._retn();
124     Handle(GEOM_Object) aSh = GetOperations()->GetEngine()->GetObject
125       (theShapes[ind]->GetStudyID(), theShapes[ind]->GetEntry());
126     if (aSh.IsNull()) return aGEOMObject._retn();
127     aShapes->Append(aSh);
128   }
129
130   //Get the tools
131   aLen = theTools.length();
132   for (ind = 0; ind < aLen; ind++) {
133     if (theTools[ind] == NULL) return aGEOMObject._retn();
134     Handle(GEOM_Object) aSh = GetOperations()->GetEngine()->GetObject
135       (theTools[ind]->GetStudyID(), theTools[ind]->GetEntry());
136     if (aSh.IsNull()) return aGEOMObject._retn();
137     aTools->Append(aSh);
138   }
139
140   //Get the keep inside shapes
141   aLen = theKeepIns.length();
142   for (ind = 0; ind < aLen; ind++) {
143     if (theKeepIns[ind] == NULL) return aGEOMObject._retn();
144     Handle(GEOM_Object) aSh = GetOperations()->GetEngine()->GetObject
145       (theKeepIns[ind]->GetStudyID(), theKeepIns[ind]->GetEntry());
146     if (aSh.IsNull()) return aGEOMObject._retn();
147     aKeepIns->Append(aSh);
148   }
149
150   //Get the remove inside shapes
151   aLen = theRemoveIns.length();
152   for (ind = 0; ind < aLen; ind++) {
153     if (theRemoveIns[ind] == NULL) return aGEOMObject._retn();
154     Handle(GEOM_Object) aSh = GetOperations()->GetEngine()->GetObject
155       (theRemoveIns[ind]->GetStudyID(), theRemoveIns[ind]->GetEntry());
156     if (aSh.IsNull()) return aGEOMObject._retn();
157     aRemIns->Append(aSh);
158   }
159
160   //Get the materials
161   aLen = theMaterials.length();
162   if ( aLen ) {
163     aMaterials = new TColStd_HArray1OfInteger (1, aLen);
164     for (ind = 0; ind < aLen; ind++) {
165       aMaterials->SetValue(ind+1, theMaterials[ind]);
166     }
167   }
168
169   // Make Partition
170   Handle(GEOM_Object) anObject =
171     GetOperations()->MakePartition(aShapes, aTools, aKeepIns, aRemIns,
172                                    theLimit, theRemoveWebs, aMaterials,
173                                    theKeepNonlimitShapes,
174                                    /*PerformSelfIntersections*/Standard_True);
175   if (!GetOperations()->IsDone() || anObject.IsNull())
176     return aGEOMObject._retn();
177
178   return GetObject(anObject);
179 }
180
181 //=============================================================================
182 /*!
183  *  MakePartitionNonSelfIntersectedShape
184  */
185 //=============================================================================
186 GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakePartitionNonSelfIntersectedShape
187                                       (const GEOM::ListOfGO&   theShapes,
188                                        const GEOM::ListOfGO&   theTools,
189                                        const GEOM::ListOfGO&   theKeepIns,
190                                        const GEOM::ListOfGO&   theRemoveIns,
191                                        CORBA::Short            theLimit,
192                                        CORBA::Boolean          theRemoveWebs,
193                                        const GEOM::ListOfLong& theMaterials,
194                                        CORBA::Short theKeepNonlimitShapes)
195 {
196   GEOM::GEOM_Object_var aGEOMObject;
197
198   //Set a not done flag
199   GetOperations()->SetNotDone();
200
201   int ind, aLen;
202   Handle(TColStd_HSequenceOfTransient) aShapes  = new TColStd_HSequenceOfTransient;
203   Handle(TColStd_HSequenceOfTransient) aTools   = new TColStd_HSequenceOfTransient;
204   Handle(TColStd_HSequenceOfTransient) aKeepIns = new TColStd_HSequenceOfTransient;
205   Handle(TColStd_HSequenceOfTransient) aRemIns  = new TColStd_HSequenceOfTransient;
206   Handle(TColStd_HArray1OfInteger) aMaterials;
207
208   //Get the shapes
209   aLen = theShapes.length();
210   for (ind = 0; ind < aLen; ind++) {
211     if (theShapes[ind] == NULL) return aGEOMObject._retn();
212     Handle(GEOM_Object) aSh = GetOperations()->GetEngine()->GetObject
213       (theShapes[ind]->GetStudyID(), theShapes[ind]->GetEntry());
214     if (aSh.IsNull()) return aGEOMObject._retn();
215     aShapes->Append(aSh);
216   }
217
218   //Get the tools
219   aLen = theTools.length();
220   for (ind = 0; ind < aLen; ind++) {
221     if (theTools[ind] == NULL) return aGEOMObject._retn();
222     Handle(GEOM_Object) aSh = GetOperations()->GetEngine()->GetObject
223       (theTools[ind]->GetStudyID(), theTools[ind]->GetEntry());
224     if (aSh.IsNull()) return aGEOMObject._retn();
225     aTools->Append(aSh);
226   }
227
228   //Get the keep inside shapes
229   aLen = theKeepIns.length();
230   for (ind = 0; ind < aLen; ind++) {
231     if (theKeepIns[ind] == NULL) return aGEOMObject._retn();
232     Handle(GEOM_Object) aSh = GetOperations()->GetEngine()->GetObject
233       (theKeepIns[ind]->GetStudyID(), theKeepIns[ind]->GetEntry());
234     if (aSh.IsNull()) return aGEOMObject._retn();
235     aKeepIns->Append(aSh);
236   }
237
238   //Get the remove inside shapes
239   aLen = theRemoveIns.length();
240   for (ind = 0; ind < aLen; ind++) {
241     if (theRemoveIns[ind] == NULL) return aGEOMObject._retn();
242     Handle(GEOM_Object) aSh = GetOperations()->GetEngine()->GetObject
243       (theRemoveIns[ind]->GetStudyID(), theRemoveIns[ind]->GetEntry());
244     if (aSh.IsNull()) return aGEOMObject._retn();
245     aRemIns->Append(aSh);
246   }
247
248   //Get the materials
249   aLen = theMaterials.length();
250   if ( aLen ) {
251     aMaterials = new TColStd_HArray1OfInteger (1, aLen);
252     for (ind = 0; ind < aLen; ind++) {
253       aMaterials->SetValue(ind+1, theMaterials[ind]);
254     }
255   }
256
257   // Make Partition
258   Handle(GEOM_Object) anObject =
259     GetOperations()->MakePartition(aShapes, aTools, aKeepIns, aRemIns,
260                                    theLimit, theRemoveWebs, aMaterials,
261                                    theKeepNonlimitShapes,
262                                    /*PerformSelfIntersections*/Standard_False);
263   if (!GetOperations()->IsDone() || anObject.IsNull())
264     return aGEOMObject._retn();
265
266   return GetObject(anObject);
267 }
268
269 //=============================================================================
270 /*!
271  *  MakeHalfPartition
272  */
273 //=============================================================================
274 GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeHalfPartition
275                                                  (GEOM::GEOM_Object_ptr theShape,
276                                                   GEOM::GEOM_Object_ptr thePlane)
277 {
278   GEOM::GEOM_Object_var aGEOMObject;
279
280   //Set a not done flag
281   GetOperations()->SetNotDone();
282
283   if (theShape == NULL || thePlane == NULL) return aGEOMObject._retn();
284
285   //Get the reference shapes
286   Handle(GEOM_Object) aSh = GetOperations()->GetEngine()->GetObject
287     (theShape->GetStudyID(), theShape->GetEntry());
288   Handle(GEOM_Object) aPl = GetOperations()->GetEngine()->GetObject
289     (thePlane->GetStudyID(), thePlane->GetEntry());
290
291   if (aSh.IsNull() || aPl.IsNull()) return aGEOMObject._retn();
292
293   // Make Half Partition
294   Handle(GEOM_Object) anObject = GetOperations()->MakeHalfPartition(aSh, aPl);
295   if (!GetOperations()->IsDone() || anObject.IsNull())
296     return aGEOMObject._retn();
297
298   return GetObject(anObject);
299 }