Salome HOME
fix for test cases bugs_13/N8 and imps_04/E5
[modules/geom.git] / src / GEOMImpl / GEOMImpl_BooleanDriver.cxx
1 // Copyright (C) 2007-2015  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(aResult, 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 (TFunction_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   log.SetTouched(Label());
326
327   return 1;
328 }
329
330 //=======================================================================
331 //function : performOperation
332 //purpose  :
333 //=======================================================================
334 TopoDS_Shape GEOMImpl_BooleanDriver::performOperation
335                                (const TopoDS_Shape theShape1,
336                                 const TopoDS_Shape theShape2,
337                                 const Standard_Integer theType)const
338 {
339   TopoDS_Shape aShape;
340
341   // perform COMMON operation
342   if (theType == BOOLEAN_COMMON) {
343     BRep_Builder B;
344     TopoDS_Compound C;
345     B.MakeCompound(C);
346
347     TopTools_ListOfShape listShape1, listShape2;
348     GEOMUtils::AddSimpleShapes(theShape1, listShape1);
349     GEOMUtils::AddSimpleShapes(theShape2, listShape2);
350
351     Standard_Boolean isCompound =
352       (listShape1.Extent() > 1 || listShape2.Extent() > 1);
353
354     TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
355     for (; itSub1.More(); itSub1.Next()) {
356       TopoDS_Shape aValue1 = itSub1.Value();
357       TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
358       for (; itSub2.More(); itSub2.Next()) {
359         TopoDS_Shape aValue2 = itSub2.Value();
360         BRepAlgoAPI_Common BO (aValue1, aValue2);
361         if (!BO.IsDone()) {
362           StdFail_NotDone::Raise("Common operation can not be performed on the given shapes");
363         }
364         if (isCompound) {
365           TopoDS_Shape aStepResult = BO.Shape();
366
367           // check result of this step: if it is a compound (boolean operations
368           // allways return a compound), we add all sub-shapes of it.
369           // This allows to avoid adding empty compounds,
370           // resulting from COMMON on two non-intersecting shapes.
371           if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
372             TopoDS_Iterator aCompIter (aStepResult);
373             for (; aCompIter.More(); aCompIter.Next()) {
374               // add shape in a result
375               B.Add(C, aCompIter.Value());
376             }
377           }
378           else {
379             // add shape in a result
380             B.Add(C, aStepResult);
381           }
382         }
383         else
384           aShape = BO.Shape();
385       }
386     }
387
388     if (isCompound) {
389       // As GlueFaces has been improved to keep all kind of shapes
390       TopExp_Explorer anExp (C, TopAbs_VERTEX);
391       if (anExp.More())
392         aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
393       else
394         aShape = C;
395     }
396   }
397
398   // perform CUT operation
399   else if (theType == BOOLEAN_CUT) {
400     BRep_Builder B;
401     TopoDS_Compound C;
402     B.MakeCompound(C);
403
404     TopTools_ListOfShape listShapes, listTools;
405     GEOMUtils::AddSimpleShapes(theShape1, listShapes);
406     GEOMUtils::AddSimpleShapes(theShape2, listTools);
407
408     Standard_Boolean isCompound = (listShapes.Extent() > 1);
409
410     TopTools_ListIteratorOfListOfShape itSub1 (listShapes);
411     for (; itSub1.More(); itSub1.Next()) {
412       TopoDS_Shape aCut = itSub1.Value();
413       // tools
414       TopTools_ListIteratorOfListOfShape itSub2 (listTools);
415       for (; itSub2.More(); itSub2.Next()) {
416         TopoDS_Shape aTool = itSub2.Value();
417         BRepAlgoAPI_Cut BO (aCut, aTool);
418         if (!BO.IsDone()) {
419           StdFail_NotDone::Raise("Cut operation can not be performed on the given shapes");
420         }
421         aCut = BO.Shape();
422       }
423       if (isCompound) {
424         // check result of this step: if it is a compound (boolean operations
425         // allways return a compound), we add all sub-shapes of it.
426         // This allows to avoid adding empty compounds,
427         // resulting from CUT of parts
428         if (aCut.ShapeType() == TopAbs_COMPOUND) {
429           TopoDS_Iterator aCompIter (aCut);
430           for (; aCompIter.More(); aCompIter.Next()) {
431             // add shape in a result
432             B.Add(C, aCompIter.Value());
433           }
434         }
435         else {
436           // add shape in a result
437           B.Add(C, aCut);
438         }
439       }
440       else
441         aShape = aCut;
442     }
443
444     if (isCompound) {
445       // As GlueFaces has been improved to keep all kind of shapes
446       TopExp_Explorer anExp (C, TopAbs_VERTEX);
447       if (anExp.More())
448         aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
449       else
450         aShape = C;
451     }
452   }
453
454   // perform FUSE operation
455   else if (theType == BOOLEAN_FUSE) {
456     // Perform
457     BRepAlgoAPI_Fuse BO (theShape1, theShape2);
458     if (!BO.IsDone()) {
459       StdFail_NotDone::Raise("Fuse operation can not be performed on the given shapes");
460     }
461     aShape = BO.Shape();
462   }
463
464   // perform SECTION operation
465   else if (theType == BOOLEAN_SECTION) {
466     BRep_Builder B;
467     TopoDS_Compound C;
468     B.MakeCompound(C);
469
470     TopTools_ListOfShape listShape1, listShape2;
471     GEOMUtils::AddSimpleShapes(theShape1, listShape1);
472     GEOMUtils::AddSimpleShapes(theShape2, listShape2);
473
474     Standard_Boolean isCompound =
475       (listShape1.Extent() > 1 || listShape2.Extent() > 1);
476
477     TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
478     for (; itSub1.More(); itSub1.Next()) {
479       TopoDS_Shape aValue1 = itSub1.Value();
480       TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
481       for (; itSub2.More(); itSub2.Next()) {
482         TopoDS_Shape aValue2 = itSub2.Value();
483         BRepAlgoAPI_Section BO (aValue1, aValue2, Standard_False);
484         // Set approximation to have an attached 3D BSpline geometry to each edge,
485         // where analytic curve is not possible. Without this flag in some cases
486         // we obtain BSpline curve of degree 1 (C0), which is slowly
487         // processed by some algorithms (Partition for example).
488         BO.Approximation(Standard_True);
489         //modified by NIZNHY-PKV Tue Oct 18 14:34:16 2011f
490         BO.ComputePCurveOn1(Standard_True);
491         BO.ComputePCurveOn2(Standard_True);
492         //modified by NIZNHY-PKV Tue Oct 18 14:34:18 2011t
493   
494         BO.Build();
495         if (!BO.IsDone()) {
496           StdFail_NotDone::Raise("Section operation can not be performed on the given shapes");
497         }
498         if (isCompound) {
499           TopoDS_Shape aStepResult = BO.Shape();
500
501           // check result of this step: if it is a compound (boolean operations
502           // allways return a compound), we add all sub-shapes of it.
503           // This allows to avoid adding empty compounds,
504           // resulting from SECTION on two non-intersecting shapes.
505           if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
506             TopoDS_Iterator aCompIter (aStepResult);
507             for (; aCompIter.More(); aCompIter.Next()) {
508               // add shape in a result
509               B.Add(C, aCompIter.Value());
510             }
511           }
512           else {
513             // add shape in a result
514             B.Add(C, aStepResult);
515           }
516         }
517         else
518           aShape = BO.Shape();
519       }
520     }
521
522     if (isCompound) {
523       // As GlueFaces has been improved to keep all kind of shapes
524       TopExp_Explorer anExp (C, TopAbs_VERTEX);
525       if (anExp.More())
526         aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
527       else
528         aShape = C;
529     }
530   }
531
532   // UNKNOWN operation
533   else {
534   }
535
536   if (aShape.IsNull()) return aShape;
537
538   // as boolean operations always produce compound, lets simplify it
539   // for the case, if it contains only one sub-shape
540   TopTools_ListOfShape listShapeRes;
541   GEOMUtils::AddSimpleShapes(aShape, listShapeRes);
542   if (listShapeRes.Extent() == 1) {
543     aShape = listShapeRes.First();
544     if (aShape.IsNull()) return aShape;
545   }
546
547   // 08.07.2008 skl for bug 19761 from Mantis
548   if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) )
549     Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result");
550
551   return aShape;
552 }
553
554 //================================================================================
555 /*!
556  * \brief Returns a name of creation operation and names and values of creation parameters
557  */
558 //================================================================================
559
560 bool GEOMImpl_BooleanDriver::
561 GetCreationInformation(std::string&             theOperationName,
562                        std::vector<GEOM_Param>& theParams)
563 {
564   if (Label().IsNull()) return 0;
565   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
566
567   GEOMImpl_IBoolean aCI (function);
568   Standard_Integer aType = function->GetType();
569   Standard_Boolean isCheckSelfInte = aCI.GetCheckSelfIntersection();
570
571   switch ( aType ) {
572   case BOOLEAN_COMMON:
573     theOperationName = "COMMON";
574     AddParam( theParams, "Object 1", aCI.GetShape1() );
575     AddParam( theParams, "Object 2", aCI.GetShape2() );
576     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
577     break;
578   case BOOLEAN_CUT:
579     theOperationName = "CUT";
580     AddParam( theParams, "Main Object", aCI.GetShape1() );
581     AddParam( theParams, "Tool Object", aCI.GetShape2() );
582     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
583     break;
584   case BOOLEAN_FUSE:
585     theOperationName = "FUSE";
586     AddParam( theParams, "Object 1", aCI.GetShape1() );
587     AddParam( theParams, "Object 2", aCI.GetShape2() );
588     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
589     AddParam( theParams, "Remove extra edges", aCI.GetRmExtraEdges() );
590     break;
591   case BOOLEAN_SECTION:
592     theOperationName = "SECTION";
593     AddParam( theParams, "Object 1", aCI.GetShape1() );
594     AddParam( theParams, "Object 2", aCI.GetShape2() );
595     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
596     break;
597   case BOOLEAN_COMMON_LIST:
598     theOperationName = "COMMON";
599     AddParam( theParams, "Selected objects", aCI.GetShapes() );
600     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
601     break;
602   case BOOLEAN_FUSE_LIST:
603     theOperationName = "FUSE";
604     AddParam( theParams, "Selected objects", aCI.GetShapes() );
605     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
606     AddParam( theParams, "Remove extra edges", aCI.GetRmExtraEdges() );
607     break;
608   case BOOLEAN_CUT_LIST:
609     theOperationName = "CUT";
610     AddParam( theParams, "Main Object", aCI.GetShape1() );
611     AddParam( theParams, "Tool Objects", aCI.GetShapes() );
612     AddParam( theParams, "Check self-intersections", isCheckSelfInte );
613     break;
614   default:
615     return false;
616   }
617
618   return true;
619 }
620
621 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_BooleanDriver,GEOM_BaseDriver);
622
623 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_BooleanDriver,GEOM_BaseDriver);