]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx
Salome HOME
a503e4c0931443aa7b0ffe3319c3fa5fff4fe997
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IBooleanOperations.cxx
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
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                               const Standard_Boolean IsCheckSelfInte)
376 {
377   SetErrorCode(KO);
378
379   //Add a new Partition object
380   Handle(GEOM_Object) aPartition = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
381
382   //Add a new Partition function
383   Handle(GEOM_Function) aFunction;
384   if (thePerformSelfIntersections)
385     aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_PARTITION);
386   else
387     aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_NO_SELF_INTERSECTIONS);
388   if (aFunction.IsNull()) return NULL;
389
390   //Check if the function is set correctly
391   if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
392
393   GEOMImpl_IPartition aCI (aFunction);
394
395   Handle(TColStd_HSequenceOfTransient) aShapesSeq;
396   Handle(TColStd_HSequenceOfTransient) aToolsSeq;
397   Handle(TColStd_HSequenceOfTransient) aKeepInsSeq;
398   Handle(TColStd_HSequenceOfTransient) aRemInsSeq;
399   TCollection_AsciiString aShapesDescr, aToolsDescr, aKeepInsDescr, aRemoveInsDescr;
400
401   // Shapes
402   aShapesSeq = getShapeFunctions(theShapes, aShapesDescr);
403
404   if (aShapesSeq.IsNull()) {
405     SetErrorCode("NULL shape for Partition");
406     return NULL;
407   }
408
409   // Tools
410   aToolsSeq = getShapeFunctions(theTools, aToolsDescr);
411
412   if (aToolsSeq.IsNull()) {
413     SetErrorCode("NULL tool shape for Partition");
414     return NULL;
415   }
416
417   // Keep Inside
418   aKeepInsSeq = getShapeFunctions(theKeepIns, aKeepInsDescr);
419
420   if (aKeepInsSeq.IsNull()) {
421     SetErrorCode("NULL <keep inside> shape for Partition");
422     return NULL;
423   }
424
425   // Remove Inside
426   aRemInsSeq  = getShapeFunctions(theRemoveIns, aRemoveInsDescr);
427
428   if (aRemInsSeq.IsNull()) {
429     SetErrorCode("NULL <remove inside> shape for Partition");
430     return NULL;
431   }
432
433   aCI.SetShapes(aShapesSeq);
434   aCI.SetTools(aToolsSeq);
435   aCI.SetKeepIns(aKeepInsSeq);
436   aCI.SetRemoveIns(aRemInsSeq);
437
438   // Limit
439   aCI.SetLimit(theLimit);
440   aCI.SetKeepNonlimitShapes(theKeepNonlimitShapes);
441   aCI.SetCheckSelfIntersection(IsCheckSelfInte);
442
443   // Materials
444   if (theRemoveWebs) {
445     if (theMaterials.IsNull()) {
446       Handle(TColStd_HArray1OfInteger) aMaterials =
447         new TColStd_HArray1OfInteger (1, aShapesSeq->Length());
448       aMaterials->Init(0);
449       aCI.SetMaterials(aMaterials);
450     } else {
451       aCI.SetMaterials(theMaterials);
452     }
453   }
454
455   //Compute the Partition
456   try {
457 #if OCC_VERSION_LARGE > 0x06010000
458     OCC_CATCH_SIGNALS;
459 #endif
460     if (!GetSolver()->ComputeFunction(aFunction)) {
461       SetErrorCode("Partition driver failed");
462       return NULL;
463     }
464   }
465   catch (Standard_Failure) {
466     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
467     SetErrorCode(aFail->GetMessageString());
468     return NULL;
469   }
470
471   //Make a Python command
472   GEOM::TPythonDump pd (aFunction);
473   if (thePerformSelfIntersections)
474     pd << aPartition << " = geompy.MakePartition([";
475   else
476     pd << aPartition << " = geompy.MakePartitionNonSelfIntersectedShape([";
477
478   // Shapes, Tools
479   pd << aShapesDescr.ToCString() << "], [" << aToolsDescr.ToCString() << "], [";
480   // Keep Ins, Remove Ins
481   pd << aKeepInsDescr.ToCString() << "], [" << aRemoveInsDescr.ToCString() << "], ";
482   // Limit, Remove Webs
483   pd << TopAbs_ShapeEnum(theLimit) << ", " << (int)theRemoveWebs << ", [";
484   // Materials
485   if (!theMaterials.IsNull() && theMaterials->Length() > 0) {
486     int i = theMaterials->Lower();
487     pd << theMaterials->Value(i);
488     i++;
489     for (; i <= theMaterials->Upper(); i++) {
490       pd << ", " << theMaterials->Value(i);
491     }
492   }
493   pd << "], " << theKeepNonlimitShapes;
494
495   if (IsCheckSelfInte && !thePerformSelfIntersections) {
496     pd << ", True";
497   }
498
499   pd << ")";
500
501   SetErrorCode(OK);
502   return aPartition;
503 }
504
505 //=============================================================================
506 /*!
507  *  MakeHalfPartition
508  */
509 //=============================================================================
510 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeHalfPartition
511        (Handle(GEOM_Object) theShape, Handle(GEOM_Object) thePlane)
512 {
513   SetErrorCode(KO);
514
515   if (theShape.IsNull() || thePlane.IsNull()) return NULL;
516
517   //Add a new Boolean object
518   Handle(GEOM_Object) aPart = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
519
520   //Add a new Partition function
521   Handle(GEOM_Function) aFunction =
522     aPart->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_HALF);
523   if (aFunction.IsNull()) return NULL;
524
525   //Check if the function is set correctly
526   if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
527
528   GEOMImpl_IPartition aCI (aFunction);
529
530   Handle(GEOM_Function) aRef1 = theShape->GetLastFunction();
531   Handle(GEOM_Function) aRef2 = thePlane->GetLastFunction();
532
533   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
534
535   aCI.SetShape(aRef1);
536   aCI.SetPlane(aRef2);
537
538   //Compute the Partition value
539   try {
540 #if OCC_VERSION_LARGE > 0x06010000
541     OCC_CATCH_SIGNALS;
542 #endif
543     if (!GetSolver()->ComputeFunction(aFunction)) {
544       SetErrorCode("Partition driver failed");
545       return NULL;
546     }
547   }
548   catch (Standard_Failure) {
549     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
550     SetErrorCode(aFail->GetMessageString());
551     return NULL;
552   }
553
554   //Make a Python command
555   GEOM::TPythonDump pd (aFunction);
556   pd << aPart << " = geompy.MakeHalfPartition("
557      << theShape << ", " << thePlane << ")";
558
559   SetErrorCode(OK);
560   return aPart;
561 }
562
563 //=============================================================================
564 /*!
565  *  getShapeFunctions
566  */
567 //=============================================================================
568 Handle(TColStd_HSequenceOfTransient)
569   GEOMImpl_IBooleanOperations::getShapeFunctions
570                   (const Handle(TColStd_HSequenceOfTransient)& theObjects,
571                          TCollection_AsciiString &theDescription)
572 {
573   Handle(TColStd_HSequenceOfTransient) aResult =
574     new TColStd_HSequenceOfTransient;
575   Standard_Integer aNbObjects = theObjects->Length();
576   Standard_Integer i;
577   TCollection_AsciiString anEntry;
578   Handle(GEOM_Object) anObj;
579   Handle(GEOM_Function) aRefObj;
580
581   // Shapes
582   for (i = 1; i <= aNbObjects; i++) {
583     anObj = Handle(GEOM_Object)::DownCast(theObjects->Value(i));
584     aRefObj = anObj->GetLastFunction();
585
586     if (aRefObj.IsNull()) {
587       aResult.Nullify();
588       break;
589     }
590
591     aResult->Append(aRefObj);
592
593     // For Python command
594     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
595
596     if (i > 1) {
597       theDescription += ", ";
598     }
599
600     theDescription += anEntry;
601   }
602
603   return aResult;
604 }