Salome HOME
Migration to OCCT 7.0
[modules/geom.git] / src / GEOMImpl / GEOMImpl_BooleanDriver.cxx
1 // Copyright (C) 2007-2016  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 <GEOMImpl_BooleanDriver.hxx>
24 #include <GEOMImpl_IBoolean.hxx>
25 #include <GEOMImpl_Types.hxx>
26 #include <GEOMImpl_GlueDriver.hxx>
27 #include <GEOM_Function.hxx>
28 #include <GEOMUtils.hxx>
29 #include <BlockFix_BlockFixAPI.hxx>
30 #include <ShHealOper_ShapeProcess.hxx>
31
32 #include <TNaming_CopyShape.hxx>
33
34 #include <BRep_Builder.hxx>
35 #include <BRepAlgoAPI_Common.hxx>
36 #include <BRepAlgoAPI_Cut.hxx>
37 #include <BRepAlgoAPI_Fuse.hxx>
38 #include <BRepAlgoAPI_Section.hxx>
39 #include <BOPAlgo_CheckerSI.hxx>
40 #include <BOPDS_DS.hxx>
41
42 #include <TopExp_Explorer.hxx>
43 #include <TopoDS_Compound.hxx>
44 #include <TopoDS_Iterator.hxx>
45 #include <TopTools_MapOfShape.hxx>
46 #include <TopTools_ListOfShape.hxx>
47 #include <TopTools_ListIteratorOfListOfShape.hxx>
48
49 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
50
51 #include <Precision.hxx>
52
53 #include <Standard_ConstructionError.hxx>
54 #include <StdFail_NotDone.hxx>
55
56 // Depth of self-intersection check (see BOPAlgo_CheckerSI::SetLevelOfCheck() for more details)
57 // Default value for BOPAlgo_CheckerSI gives very long computation when checking face-to-face intersections;
58 // here check level is decreased to more appropriate value to avoid problems with performance).
59 #define BOP_SELF_INTERSECTIONS_LEVEL 4
60
61 /**
62  * This function performs extra edges removal.
63  *
64  * \param theShape the shape to be processed.
65  * \return the modified shape or null shape in case of failure.
66  */
67 static TopoDS_Shape RemoveExtraEdges(const TopoDS_Shape &theShape)
68 {
69   TopoDS_Shape aResult;
70
71   if (!theShape.IsNull()) {
72     BlockFix_BlockFixAPI aTool;
73
74     aTool.OptimumNbFaces() = 0;
75     aTool.SetShape(theShape);
76     aTool.Perform();
77     TopoDS_Shape aShape = aTool.Shape();
78
79     if (GEOMUtils::CheckShape(aShape)) {
80       aResult = aShape;
81     }
82     else {
83       TopoDS_Shape aFixed;
84       ShHealOper_ShapeProcess aHealer;
85       aHealer.Perform(aShape, aFixed);
86       if (aHealer.isDone() && GEOMUtils::CheckShape(aFixed))
87         aResult = aFixed;
88     }
89   }
90
91   return aResult;
92 }
93
94 //=======================================================================
95 //function : GetID
96 //purpose  :
97 //=======================================================================
98 const Standard_GUID& GEOMImpl_BooleanDriver::GetID()
99 {
100   static Standard_GUID aBooleanDriver("FF1BBB21-5D14-4df2-980B-3A668264EA16");
101   return aBooleanDriver;
102 }
103
104 //=======================================================================
105 //function : GEOMImpl_BooleanDriver
106 //purpose  :
107 //=======================================================================
108 GEOMImpl_BooleanDriver::GEOMImpl_BooleanDriver()
109 {
110 }
111
112 //=======================================================================
113 //function : Execute
114 //purpose  :
115 //=======================================================================
116 Standard_Integer GEOMImpl_BooleanDriver::Execute(LOGBOOK& log) const
117 {
118   if (Label().IsNull()) return 0;
119   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
120
121   GEOMImpl_IBoolean aCI (aFunction);
122   Standard_Integer aType = aFunction->GetType();
123   const Standard_Boolean isCheckSelfInte = aCI.GetCheckSelfIntersection();
124   const Standard_Boolean isRmExtraEdges  = aCI.GetRmExtraEdges();
125
126   TopoDS_Shape aShape;
127
128   switch (aType) {
129   case BOOLEAN_COMMON:
130   case BOOLEAN_CUT:
131   case BOOLEAN_FUSE:
132   case BOOLEAN_SECTION:
133     {
134       Handle(GEOM_Function) aRefShape1 = aCI.GetShape1();
135       Handle(GEOM_Function) aRefShape2 = aCI.GetShape2();
136       TopoDS_Shape aShape1 = aRefShape1->GetValue();
137       TopoDS_Shape aShape2 = aRefShape2->GetValue();
138
139       if (!aShape1.IsNull() && !aShape2.IsNull()) {
140         // check arguments for Mantis issue 0021019
141         if (!GEOMUtils::CheckShape(aShape1, true) || !GEOMUtils::CheckShape(aShape2, true))
142           StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
143
144         if (isCheckSelfInte) {
145           BOPAlgo_CheckerSI aCSI;  // checker of self-interferences
146           aCSI.SetLevelOfCheck(BOP_SELF_INTERSECTIONS_LEVEL);
147           BOPCol_ListOfShape aList1, aList2;
148           aList1.Append(aShape1);
149           aList2.Append(aShape2);
150           aCSI.SetArguments(aList1);
151           aCSI.Perform();
152           if (aCSI.ErrorStatus() || aCSI.DS().Interferences().Extent() > 0)
153             StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is self-intersected");
154           aCSI.SetArguments(aList2);
155           aCSI.Perform();
156           if (aCSI.ErrorStatus() || aCSI.DS().Interferences().Extent() > 0)
157             StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is self-intersected");
158         }
159
160         // Make a copy to prevent the original shape changes.
161         TopoDS_Shape aShapeCopy1;
162         TopoDS_Shape aShapeCopy2;
163         TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
164         TNaming_CopyShape::CopyTool(aShape1, aMapTShapes, aShapeCopy1);
165         TNaming_CopyShape::CopyTool(aShape2, aMapTShapes, aShapeCopy2);
166
167         aShape = performOperation (aShapeCopy1, aShapeCopy2, aType);
168
169         if (isRmExtraEdges) {
170           aShape = RemoveExtraEdges(aShape);
171         }
172
173         if (aShape.IsNull()) {
174           return 0;
175         }
176       }
177     }
178     break;
179   case BOOLEAN_COMMON_LIST:
180   case BOOLEAN_FUSE_LIST:
181     {
182       Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
183       const Standard_Integer nbShapes = aShapes->Length();
184       Standard_Integer i;
185       Handle(GEOM_Function) aRefShape;
186       TopoDS_Shape aShape2;
187       Standard_Integer aSimpleType =
188         (aType == BOOLEAN_FUSE_LIST ? BOOLEAN_FUSE : BOOLEAN_COMMON);
189
190       if (nbShapes > 0) {
191         aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(1));
192         aShape = aRefShape->GetValue();
193         
194         if (!aShape.IsNull()) {
195           // check arguments for Mantis issue 0021019
196           if (!GEOMUtils::CheckShape(aShape, true))
197             StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
198
199           BOPAlgo_CheckerSI aCSI;  // checker of self-interferences
200
201           if (isCheckSelfInte) {
202             aCSI.SetLevelOfCheck(BOP_SELF_INTERSECTIONS_LEVEL);
203             BOPCol_ListOfShape aList1;
204             aList1.Append(aShape);
205             aCSI.SetArguments(aList1);
206             aCSI.Perform();
207             if (aCSI.ErrorStatus() || aCSI.DS().Interferences().Extent() > 0) {
208               StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is self-intersected");
209             }
210           }
211
212           // Copy shape
213           TopoDS_Shape aShapeCopy;
214           TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
215
216           TNaming_CopyShape::CopyTool(aShape, aMapTShapes, aShapeCopy);
217           aShape = aShapeCopy;
218
219           for (i = 2; i <= nbShapes; i++) {
220             aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(i));
221             aShape2 = aRefShape->GetValue();
222             
223             if (!GEOMUtils::CheckShape(aShape2, true))
224               StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
225             
226             if (isCheckSelfInte) {
227               BOPCol_ListOfShape aList2;
228               aList2.Append(aShape2);
229               aCSI.SetArguments(aList2);
230               aCSI.Perform();
231               if (aCSI.ErrorStatus() || aCSI.DS().Interferences().Extent() > 0) {
232                 StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is self-intersected");
233               }
234             }
235
236             // Copy shape
237             aShapeCopy.Nullify();
238             TNaming_CopyShape::CopyTool(aShape2, aMapTShapes, aShapeCopy);
239             aShape = performOperation (aShape, aShapeCopy, aSimpleType);
240
241             if (isRmExtraEdges) {
242               aShape = RemoveExtraEdges(aShape);
243             }
244             
245             if (aShape.IsNull()) {
246               return 0;
247             }
248           }
249         }
250       }
251     }
252     break;
253   case BOOLEAN_CUT_LIST:
254     {
255       Handle(GEOM_Function) aRefObject = aCI.GetShape1();
256
257       aShape = aRefObject->GetValue();
258
259       if (!aShape.IsNull()) {
260         // check arguments for Mantis issue 0021019
261         if (!GEOMUtils::CheckShape(aShape, true))
262           StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
263
264         BOPAlgo_CheckerSI aCSI;  // checker of self-interferences
265
266         if (isCheckSelfInte) {
267           aCSI.SetLevelOfCheck(BOP_SELF_INTERSECTIONS_LEVEL);
268           BOPCol_ListOfShape aList1;
269           aList1.Append(aShape);
270           aCSI.SetArguments(aList1);
271           aCSI.Perform();
272           if (aCSI.ErrorStatus() || aCSI.DS().Interferences().Extent() > 0) {
273             StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is self-intersected");
274           }
275         }
276
277         // Copy shape
278         TopoDS_Shape aShapeCopy;
279         TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
280
281         TNaming_CopyShape::CopyTool(aShape, aMapTShapes, aShapeCopy);
282         aShape = aShapeCopy;
283         
284         Handle(TColStd_HSequenceOfTransient) aTools = aCI.GetShapes();
285         const Standard_Integer nbShapes = aTools->Length();
286         Standard_Integer i;
287         Handle(GEOM_Function) aRefTool;
288         TopoDS_Shape aTool;
289
290         for (i = 1; i <= nbShapes; i++) {
291           aRefTool = Handle(GEOM_Function)::DownCast(aTools->Value(i));
292           aTool = aRefTool->GetValue();
293
294           if (!GEOMUtils::CheckShape(aTool, true))
295             StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
296
297           if (isCheckSelfInte) {
298             BOPCol_ListOfShape aList2;
299             aList2.Append(aTool);
300             aCSI.SetArguments(aList2);
301             aCSI.Perform();
302             if (aCSI.ErrorStatus() || aCSI.DS().Interferences().Extent() > 0) {
303               StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is self-intersected");
304             }
305           }
306
307           // Copy shape
308           aShapeCopy.Nullify();
309           TNaming_CopyShape::CopyTool(aTool, aMapTShapes, aShapeCopy);
310           aShape = performOperation (aShape, aShapeCopy, BOOLEAN_CUT);
311
312           if (aShape.IsNull()) {
313             return 0;
314           }
315         }
316       }
317     }
318     break;
319   default:
320     break;
321   }
322
323   aFunction->SetValue(aShape);
324
325 #if OCC_VERSION_MAJOR < 7
326   log.SetTouched(Label());
327 #else
328   log->SetTouched(Label());
329 #endif
330
331   return 1;
332 }
333
334 //=======================================================================
335 //function : performOperation
336 //purpose  :
337 //=======================================================================
338 TopoDS_Shape GEOMImpl_BooleanDriver::performOperation
339                                (const TopoDS_Shape theShape1,
340                                 const TopoDS_Shape theShape2,
341                                 const Standard_Integer theType)const
342 {
343   TopoDS_Shape aShape;
344
345   // perform COMMON operation
346   if (theType == BOOLEAN_COMMON) {
347     BRep_Builder B;
348     TopoDS_Compound C;
349     B.MakeCompound(C);
350
351     TopTools_ListOfShape listShape1, listShape2;
352     GEOMUtils::AddSimpleShapes(theShape1, listShape1);
353     GEOMUtils::AddSimpleShapes(theShape2, listShape2);
354
355     Standard_Boolean isCompound =
356       (listShape1.Extent() > 1 || listShape2.Extent() > 1);
357
358     TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
359     for (; itSub1.More(); itSub1.Next()) {
360       TopoDS_Shape aValue1 = itSub1.Value();
361       TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
362       for (; itSub2.More(); itSub2.Next()) {
363         TopoDS_Shape aValue2 = itSub2.Value();
364         BRepAlgoAPI_Common BO (aValue1, aValue2);
365         if (!BO.IsDone()) {
366           StdFail_NotDone::Raise("Common operation can not be performed on the given shapes");
367         }
368         if (isCompound) {
369           TopoDS_Shape aStepResult = BO.Shape();
370
371           // check result of this step: if it is a compound (boolean operations
372           // allways return a compound), we add all sub-shapes of it.
373           // This allows to avoid adding empty compounds,
374           // resulting from COMMON on two non-intersecting shapes.
375           if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
376             TopoDS_Iterator aCompIter (aStepResult);
377             for (; aCompIter.More(); aCompIter.Next()) {
378               // add shape in a result
379               B.Add(C, aCompIter.Value());
380             }
381           }
382           else {
383             // add shape in a result
384             B.Add(C, aStepResult);
385           }
386         }
387         else
388           aShape = BO.Shape();
389       }
390     }
391
392     if (isCompound) {
393       // As GlueFaces has been improved to keep all kind of shapes
394       TopExp_Explorer anExp (C, TopAbs_VERTEX);
395       if (anExp.More())
396         aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
397       else
398         aShape = C;
399     }
400   }
401
402   // perform CUT operation
403   else if (theType == BOOLEAN_CUT) {
404     BRep_Builder B;
405     TopoDS_Compound C;
406     B.MakeCompound(C);
407
408     TopTools_ListOfShape listShapes, listTools;
409     GEOMUtils::AddSimpleShapes(theShape1, listShapes);
410     GEOMUtils::AddSimpleShapes(theShape2, listTools);
411
412     Standard_Boolean isCompound = (listShapes.Extent() > 1);
413
414     TopTools_ListIteratorOfListOfShape itSub1 (listShapes);
415     for (; itSub1.More(); itSub1.Next()) {
416       TopoDS_Shape aCut = itSub1.Value();
417       // tools
418       TopTools_ListIteratorOfListOfShape itSub2 (listTools);
419       for (; itSub2.More(); itSub2.Next()) {
420         TopoDS_Shape aTool = itSub2.Value();
421         BRepAlgoAPI_Cut BO (aCut, aTool);
422         if (!BO.IsDone()) {
423           StdFail_NotDone::Raise("Cut operation can not be performed on the given shapes");
424         }
425         aCut = BO.Shape();
426       }
427       if (isCompound) {
428         // check result of this step: if it is a compound (boolean operations
429         // allways return a compound), we add all sub-shapes of it.
430         // This allows to avoid adding empty compounds,
431         // resulting from CUT of parts
432         if (aCut.ShapeType() == TopAbs_COMPOUND) {
433           TopoDS_Iterator aCompIter (aCut);
434           for (; aCompIter.More(); aCompIter.Next()) {
435             // add shape in a result
436             B.Add(C, aCompIter.Value());
437           }
438         }
439         else {
440           // add shape in a result
441           B.Add(C, aCut);
442         }
443       }
444       else
445         aShape = aCut;
446     }
447
448     if (isCompound) {
449       // As GlueFaces has been improved to keep all kind of shapes
450       TopExp_Explorer anExp (C, TopAbs_VERTEX);
451       if (anExp.More())
452         aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
453       else
454         aShape = C;
455     }
456   }
457
458   // perform FUSE operation
459   else if (theType == BOOLEAN_FUSE) {
460     // Perform
461     BRepAlgoAPI_Fuse BO (theShape1, theShape2);
462     if (!BO.IsDone()) {
463       StdFail_NotDone::Raise("Fuse operation can not be performed on the given shapes");
464     }
465     aShape = BO.Shape();
466   }
467
468   // perform SECTION operation
469   else if (theType == BOOLEAN_SECTION) {
470     BRep_Builder B;
471     TopoDS_Compound C;
472     B.MakeCompound(C);
473
474     TopTools_ListOfShape listShape1, listShape2;
475     GEOMUtils::AddSimpleShapes(theShape1, listShape1);
476     GEOMUtils::AddSimpleShapes(theShape2, listShape2);
477
478     Standard_Boolean isCompound =
479       (listShape1.Extent() > 1 || listShape2.Extent() > 1);
480
481     TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
482     for (; itSub1.More(); itSub1.Next()) {
483       TopoDS_Shape aValue1 = itSub1.Value();
484       TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
485       for (; itSub2.More(); itSub2.Next()) {
486         TopoDS_Shape aValue2 = itSub2.Value();
487         BRepAlgoAPI_Section BO (aValue1, aValue2, Standard_False);
488         // Set approximation to have an attached 3D BSpline geometry to each edge,
489         // where analytic curve is not possible. Without this flag in some cases
490         // we obtain BSpline curve of degree 1 (C0), which is slowly
491         // processed by some algorithms (Partition for example).
492         BO.Approximation(Standard_True);
493         //modified by NIZNHY-PKV Tue Oct 18 14:34:16 2011f
494         BO.ComputePCurveOn1(Standard_True);
495         BO.ComputePCurveOn2(Standard_True);
496         //modified by NIZNHY-PKV Tue Oct 18 14:34:18 2011t
497   
498         BO.Build();
499         if (!BO.IsDone()) {
500           StdFail_NotDone::Raise("Section operation can not be performed on the given shapes");
501         }
502         if (isCompound) {
503           TopoDS_Shape aStepResult = BO.Shape();
504
505           // check result of this step: if it is a compound (boolean operations
506           // allways return a compound), we add all sub-shapes of it.
507           // This allows to avoid adding empty compounds,
508           // resulting from SECTION on two non-intersecting shapes.
509           if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
510             TopoDS_Iterator aCompIter (aStepResult);
511             for (; aCompIter.More(); aCompIter.Next()) {
512               // add shape in a result
513               B.Add(C, aCompIter.Value());
514             }
515           }
516           else {
517             // add shape in a result
518             B.Add(C, aStepResult);
519           }
520         }
521         else
522           aShape = BO.Shape();
523       }
524     }
525
526     if (isCompound) {
527       // As GlueFaces has been improved to keep all kind of shapes
528       TopExp_Explorer anExp (C, TopAbs_VERTEX);
529       if (anExp.More())
530         aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
531       else
532         aShape = C;
533     }
534   }
535
536   // UNKNOWN operation
537   else {
538   }
539
540   if (aShape.IsNull()) return aShape;
541
542   // as boolean operations always produce compound, lets simplify it
543   // for the case, if it contains only one sub-shape
544   TopTools_ListOfShape listShapeRes;
545   GEOMUtils::AddSimpleShapes(aShape, listShapeRes);
546   if (listShapeRes.Extent() == 1) {
547     aShape = listShapeRes.First();
548     if (aShape.IsNull()) return aShape;
549   }
550
551   // 08.07.2008 skl for bug 19761 from Mantis
552   if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) )
553     Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result");
554
555   return aShape;
556 }
557
558 //================================================================================
559 /*!
560  * \brief Returns a name of creation operation and names and values of creation parameters
561  */
562 //================================================================================
563
564 bool GEOMImpl_BooleanDriver::
565 GetCreationInformation(std::string&             theOperationName,
566                        std::vector<GEOM_Param>& theParams)
567 {
568   if (Label().IsNull()) return 0;
569   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
570
571   GEOMImpl_IBoolean aCI (function);
572   Standard_Integer aType = function->GetType();
573   Standard_Boolean isCheckSelfInte = aCI.GetCheckSelfIntersection();
574
575   switch ( aType ) {
576   case BOOLEAN_COMMON:
577     theOperationName = "COMMON";
578     AddParam( theParams, "Object 1", aCI.GetShape1() );
579     AddParam( theParams, "Object 2", aCI.GetShape2() );
580     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
581     break;
582   case BOOLEAN_CUT:
583     theOperationName = "CUT";
584     AddParam( theParams, "Main Object", aCI.GetShape1() );
585     AddParam( theParams, "Tool Object", aCI.GetShape2() );
586     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
587     break;
588   case BOOLEAN_FUSE:
589     theOperationName = "FUSE";
590     AddParam( theParams, "Object 1", aCI.GetShape1() );
591     AddParam( theParams, "Object 2", aCI.GetShape2() );
592     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
593     AddParam( theParams, "Remove extra edges", aCI.GetRmExtraEdges() );
594     break;
595   case BOOLEAN_SECTION:
596     theOperationName = "SECTION";
597     AddParam( theParams, "Object 1", aCI.GetShape1() );
598     AddParam( theParams, "Object 2", aCI.GetShape2() );
599     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
600     break;
601   case BOOLEAN_COMMON_LIST:
602     theOperationName = "COMMON";
603     AddParam( theParams, "Selected objects", aCI.GetShapes() );
604     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
605     break;
606   case BOOLEAN_FUSE_LIST:
607     theOperationName = "FUSE";
608     AddParam( theParams, "Selected objects", aCI.GetShapes() );
609     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
610     AddParam( theParams, "Remove extra edges", aCI.GetRmExtraEdges() );
611     break;
612   case BOOLEAN_CUT_LIST:
613     theOperationName = "CUT";
614     AddParam( theParams, "Main Object", aCI.GetShape1() );
615     AddParam( theParams, "Tool Objects", aCI.GetShapes() );
616     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
617     break;
618   default:
619     return false;
620   }
621
622   return true;
623 }
624
625 OCCT_IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_BooleanDriver,GEOM_BaseDriver);