]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx
Salome HOME
Add of exports
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IBooleanOperations.cxx
1 // Copyright (C) 2007-2013  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
23 #include <Standard_Stream.hxx>
24
25 #include <GEOMImpl_IBooleanOperations.hxx>
26
27 #include <GEOM_Function.hxx>
28 #include <GEOM_PythonDump.hxx>
29
30 #include <GEOMImpl_Types.hxx>
31
32 #include <GEOMImpl_BooleanDriver.hxx>
33 #include <GEOMImpl_IBoolean.hxx>
34
35 #include <GEOMImpl_PartitionDriver.hxx>
36 #include <GEOMImpl_IPartition.hxx>
37
38 #include <Basics_OCCTVersion.hxx>
39
40 #include <TDF_Tool.hxx>
41
42 #include "utilities.h"
43
44 #include <Standard_Failure.hxx>
45 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
46
47 //=============================================================================
48 /*!
49  *   constructor:
50  */
51 //=============================================================================
52 GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations (GEOM_Engine* theEngine, int theDocID)
53 : GEOM_IOperations(theEngine, theDocID)
54 {
55   MESSAGE("GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations");
56 }
57
58 //=============================================================================
59 /*!
60  *  destructor
61  */
62 //=============================================================================
63 GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations()
64 {
65   MESSAGE("GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations");
66 }
67
68
69 //=============================================================================
70 /*!
71  *  MakeBoolean
72  */
73 //=============================================================================
74 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeBoolean
75                                   (Handle(GEOM_Object)    theShape1,
76                                    Handle(GEOM_Object)    theShape2,
77                                    const Standard_Integer theOp,
78                                    const Standard_Boolean IsCheckSelfInte)
79 {
80   SetErrorCode(KO);
81
82   if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
83
84   //Add a new Boolean object
85   Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
86
87   //Add a new Boolean function
88   Handle(GEOM_Function) aFunction;
89   if (theOp == 1) {
90     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_COMMON);
91   } else if (theOp == 2) {
92     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_CUT);
93   } else if (theOp == 3) {
94     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_FUSE);
95   } else if (theOp == 4) {
96     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_SECTION);
97   } else {
98   }
99   if (aFunction.IsNull()) return NULL;
100
101   //Check if the function is set correctly
102   if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
103
104   GEOMImpl_IBoolean aCI (aFunction);
105
106   Handle(GEOM_Function) aRef1 = theShape1->GetLastFunction();
107   Handle(GEOM_Function) aRef2 = theShape2->GetLastFunction();
108
109   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
110
111   aCI.SetShape1(aRef1);
112   aCI.SetShape2(aRef2);
113   aCI.SetCheckSelfIntersection(IsCheckSelfInte);
114
115   //Compute the Boolean value
116   try {
117 #if OCC_VERSION_LARGE > 0x06010000
118     OCC_CATCH_SIGNALS;
119 #endif
120     if (!GetSolver()->ComputeFunction(aFunction)) {
121       SetErrorCode("Boolean driver failed");
122       return NULL;
123     }
124   }
125   catch (Standard_Failure) {
126     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
127     SetErrorCode(aFail->GetMessageString());
128     return NULL;
129   }
130
131   //Make a Python command
132   GEOM::TPythonDump pd (aFunction);
133   pd << aBool;
134   if      (theOp == 1) pd << " = geompy.MakeCommon(";
135   else if (theOp == 2) pd << " = geompy.MakeCut(";
136   else if (theOp == 3) pd << " = geompy.MakeFuse(";
137   else if (theOp == 4) pd << " = geompy.MakeSection(";
138   else {}
139   pd << theShape1 << ", " << theShape2;
140
141   if (IsCheckSelfInte) {
142     pd << ", True";
143   }
144
145   pd << ")";
146
147   SetErrorCode(OK);
148   return aBool;
149 }
150
151 //=============================================================================
152 /*!
153  *  MakeFuseList
154  */
155 //=============================================================================
156 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeFuseList
157                   (const Handle(TColStd_HSequenceOfTransient)& theShapes,
158                    const Standard_Boolean IsCheckSelfInte)
159 {
160   SetErrorCode(KO);
161
162   if (theShapes.IsNull()) return NULL;
163
164   //Add a new Boolean object
165   Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
166
167   //Add a new Boolean function
168   Handle(GEOM_Function) aFunction =
169     aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_FUSE_LIST);
170
171   if (aFunction.IsNull()) return NULL;
172
173   //Check if the function is set correctly
174   if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
175
176   GEOMImpl_IBoolean aCI (aFunction);
177
178   TCollection_AsciiString aDescription;
179   Handle(TColStd_HSequenceOfTransient) aShapesSeq =
180     getShapeFunctions(theShapes, aDescription);
181
182   if (aShapesSeq.IsNull()) return NULL;
183
184   aCI.SetShapes(aShapesSeq);
185   aCI.SetCheckSelfIntersection(IsCheckSelfInte);
186
187   //Compute the Boolean value
188   try {
189 #if OCC_VERSION_LARGE > 0x06010000
190     OCC_CATCH_SIGNALS;
191 #endif
192     if (!GetSolver()->ComputeFunction(aFunction)) {
193       SetErrorCode("Boolean driver failed");
194       return NULL;
195     }
196   }
197   catch (Standard_Failure) {
198     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
199     SetErrorCode(aFail->GetMessageString());
200     return NULL;
201   }
202
203   //Make a Python command
204   GEOM::TPythonDump pd (aFunction);
205
206   pd << aBool <<
207     " = geompy.MakeFuseList([" << aDescription.ToCString() << "]";
208
209   if (IsCheckSelfInte) {
210     pd << ", True";
211   }
212
213   pd << ")";
214
215   SetErrorCode(OK);
216   return aBool;
217 }
218
219 //=============================================================================
220 /*!
221  *  MakeCommonList
222  */
223 //=============================================================================
224 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeCommonList
225                   (const Handle(TColStd_HSequenceOfTransient)& theShapes,
226                    const Standard_Boolean IsCheckSelfInte)
227 {
228   SetErrorCode(KO);
229
230   if (theShapes.IsNull()) return NULL;
231
232   //Add a new Boolean object
233   Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
234
235   //Add a new Boolean function
236   Handle(GEOM_Function) aFunction =
237     aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_COMMON_LIST);
238
239   if (aFunction.IsNull()) return NULL;
240
241   //Check if the function is set correctly
242   if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
243
244   GEOMImpl_IBoolean aCI (aFunction);
245
246   TCollection_AsciiString aDescription;
247   Handle(TColStd_HSequenceOfTransient) aShapesSeq =
248     getShapeFunctions(theShapes, aDescription);
249
250   if (aShapesSeq.IsNull()) return NULL;
251
252   aCI.SetShapes(aShapesSeq);
253   aCI.SetCheckSelfIntersection(IsCheckSelfInte);
254
255   //Compute the Boolean value
256   try {
257 #if OCC_VERSION_LARGE > 0x06010000
258     OCC_CATCH_SIGNALS;
259 #endif
260     if (!GetSolver()->ComputeFunction(aFunction)) {
261       SetErrorCode("Boolean driver failed");
262       return NULL;
263     }
264   }
265   catch (Standard_Failure) {
266     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
267     SetErrorCode(aFail->GetMessageString());
268     return NULL;
269   }
270
271   //Make a Python command
272   GEOM::TPythonDump pd (aFunction);
273
274   pd << aBool <<
275     " = geompy.MakeCommonList([" << aDescription.ToCString() << "]";
276
277   if (IsCheckSelfInte) {
278     pd << ", True";
279   }
280
281   pd << ")";
282
283   SetErrorCode(OK);
284   return aBool;
285 }
286
287 //=============================================================================
288 /*!
289  *  MakeCutList
290  */
291 //=============================================================================
292 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeCutList
293                   (Handle(GEOM_Object) theMainShape,
294                    const Handle(TColStd_HSequenceOfTransient)& theShapes,
295                    const Standard_Boolean IsCheckSelfInte)
296 {
297   SetErrorCode(KO);
298
299   if (theShapes.IsNull()) return NULL;
300
301   //Add a new Boolean object
302   Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
303
304   //Add a new Boolean function
305   Handle(GEOM_Function) aFunction =
306     aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_CUT_LIST);
307
308   if (aFunction.IsNull()) return NULL;
309
310   //Check if the function is set correctly
311   if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
312
313   GEOMImpl_IBoolean aCI (aFunction);
314   Handle(GEOM_Function) aMainRef = theMainShape->GetLastFunction();
315
316   if (aMainRef.IsNull()) return NULL;
317
318   TCollection_AsciiString aDescription;
319   Handle(TColStd_HSequenceOfTransient) aShapesSeq =
320     getShapeFunctions(theShapes, aDescription);
321
322   if (aShapesSeq.IsNull()) return NULL;
323
324   aCI.SetShape1(aMainRef);
325   aCI.SetShapes(aShapesSeq);
326   aCI.SetCheckSelfIntersection(IsCheckSelfInte);
327
328   //Compute the Boolean value
329   try {
330 #if OCC_VERSION_LARGE > 0x06010000
331     OCC_CATCH_SIGNALS;
332 #endif
333     if (!GetSolver()->ComputeFunction(aFunction)) {
334       SetErrorCode("Boolean 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 pd (aFunction);
346
347   pd << aBool << " = geompy.MakeCutList("
348     << theMainShape << ", [" << aDescription.ToCString() << "]";
349
350   if (IsCheckSelfInte) {
351     pd << ", True";
352   }
353
354   pd << ")";
355
356   SetErrorCode(OK);
357   return aBool;
358 }
359
360 //=============================================================================
361 /*!
362  *  MakePartition
363  */
364 //=============================================================================
365 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakePartition
366                              (const Handle(TColStd_HSequenceOfTransient)& theShapes,
367                               const Handle(TColStd_HSequenceOfTransient)& theTools,
368                               const Handle(TColStd_HSequenceOfTransient)& theKeepIns,
369                               const Handle(TColStd_HSequenceOfTransient)& theRemoveIns,
370                               const Standard_Integer                      theLimit,
371                               const Standard_Boolean                      theRemoveWebs,
372                               const Handle(TColStd_HArray1OfInteger)&     theMaterials,
373                               const Standard_Integer theKeepNonlimitShapes,
374                               const Standard_Boolean thePerformSelfIntersections)
375 {
376   SetErrorCode(KO);
377
378   //Add a new Partition object
379   Handle(GEOM_Object) aPartition = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
380
381   //Add a new Partition function
382   Handle(GEOM_Function) aFunction;
383   if (thePerformSelfIntersections)
384     aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_PARTITION);
385   else
386     aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_NO_SELF_INTERSECTIONS);
387   if (aFunction.IsNull()) return NULL;
388
389   //Check if the function is set correctly
390   if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
391
392   GEOMImpl_IPartition aCI (aFunction);
393
394   Handle(TColStd_HSequenceOfTransient) aShapesSeq;
395   Handle(TColStd_HSequenceOfTransient) aToolsSeq;
396   Handle(TColStd_HSequenceOfTransient) aKeepInsSeq;
397   Handle(TColStd_HSequenceOfTransient) aRemInsSeq;
398   TCollection_AsciiString aShapesDescr, aToolsDescr, aKeepInsDescr, aRemoveInsDescr;
399
400   // Shapes
401   aShapesSeq = getShapeFunctions(theShapes, aShapesDescr);
402
403   if (aShapesSeq.IsNull()) {
404     SetErrorCode("NULL shape for Partition");
405     return NULL;
406   }
407
408   // Tools
409   aToolsSeq = getShapeFunctions(theTools, aToolsDescr);
410
411   if (aToolsSeq.IsNull()) {
412     SetErrorCode("NULL tool shape for Partition");
413     return NULL;
414   }
415
416   // Keep Inside
417   aKeepInsSeq = getShapeFunctions(theKeepIns, aKeepInsDescr);
418
419   if (aKeepInsSeq.IsNull()) {
420     SetErrorCode("NULL <keep inside> shape for Partition");
421     return NULL;
422   }
423
424   // Remove Inside
425   aRemInsSeq  = getShapeFunctions(theRemoveIns, aRemoveInsDescr);
426
427   if (aRemInsSeq.IsNull()) {
428     SetErrorCode("NULL <remove inside> shape for Partition");
429     return NULL;
430   }
431
432   aCI.SetShapes(aShapesSeq);
433   aCI.SetTools(aToolsSeq);
434   aCI.SetKeepIns(aKeepInsSeq);
435   aCI.SetRemoveIns(aRemInsSeq);
436
437   // Limit
438   aCI.SetLimit(theLimit);
439   aCI.SetKeepNonlimitShapes(theKeepNonlimitShapes);
440
441   // Materials
442   if (theRemoveWebs) {
443     if (theMaterials.IsNull()) {
444       Handle(TColStd_HArray1OfInteger) aMaterials =
445         new TColStd_HArray1OfInteger (1, aShapesSeq->Length());
446       aMaterials->Init(0);
447       aCI.SetMaterials(aMaterials);
448     } else {
449       aCI.SetMaterials(theMaterials);
450     }
451   }
452
453   //Compute the Partition
454   try {
455 #if OCC_VERSION_LARGE > 0x06010000
456     OCC_CATCH_SIGNALS;
457 #endif
458     if (!GetSolver()->ComputeFunction(aFunction)) {
459       SetErrorCode("Partition driver failed");
460       return NULL;
461     }
462   }
463   catch (Standard_Failure) {
464     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
465     SetErrorCode(aFail->GetMessageString());
466     return NULL;
467   }
468
469   //Make a Python command
470   GEOM::TPythonDump pd (aFunction);
471   if (thePerformSelfIntersections)
472     pd << aPartition << " = geompy.MakePartition([";
473   else
474     pd << aPartition << " = geompy.MakePartitionNonSelfIntersectedShape([";
475
476   // Shapes, Tools
477   pd << aShapesDescr.ToCString() << "], [" << aToolsDescr.ToCString() << "], [";
478   // Keep Ins, Remove Ins
479   pd << aKeepInsDescr.ToCString() << "], [" << aRemoveInsDescr.ToCString() << "], ";
480   // Limit, Remove Webs
481   pd << TopAbs_ShapeEnum(theLimit) << ", " << (int)theRemoveWebs << ", [";
482   // Materials
483   if (!theMaterials.IsNull() && theMaterials->Length() > 0) {
484     int i = theMaterials->Lower();
485     pd << theMaterials->Value(i);
486     i++;
487     for (; i <= theMaterials->Upper(); i++) {
488       pd << ", " << theMaterials->Value(i);
489     }
490   }
491   pd << "], " << theKeepNonlimitShapes <<")";
492
493   SetErrorCode(OK);
494   return aPartition;
495 }
496
497 //=============================================================================
498 /*!
499  *  MakeHalfPartition
500  */
501 //=============================================================================
502 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeHalfPartition
503        (Handle(GEOM_Object) theShape, Handle(GEOM_Object) thePlane)
504 {
505   SetErrorCode(KO);
506
507   if (theShape.IsNull() || thePlane.IsNull()) return NULL;
508
509   //Add a new Boolean object
510   Handle(GEOM_Object) aPart = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
511
512   //Add a new Partition function
513   Handle(GEOM_Function) aFunction =
514     aPart->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_HALF);
515   if (aFunction.IsNull()) return NULL;
516
517   //Check if the function is set correctly
518   if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
519
520   GEOMImpl_IPartition aCI (aFunction);
521
522   Handle(GEOM_Function) aRef1 = theShape->GetLastFunction();
523   Handle(GEOM_Function) aRef2 = thePlane->GetLastFunction();
524
525   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
526
527   aCI.SetShape(aRef1);
528   aCI.SetPlane(aRef2);
529
530   //Compute the Partition value
531   try {
532 #if OCC_VERSION_LARGE > 0x06010000
533     OCC_CATCH_SIGNALS;
534 #endif
535     if (!GetSolver()->ComputeFunction(aFunction)) {
536       SetErrorCode("Partition driver failed");
537       return NULL;
538     }
539   }
540   catch (Standard_Failure) {
541     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
542     SetErrorCode(aFail->GetMessageString());
543     return NULL;
544   }
545
546   //Make a Python command
547   GEOM::TPythonDump(aFunction) << aPart << " = geompy.MakeHalfPartition("
548                                << theShape << ", " << thePlane << ")";
549
550   SetErrorCode(OK);
551   return aPart;
552 }
553
554 //=============================================================================
555 /*!
556  *  getShapeFunctions
557  */
558 //=============================================================================
559 Handle(TColStd_HSequenceOfTransient)
560   GEOMImpl_IBooleanOperations::getShapeFunctions
561                   (const Handle(TColStd_HSequenceOfTransient)& theObjects,
562                          TCollection_AsciiString &theDescription)
563 {
564   Handle(TColStd_HSequenceOfTransient) aResult =
565     new TColStd_HSequenceOfTransient;
566   Standard_Integer aNbObjects = theObjects->Length();
567   Standard_Integer i;
568   TCollection_AsciiString anEntry;
569   Handle(GEOM_Object) anObj;
570   Handle(GEOM_Function) aRefObj;
571
572   // Shapes
573   for (i = 1; i <= aNbObjects; i++) {
574     anObj = Handle(GEOM_Object)::DownCast(theObjects->Value(i));
575     aRefObj = anObj->GetLastFunction();
576
577     if (aRefObj.IsNull()) {
578       aResult.Nullify();
579       break;
580     }
581
582     aResult->Append(aRefObj);
583
584     // For Python command
585     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
586
587     if (i > 1) {
588       theDescription += ", ";
589     }
590
591     theDescription += anEntry;
592   }
593
594   return aResult;
595 }