]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
0022081: EDF 2386 GEOM: Union of a list of objects
authorskv <skv@opencascade.com>
Thu, 23 May 2013 06:42:48 +0000 (06:42 +0000)
committerskv <skv@opencascade.com>
Thu, 23 May 2013 06:42:48 +0000 (06:42 +0000)
25 files changed:
doc/salome/examples/boolean_operations_ex01.py
doc/salome/examples/boolean_operations_ex02.py
doc/salome/examples/boolean_operations_ex03.py
doc/salome/gui/GEOM/input/common_operation.doc
doc/salome/gui/GEOM/input/cut_operation.doc
doc/salome/gui/GEOM/input/fuse_operation.doc
doc/salome/gui/GEOM/input/section_operation.doc
doc/salome/gui/GEOM/input/using_boolean_operations.doc
idl/GEOM_Gen.idl
src/BooleanGUI/BooleanGUI_Dialog.cxx
src/BooleanGUI/BooleanGUI_Dialog.h
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GEOM_msg_fr.ts
src/GEOMImpl/GEOMImpl_BooleanDriver.cxx
src/GEOMImpl/GEOMImpl_BooleanDriver.hxx
src/GEOMImpl/GEOMImpl_IBoolean.hxx
src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx
src/GEOMImpl/GEOMImpl_IBooleanOperations.hxx
src/GEOMImpl/GEOMImpl_Types.hxx
src/GEOM_I/GEOM_IBooleanOperations_i.cc
src/GEOM_I/GEOM_IBooleanOperations_i.hh
src/GEOM_I/GEOM_IOperations_i.cc
src/GEOM_I/GEOM_IOperations_i.hh
src/GEOM_SWIG/GEOM_TestOthers.py
src/GEOM_SWIG/geomBuilder.py

index 01809955eecf467531b3103693e9346cbcc6d0e8..7c365d7eb6980c5cd8f7ca4e90292e3672f8fa54 100644 (file)
@@ -20,22 +20,32 @@ cylinder = geompy.MakeCylinder(p1, v, radius1, height)
 # create a sphere
 sphere = geompy.MakeSphereR(40)
 
+# create a box
+box = geompy.MakeBoxDXDYDZ(80, 80, 80)
+
 # fuse
 fuse1 = geompy.MakeFuse(cylinder, sphere)
 fuse2 = geompy.MakeBoolean(cylinder, sphere, 3)
+fuse3 = geompy.MakeFuseList([cylinder, sphere, box])
 
 # add objects in the study
 id_cylinder = geompy.addToStudy(cylinder, "Cylinder")
 id_sphere = geompy.addToStudy(sphere, "Sphere")
+id_box = geompy.addToStudy(box, "Box")
 id_fuse1 = geompy.addToStudy(fuse1, "Fuse_1")
 id_fuse2 = geompy.addToStudy(fuse2, "Fuse_2")
+id_fuse3 = geompy.addToStudy(fuse3, "Fuse_3")
 
 # display results
 gg.createAndDisplayGO(id_cylinder)
 gg.setDisplayMode(id_cylinder,1)
 gg.createAndDisplayGO(id_sphere)
 gg.setDisplayMode(id_sphere,1)
+gg.createAndDisplayGO(id_box)
+gg.setDisplayMode(id_box,1)
 gg.createAndDisplayGO(id_fuse1)
 gg.setDisplayMode(id_fuse1,1)
 gg.createAndDisplayGO(id_fuse2)
 gg.setDisplayMode(id_fuse2,1)
+gg.createAndDisplayGO(id_fuse3)
+gg.setDisplayMode(id_fuse3,1)
index 90317ba93efe389d951cfbed3b28b05f04fb7c64..212e313d479b59008c8c268418095d3b5711e18d 100644 (file)
@@ -20,12 +20,28 @@ cylinder = geompy.MakeCylinder(p1, v, radius1, height)
 # create a sphere
 sphere = geompy.MakeSphereR(40)
 
+# create a box
+box = geompy.MakeBoxDXDYDZ(80, 80, 80)
+
 # make common
-common = geompy.MakeCommon(cylinder, sphere)
+common1 = geompy.MakeCommon(cylinder, sphere)
+common2 = geompy.MakeCommonList([cylinder, sphere, box])
 
 # add objects in the study
-id_common = geompy.addToStudy(common, "Common")
+id_cylinder = geompy.addToStudy(cylinder, "Cylinder")
+id_sphere = geompy.addToStudy(sphere, "Sphere")
+id_box = geompy.addToStudy(box, "Box")
+id_common1 = geompy.addToStudy(common1, "Common_1")
+id_common2 = geompy.addToStudy(common2, "Common_2")
 
 # display the results
-gg.createAndDisplayGO(id_common)
-gg.setDisplayMode(id_common,1)
+gg.createAndDisplayGO(id_cylinder)
+gg.setDisplayMode(id_cylinder,1)
+gg.createAndDisplayGO(id_sphere)
+gg.setDisplayMode(id_sphere,1)
+gg.createAndDisplayGO(id_box)
+gg.setDisplayMode(id_box,1)
+gg.createAndDisplayGO(id_common1)
+gg.setDisplayMode(id_common1,1)
+gg.createAndDisplayGO(id_common2)
+gg.setDisplayMode(id_common2,1)
index 7c97b09f0b49ed310c47487e3d56b14d30f08ed0..fdb7545f1e2a2b113409d88869b8f563216a8602 100644 (file)
@@ -20,12 +20,28 @@ cylinder = geompy.MakeCylinder(p1, v, radius1, height)
 # create a sphere
 sphere = geompy.MakeSphereR(40)
 
+# create a box
+box = geompy.MakeBoxDXDYDZ(80, 80, 80)
+
 #cut
-cut = geompy.MakeCut(cylinder, sphere)
+cut1 = geompy.MakeCut(cylinder, sphere)
+cut2 = geompy.MakeCutList(cylinder, [sphere, box])
 
 # add objects in the study
-id_cut = geompy.addToStudy(cut, "Cut")
+id_cylinder = geompy.addToStudy(cylinder, "Cylinder")
+id_sphere = geompy.addToStudy(sphere, "Sphere")
+id_box = geompy.addToStudy(box, "Box")
+id_cut1 = geompy.addToStudy(cut1, "Cut_1")
+id_cut2 = geompy.addToStudy(cut2, "Cut_2")
 
 # display the results
-gg.createAndDisplayGO(id_cut)
-gg.setDisplayMode(id_cut,1) 
+gg.createAndDisplayGO(id_cylinder)
+gg.setDisplayMode(id_cylinder,1)
+gg.createAndDisplayGO(id_sphere)
+gg.setDisplayMode(id_sphere,1)
+gg.createAndDisplayGO(id_box)
+gg.setDisplayMode(id_box,1)
+gg.createAndDisplayGO(id_cut1)
+gg.setDisplayMode(id_cut1,1) 
+gg.createAndDisplayGO(id_cut2)
+gg.setDisplayMode(id_cut2,1) 
index f6903e24c140e2ec472c376d7fe17dfea2332c54..e24645f31eb9280ad6149c911ff55725b30a28c4 100644 (file)
@@ -2,23 +2,23 @@
 
 \page common_operation_page Common
 
-For detail description of the Boolean operations please refer to
-<a href="SALOME_BOA_PA.pdf">this document</a>. 
-It provides a general review of the Partition and Boolean
-operations algorithms, describes the usage methodology and highlighs
-major limitations of these operations.
-
 To produce a \b Common operation in the <b>Main Menu</b> select <b>Operations - > Boolean - > Common</b>
 
-This operation cuts the common part of two shapes and transforms it into an independent geometrical object.
+This operation cuts the common part of a list of shapes and transforms it into an independent geometrical object.
+
+The \b Result will be a \b GEOM_Object.
 
-The \b Result will be any \b GEOM_Object.
-<b>TUI Command:</b> <em>geompy.MakeCommon(s1, s2)</em>
-<b>Arguments:</b> Name + 2 shapes.
+<b>TUI Command:</b> <em>geompy.MakeCommonList(theShapesList)</em>\n
+<b>Arguments:</b> Name + a list of shapes.\n
 <b>Advanced option:</b>
 \ref restore_presentation_parameters_page "Set presentation parameters and sub-shapes from arguments".
 
-\image html bool2.png
+\image html bool2.png "Common dialog"
+\r
+For a particular case with two shapes for the Common operation there is the following TUI command:
+
+<b>TUI Command:</b> <em>geompy.MakeCommon(s1, s2)</em>\n\r
+<b>Arguments:</b> Name + 2 shapes.\r
 
 <b>Example:</b>
 
@@ -29,4 +29,12 @@ The \b Result will be any \b GEOM_Object.
 Our <b>TUI Scripts</b> provide you with useful examples of the use of
 \ref tui_common "Boolean Operations".
 
+<b> More details </b>
+
+For a detailed description of the Boolean operations please refer to
+<a href="SALOME_BOA_PA.pdf">this document</a>. 
+It provides a general review of the Partition and Boolean
+operations algorithms, describes the usage methodology and highlights
+major limitations of these operations.
+
 */
index 5ea6c5dfca6e1128a89433f47ac9b17d7ac280f0..d00c587eb5825927ac0de953dda1543415c03eb2 100644 (file)
@@ -2,23 +2,23 @@
 
 \page cut_operation_page Cut
 
-For detail description of the Boolean operations please refer to
-<a href="SALOME_BOA_PA.pdf">this document</a>. 
-It provides a general review of the Partition and Boolean
-operations algorithms, describes the usage methodology and highlighs
-major limitations of these operations.
-
 To produce a \b Cut operation in the <b>Main Menu</b> select <b>Operations - > Boolean - > Cut</b>
 
-This operation cuts a shape with another one.
-The \b Result will be any \b GEOM_Object.
-<b>Arguments:</b> Name + 2 shapes.
+This operation cuts a shape with a list of other shapes.
+
+The \b Result will be a \b GEOM_Object.
+
+<b>TUI Command:</b> <em>geompy.MakeCutList(theMainShape, theShapesList)</em>\n
+<b>Arguments:</b> Name + a main shape + a list of other shapes.\n
 <b>Advanced option:</b>
 \ref restore_presentation_parameters_page "Set presentation parameters and sub-shapes from arguments".
 
-<b>Dialog Box:</b>
+\image html bool3.png "Cut dialog"
 
-\image html bool3.png
+For a particular case with two shapes (object and tool) for the Cut operation there is the following TUI command:
+
+<b>TUI Command:</b> <em>geompy.MakeCut(s1, s2)</em>\n\r
+<b>Arguments:</b> Name + the object + the tool.\r
 
 <b>Example:</b>
 
@@ -29,4 +29,12 @@ The \b Result will be any \b GEOM_Object.
 Our <b>TUI Scripts</b> provide you with useful examples of the use of 
 \ref tui_cut "Boolean Operations".
 
+<b> More details </b>
+
+For a detailed description of the Boolean operations please refer to
+<a href="SALOME_BOA_PA.pdf">this document</a>. 
+It provides a general review of the Partition and Boolean
+operations algorithms, describes the usage methodology and highlights
+major limitations of these operations.
+
 */
index df13c732e94fd22158646628922b06e603064669..b45e580a8238c51a2511c0d805bbeec53b58449d 100644 (file)
@@ -5,8 +5,21 @@
 To produce a \b Fuse operation in the <b>Main Menu</b> select
 <b>Operations - > Boolean - > Fuse</b>. 
 
-This operation creates one shape from two shapes.
-The \b Result will be any \b GEOM_Object.
+This operation creates one shape from a list of shapes.
+
+The \b Result will be a \b GEOM_Object.
+
+<b>TUI Command:</b> <em>geompy.MakeFuseList(theShapesList)</em>\n
+<b>Arguments:</b> Name + a list of shapes.\n
+<b>Advanced option:</b>
+\ref restore_presentation_parameters_page "Set presentation parameters and sub-shapes from arguments".
+
+\image html bool1.png "Fuse dialog"
+
+For a particular case with two shapes to be fused there is the following TUI command:
+
+<b>TUI Command:</b> <em>geompy.MakeFuse(s1, s2)</em>\n\r
+<b>Arguments:</b> Name + 2 shapes.\r
 
 <b>Example:</b>
 
@@ -14,13 +27,6 @@ The \b Result will be any \b GEOM_Object.
 
 \image html fusesn2.png "The resulting fuse"
 
-<b>TUI Command:</b> <em>geompy.MakeFuse(s1, s2)</em>\n
-<b>Arguments:</b> Name + 2 shapes.\n
-<b>Advanced option:</b>
-\ref restore_presentation_parameters_page "Set presentation parameters and sub-shapes from arguments".
-
-\image html bool1.png
-
 Our <b>TUI Scripts</b> provide you with useful examples of the use of 
 \ref tui_fuse "Boolean Operations".
 
index 383f1c5de39413eddfbefd3c719427c19ac529ad..5d60cf433d0a40342e920c52883b280294fd71ab 100644 (file)
@@ -2,24 +2,19 @@
 
 \page section_opeartion_page Section
 
-For detail description of the Boolean operations please refer to
-<a href="SALOME_BOA_PA.pdf">this document</a>. 
-It provides a general review of the Partition and Boolean
-operations algorithms, describes the usage methodology and highlighs
-major limitations of these operations.
-
 To produce a \b Section operation in the <b>Main Menu</b> select
 <b>Operations - > Boolean - > Section</b>
 
 This operation creates the section between 2 shapes.
 
 The \b Result will be any \b GEOM_Object (EDGE or WIRE).
-<b>TUI Command:</b> <em>geompy.MakeSection(s1, s2)</em>
-<b>Arguments:</b> Name + 2 shapes.
+
+<b>TUI Command:</b> <em>geompy.MakeSection(s1, s2)</em>\n
+<b>Arguments:</b> Name + 2 shapes.\n
 <b>Advanced option:</b>
 \ref restore_presentation_parameters_page "Set presentation parameters and sub-shapes from arguments".
 
-\image html neo-section.png
+\image html neo-section.png "Section dialog"
 
 <b>Example:</b>
 
@@ -30,4 +25,12 @@ The \b Result will be any \b GEOM_Object (EDGE or WIRE).
 Our <b>TUI Scripts</b> provide you with useful examples of the use of 
 \ref tui_section "Boolean Operations".
 
+<b> More details </b>
+
+For a detailed description of the Boolean operations please refer to
+<a href="SALOME_BOA_PA.pdf">this document</a>. 
+It provides a general review of the Partition and Boolean
+operations algorithms, describes the usage methodology and highlights
+major limitations of these operations.
+
 */
index d0bca5b6a86e3b64dbf696ed8cdb9c2508b5e42e..84301523e8c22a91f813a962cec133b2cd82abfe 100644 (file)
@@ -12,16 +12,35 @@ You can use the following boolean operations for construction of more
 complex geometrical objects (2D & 3D elements):
 
 <ul>
-<li>\subpage fuse_operation_page "Fuse" - creates a shape from two shapes.</li>
+<li>\subpage fuse_operation_page "Fuse" - creates a shape from a list of shapes.</li>
 <li>\subpage common_operation_page "Common" - transforms the common part
-of two objects into an independent object.</li>
+of a list of objects into an independent object.</li>
 <li>\subpage cut_operation_page "Cut" - cuts one shape with
-another. </li>
+a list of others. </li>
 <li>\subpage section_opeartion_page "Section" - creates a section between two shapes.</li>
 </ul>
 
-There is a general TUI command covering all these operations, which
-can be used alongside with separate commands for each operation.
+You can use advanced TUI commands performing these operations
+independently from each other:
+\par
+<em>geompy.MakeFuseList(theShapesList)</em>, where \em theShapesList is
+the list of shapes for Fuse operation; 
+\par
+<em>geompy.MakeCommonList(theShapesList)</em>, where \em theShapesList is
+the list of shapes for Common operation;
+\par
+<em>geompy.MakeCutList(theMainShape, theShapesList)</em>, where \em
+theMainShape is the object of the operation and \em theShapesList is
+the list of tools for Cut operation;
+\par
+<em>geompy.MakeSection(Shape1, Shape2)</em>, where \em Shape1 is the first
+argument and \em Shape2 is the second argument of Section operation;
+
+
+There are several TUI commands that can be used to perform boolean operations
+with only two arguments. There is a general TUI command covering these
+operations, which can be used alongside with separate commands for each
+operation.
 \par
 <em>geompy.MakeBoolean(Shape1, Shape2, Operation),</em> where \em
 Shape1 is the first argument and \em Shape2 is the second argument of
@@ -32,17 +51,14 @@ Boolean operation, \em Operation is a type of the Boolean operation (1
 Besides, you can use advanced TUI commands performing these operations
 independently from each other:
 \par
-<em>geompy.MakeFuse(Shape1, Shape2)</em>, where \em Shape1 and \em
-Shape2 is the second argument of Fuse operation; 
-\par
-<em>geompy.MakeCommon(Shape1, Shape2)</em>, where \em Shape1 and \em
-Shape2 is the second argument of Common operation;
+<em>geompy.MakeFuse(Shape1, Shape2)</em>, where \em Shape1 is the first
+argument and \em Shape2 is the second argument of Fuse operation; 
 \par
-<em>geompy.MakeCut(Shape1, Shape2)</em>, where \em Shape1 and \em
-Shape2 is the second argument of Cut operation;
+<em>geompy.MakeCommon(Shape1, Shape2)</em>, where \em Shape1 is the first
+argument and \em Shape2 is the second argument of Common operation;
 \par
-<em>geompy.MakeSection(Shape1, Shape2)</em>, where \em Shape1 and \em
-Shape2 is the second argument of Section operation;
+<em>geompy.MakeCut(Shape1, Shape2)</em>, where \em Shape1 is the first
+argument and \em Shape2 is the second argument of Cut operation;
 
 Our <b>TUI Scripts</b> provide you with useful examples of the use of 
 \ref tui_boolean_operations_page "Boolean Operations".
index b3b95cedb77a27ad2ad1cf694163d6a684ec7adb..1395c58597c575f48bf934c24ec463c44b115ced 100644 (file)
@@ -2675,6 +2675,29 @@ module GEOM
                              in GEOM_Object theShape2,
                              in long theOperation);
 
+    /*!
+     *  \brief Perform fusion boolean operation on list of objects.
+     *  \param theShapes Shapes to be fused.
+     *  \return New GEOM_Object, containing the result shape.
+     */
+    GEOM_Object MakeFuseList (in ListOfGO theShapes);
+
+    /*!
+     *  \brief Perform common boolean operation on list of objects.
+     *  \param theShapes Shapes for common operation.
+     *  \return New GEOM_Object, containing the result shape.
+     */
+    GEOM_Object MakeCommonList (in ListOfGO theShapes);
+
+    /*!
+     *  \brief Perform cutting of list of objects from theMainShape.
+     *  \param theMainShape the object for cut operation.
+     *  \param theShapes Shapes to be cut from theMainShape (tools).
+     *  \return New GEOM_Object, containing the result shape.
+     */
+    GEOM_Object MakeCutList (in GEOM_Object theMainShape,
+                             in ListOfGO theShapes);
+
     /*!
      *  \brief Perform partition operation.
      *
index 1ee19166506c587349e0546bc259951ef9f39b70..b312686e327691674dbe152077819fc308648b36 100644 (file)
@@ -35,6 +35,7 @@
 #include <SUIT_ResourceMgr.h>
 #include <SalomeApp_Application.h>
 #include <LightApp_SelectionMgr.h>
+#include <SALOME_ListIteratorOfListIO.hxx>
 
 // VSR 22/08/2012: issue 0021787: remove "Preview" button from BOP and Partition operations
 // Comment next line to enable preview in BOP dialog box
@@ -95,19 +96,27 @@ BooleanGUI_Dialog::BooleanGUI_Dialog (const int theOperation, GeometryGUI* theGe
   myGroup = new DlgRef_2Sel(centralWidget());
 
   myGroup->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
-  if (myOperation != BooleanGUI::CUT) {
+  if (myOperation == BooleanGUI::CUT) {
+    myGroup->TextLabel1->setText(tr("GEOM_MAIN_OBJECT"));
+    myGroup->TextLabel2->setText(tr("GEOM_TOOL_OBJECTS"));
+  }
+  else if (myOperation == BooleanGUI::SECTION) {
     myGroup->TextLabel1->setText(tr("GEOM_OBJECT_I").arg(1));
     myGroup->TextLabel2->setText(tr("GEOM_OBJECT_I").arg(2));
-  }
-  else {
-    myGroup->TextLabel1->setText(tr("GEOM_MAIN_OBJECT"));
-    myGroup->TextLabel2->setText(tr("GEOM_TOOL_OBJECT"));
+  } else { // Fuse or Common
+    myGroup->TextLabel1->setText(tr( "GEOM_SELECTED_OBJECTS" ));
+    myGroup->TextLabel2->hide();
+    myGroup->PushButton2->hide();
+    myGroup->LineEdit2->hide();
   }
 
   myGroup->PushButton1->setIcon(image1);
-  myGroup->PushButton2->setIcon(image1);
   myGroup->LineEdit1->setReadOnly(true);
-  myGroup->LineEdit2->setReadOnly(true);
+
+  if (myOperation != BooleanGUI::FUSE && myOperation != BooleanGUI::COMMON) {
+    myGroup->PushButton2->setIcon(image1);
+    myGroup->LineEdit2->setReadOnly(true);
+  }
 
   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
   layout->setMargin(0); layout->setSpacing(6);
@@ -144,14 +153,17 @@ void BooleanGUI_Dialog::Init()
   myGroup->LineEdit1->setText("");
   myGroup->LineEdit2->setText("");
   myObject1.nullify();
-  myObject2.nullify();
+  reset();
  
   // signals and slots connections
   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
 
   connect(myGroup->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
-  connect(myGroup->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+
+  if (!myGroup->PushButton2->isHidden()) {
+    connect(myGroup->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+  }
 
   connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(),
            SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
@@ -198,10 +210,20 @@ bool BooleanGUI_Dialog::ClickOnApply()
 }
 
 //=================================================================================
-// function : SelectionIntoArgument()
-// purpose  : Called when selection is changed or on dialog initialization or activation
+// function : reset()
+// purpose  : 
 //=================================================================================
-void BooleanGUI_Dialog::SelectionIntoArgument()
+void BooleanGUI_Dialog::reset()
+{
+  myObjects = new GEOM::ListOfGO;
+  myObjects->length( 0 );       
+}
+
+//=================================================================================
+// function : singleSelection
+// purpose  : Performs single selection. Called from SelectionIntoArgument()
+//=================================================================================
+void BooleanGUI_Dialog::singleSelection()
 {
   myEditCurrentArgument->setText("");
 
@@ -219,19 +241,67 @@ void BooleanGUI_Dialog::SelectionIntoArgument()
 
     if (myEditCurrentArgument == myGroup->LineEdit1) {
       myObject1 = aSelectedObject;
-      if (!myObject2)
+      if (!myGroup->PushButton2->isHidden() && !myObjects->length())
         myGroup->PushButton2->click();
     }
     else if (myEditCurrentArgument == myGroup->LineEdit2) {
-      myObject2 = aSelectedObject;
+      myObjects->length(1);
+      myObjects[0] = aSelectedObject.get();
       if (!myObject1)
         myGroup->PushButton1->click();
     }
   }
   else {
     if      (myEditCurrentArgument == myGroup->LineEdit1) myObject1.nullify();
-    else if (myEditCurrentArgument == myGroup->LineEdit2) myObject2.nullify();
+    else if (myEditCurrentArgument == myGroup->LineEdit2) reset();
+  }
+}
+
+//=================================================================================
+// function : multipleSelection
+// purpose  : Performs multiple selection. Called from SelectionIntoArgument()
+//=================================================================================
+void BooleanGUI_Dialog::multipleSelection()
+{
+  myEditCurrentArgument->setText( "" );
+  reset();
+        
+  LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
+  SALOME_ListIO aSelList;
+  aSelMgr->selectedObjects(aSelList);
+  myObjects->length(aSelList.Extent());
+
+  int i = 0;
+  for (SALOME_ListIteratorOfListIO anIt (aSelList); anIt.More(); anIt.Next()) {
+    GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject( anIt.Value() );
+
+    if ( !CORBA::is_nil( aSelectedObject ) ) {
+      myObjects[i++] = aSelectedObject;
+    }
+  }
+
+  myObjects->length( i );
+  if ( i == 1 ) {
+    myEditCurrentArgument->setText( GEOMBase::GetName( myObjects[0] ) );
+  } else if ( i > 0 ) {
+    myEditCurrentArgument->setText( QString::number( i ) + "_" + tr( "GEOM_OBJECTS" ) );
+  }
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection is changed or on dialog initialization or activation
+//=================================================================================
+void BooleanGUI_Dialog::SelectionIntoArgument()
+{
+  if ( myOperation == BooleanGUI::SECTION ||
+      (myOperation == BooleanGUI::CUT &&
+       myEditCurrentArgument == myGroup->LineEdit1)) {
+    singleSelection();
+  } else {
+    multipleSelection();
   }
+
   processPreview();
 }
 
@@ -246,8 +316,10 @@ void BooleanGUI_Dialog::SetEditCurrentArgument()
   if (send == myGroup->PushButton1) {
     myEditCurrentArgument = myGroup->LineEdit1;
 
-    myGroup->PushButton2->setDown(false);
-    myGroup->LineEdit2->setEnabled(false);
+    if (!myGroup->PushButton2->isHidden()) {
+      myGroup->PushButton2->setDown(false);
+      myGroup->LineEdit2->setEnabled(false);
+    }
   }
   else if (send == myGroup->PushButton2) {
     myEditCurrentArgument = myGroup->LineEdit2;
@@ -301,7 +373,24 @@ GEOM::GEOM_IOperations_ptr BooleanGUI_Dialog::createOperation()
 //=================================================================================
 bool BooleanGUI_Dialog::isValid (QString&)
 {
-  return myObject1 && myObject2;
+  bool isOK = false;
+
+  switch (myOperation) {
+    case BooleanGUI::FUSE:
+    case BooleanGUI::COMMON:
+      isOK = myObjects->length() > 1;
+    break;
+  case BooleanGUI::CUT:
+      isOK = myObject1 && myObjects->length();
+    break;
+  case BooleanGUI::SECTION:
+      isOK = myObject1 && (myObjects->length() == 1);
+    break;
+  default:
+    break;
+  }
+
+  return isOK;
 }
 
 //=================================================================================
@@ -313,7 +402,24 @@ bool BooleanGUI_Dialog::execute (ObjectList& objects)
   GEOM::GEOM_Object_var anObj;
 
   GEOM::GEOM_IBooleanOperations_var anOper = GEOM::GEOM_IBooleanOperations::_narrow(getOperation());
-  anObj = anOper->MakeBoolean(myObject1.get(), myObject2.get(), myOperation);
+
+  switch (myOperation) {
+    case BooleanGUI::FUSE:
+      anObj = anOper->MakeFuseList(myObjects);
+    break;
+    case BooleanGUI::COMMON:
+      anObj = anOper->MakeCommonList(myObjects);
+    break;
+  case BooleanGUI::CUT:
+      anObj = anOper->MakeCutList(myObject1.get(), myObjects);
+    break;
+  case BooleanGUI::SECTION:
+      anObj = anOper->MakeBoolean(myObject1.get(), myObjects[0], myOperation);
+    break;
+  default:
+    break;
+  }
+
   if (!anObj->_is_nil())
     objects.push_back(anObj._retn());
 
index 4601cc97d6e33ecb93f03740bed73f1f65a1ba4b..14d84ffd9adf0ddd1a8b91e570285142792c9532 100644 (file)
@@ -55,12 +55,15 @@ protected:
 private:
   void                               Init();
   void                               enterEvent( QEvent* );
+  void                               reset();
+  void                               singleSelection();
+  void                               multipleSelection();
   
 private:
   int                                myOperation;
   
   GEOM::GeomObjPtr                   myObject1;
-  GEOM::GeomObjPtr                   myObject2;
+  GEOM::ListOfGO_var                 myObjects;
   
   DlgRef_2Sel*                       myGroup;
 
index a853aa9984d8014fdad6eb0ecf71219035f7b93e..2d94e74b75cba3b8c0b8459cce21d1f132ffd484 100644 (file)
@@ -439,7 +439,7 @@ Please, select face, shell or solid and try again</translation>
     </message>
     <message>
         <source>GEOM_COMMON_TITLE</source>
-        <translation>Common Of Two Objects</translation>
+        <translation>Common Of Objects</translation>
     </message>
     <message>
         <source>GEOM_COMPOUND</source>
@@ -507,7 +507,7 @@ Please, select face, shell or solid and try again</translation>
     </message>
     <message>
         <source>GEOM_CUT_TITLE</source>
-        <translation>Cut Of Two Objects</translation>
+        <translation>Cut Of Objects</translation>
     </message>
     <message>
         <source>GEOM_CYLINDER</source>
@@ -836,7 +836,7 @@ Please, select face, shell or solid and try again</translation>
     </message>
     <message>
         <source>GEOM_FUSE_TITLE</source>
-        <translation>Fuse Two Objects</translation>
+        <translation>Fuse Objects</translation>
     </message>
     <message>
         <source>GEOM_FixFaceSize</source>
@@ -2142,10 +2142,6 @@ Please, select face, shell or solid and try again</translation>
         <source>GEOM_TOLERANCE_VERTEX</source>
         <translation>Vertex :</translation>
     </message>
-    <message>
-        <source>GEOM_TOOL_OBJECT</source>
-        <translation>Tool Object</translation>
-    </message>
     <message>
         <source>GEOM_TOOL_OBJECTS</source>
         <translation>Tool Objects</translation>
index f8dd0ec2044f93b0f704a900c4eb8999aa739010..3676d3905dd6287d74bfe875950ee4275016801b 100644 (file)
@@ -439,7 +439,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
     </message>
     <message>
         <source>GEOM_COMMON_TITLE</source>
-        <translation>Intersection de deux objets</translation>
+        <translation>Intersection des objets</translation>
     </message>
     <message>
         <source>GEOM_COMPOUND</source>
@@ -507,7 +507,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
     </message>
     <message>
         <source>GEOM_CUT_TITLE</source>
-        <translation>Découpe de deux objets</translation>
+        <translation>Découpe des objets</translation>
     </message>
     <message>
         <source>GEOM_CYLINDER</source>
@@ -836,7 +836,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
     </message>
     <message>
         <source>GEOM_FUSE_TITLE</source>
-        <translation>Réunir deux objets</translation>
+        <translation>Réunir des objets</translation>
     </message>
     <message>
         <source>GEOM_FixFaceSize</source>
@@ -2142,10 +2142,6 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
         <source>GEOM_TOLERANCE_VERTEX</source>
         <translation>Point:</translation>
     </message>
-    <message>
-        <source>GEOM_TOOL_OBJECT</source>
-        <translation>Objet outil </translation>
-    </message>
     <message>
         <source>GEOM_TOOL_OBJECTS</source>
         <translation>Objets outils </translation>
index a0af1efd6da9258cb7dc98b6278e6005e90d9946..8cc9f8bfdd485c6943fe148c2df092f766805b4e 100644 (file)
@@ -41,7 +41,6 @@
 #include <BRepCheck_Analyzer.hxx>
 
 #include <TopExp_Explorer.hxx>
-#include <TopoDS_Shape.hxx>
 #include <TopoDS_Compound.hxx>
 #include <TopoDS_Iterator.hxx>
 #include <TopTools_MapOfShape.hxx>
@@ -87,124 +86,166 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const
 
   TopoDS_Shape aShape;
 
-  Handle(GEOM_Function) aRefShape1 = aCI.GetShape1();
-  Handle(GEOM_Function) aRefShape2 = aCI.GetShape2();
-  TopoDS_Shape aShape1 = aRefShape1->GetValue();
-  TopoDS_Shape aShape2 = aRefShape2->GetValue();
-
-  if (!aShape1.IsNull() && !aShape2.IsNull()) {
-    // check arguments for Mantis issue 0021019
-    BRepCheck_Analyzer ana (aShape1, Standard_True);
-    if (!ana.IsValid())
-      StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
-    ana.Init(aShape2);
-    if (!ana.IsValid())
-      StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
-
-    // perform COMMON operation
-    if (aType == BOOLEAN_COMMON) {
-      BRep_Builder B;
-      TopoDS_Compound C;
-      B.MakeCompound(C);
-
-      TopTools_ListOfShape listShape1, listShape2;
-      GEOMUtils::AddSimpleShapes(aShape1, listShape1);
-      GEOMUtils::AddSimpleShapes(aShape2, listShape2);
-
-      Standard_Boolean isCompound =
-        (listShape1.Extent() > 1 || listShape2.Extent() > 1);
-
-      TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
-      for (; itSub1.More(); itSub1.Next()) {
-        TopoDS_Shape aValue1 = itSub1.Value();
-        TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
-        for (; itSub2.More(); itSub2.Next()) {
-          TopoDS_Shape aValue2 = itSub2.Value();
-          BRepAlgoAPI_Common BO (aValue1, aValue2);
-          if (!BO.IsDone()) {
-            StdFail_NotDone::Raise("Common operation can not be performed on the given shapes");
+  switch (aType) {
+  case BOOLEAN_COMMON:
+  case BOOLEAN_CUT:
+  case BOOLEAN_FUSE:
+  case BOOLEAN_SECTION:
+    {
+      Handle(GEOM_Function) aRefShape1 = aCI.GetShape1();
+      Handle(GEOM_Function) aRefShape2 = aCI.GetShape2();
+      TopoDS_Shape aShape1 = aRefShape1->GetValue();
+      TopoDS_Shape aShape2 = aRefShape2->GetValue();
+
+      if (!aShape1.IsNull() && !aShape2.IsNull()) {
+        // check arguments for Mantis issue 0021019
+        BRepCheck_Analyzer ana (aShape1, Standard_True);
+        if (!ana.IsValid())
+          StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
+        ana.Init(aShape2);
+        if (!ana.IsValid())
+          StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
+
+        aShape = performOperation (aShape1, aShape2, aType);
+
+        if (aShape.IsNull())
+          return 0;
+      }
+    }
+    break;
+  case BOOLEAN_COMMON_LIST:
+  case BOOLEAN_FUSE_LIST:
+    {
+      Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
+      const Standard_Integer nbShapes = aShapes->Length();
+      Standard_Integer i;
+      Handle(GEOM_Function) aRefShape;
+      TopoDS_Shape aShape2;
+      Standard_Integer aSimpleType =
+        (aType == BOOLEAN_FUSE_LIST ? BOOLEAN_FUSE : BOOLEAN_COMMON);
+
+      if (nbShapes > 0) {
+        aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(1));
+        aShape = aRefShape->GetValue();
+
+        if (!aShape.IsNull()) {
+          BRepCheck_Analyzer anAna (aShape, Standard_True);
+
+          if (!anAna.IsValid()) {
+            StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
           }
-          if (isCompound) {
-            TopoDS_Shape aStepResult = BO.Shape();
-
-            // check result of this step: if it is a compound (boolean operations
-            // allways return a compound), we add all sub-shapes of it.
-            // This allows to avoid adding empty compounds,
-            // resulting from COMMON on two non-intersecting shapes.
-            if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
-              TopoDS_Iterator aCompIter (aStepResult);
-              for (; aCompIter.More(); aCompIter.Next()) {
-                // add shape in a result
-                B.Add(C, aCompIter.Value());
-              }
+
+          for (i = 2; i <= nbShapes; i++) {
+            aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(i));
+            aShape2 = aRefShape->GetValue();
+            anAna.Init(aShape2);
+
+            if (!anAna.IsValid()) {
+              StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
             }
-            else {
-              // add shape in a result
-              B.Add(C, aStepResult);
+
+            aShape = performOperation (aShape, aShape2, aSimpleType);
+
+            if (aShape.IsNull()) {
+              return 0;
             }
           }
-          else
-            aShape = BO.Shape();
         }
       }
+    }
+    break;
+  case BOOLEAN_CUT_LIST:
+    {
+      Handle(GEOM_Function) aRefObject = aCI.GetShape1();
 
-      if (isCompound) {
-        /*
-        TopTools_ListOfShape listShapeC;
-        GEOMUtils::AddSimpleShapes(C, listShapeC);
-        TopTools_ListIteratorOfListOfShape itSubC (listShapeC);
-        bool isOnlySolids = true;
-        for (; itSubC.More(); itSubC.Next()) {
-          TopoDS_Shape aValueC = itSubC.Value();
-          if (aValueC.ShapeType() != TopAbs_SOLID) isOnlySolids = false;
+      aShape = aRefObject->GetValue();
+
+      if (!aShape.IsNull()) {
+        // check arguments for Mantis issue 0021019
+        BRepCheck_Analyzer anAna (aShape, Standard_True);
+
+        if (!anAna.IsValid()) {
+          StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
         }
-        if (isOnlySolids)
-          aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion());
-        else
-          aShape = C;
-        */
 
-        // As GlueFaces has been improved to keep all kind of shapes
-        TopExp_Explorer anExp (C, TopAbs_VERTEX);
-        if (anExp.More())
-          aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
-        else
-          aShape = C;
+        Handle(TColStd_HSequenceOfTransient) aTools = aCI.GetShapes();
+        const Standard_Integer nbShapes = aTools->Length();
+        Standard_Integer i;
+        Handle(GEOM_Function) aRefTool;
+        TopoDS_Shape aTool;
+
+        for (i = 1; i <= nbShapes; i++) {
+          aRefTool = Handle(GEOM_Function)::DownCast(aTools->Value(i));
+          aTool = aRefTool->GetValue();
+          anAna.Init(aTool);
+
+          if (!anAna.IsValid()) {
+            StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
+          }
+
+          aShape = performOperation (aShape, aTool, BOOLEAN_CUT);
+
+          if (aShape.IsNull()) {
+            return 0;
+          }
+        }
       }
     }
+    break;
+  default:
+    break;
+  }
 
-    // perform CUT operation
-    else if (aType == BOOLEAN_CUT) {
-      BRep_Builder B;
-      TopoDS_Compound C;
-      B.MakeCompound(C);
-
-      TopTools_ListOfShape listShapes, listTools;
-      GEOMUtils::AddSimpleShapes(aShape1, listShapes);
-      GEOMUtils::AddSimpleShapes(aShape2, listTools);
-
-      Standard_Boolean isCompound = (listShapes.Extent() > 1);
-
-      TopTools_ListIteratorOfListOfShape itSub1 (listShapes);
-      for (; itSub1.More(); itSub1.Next()) {
-        TopoDS_Shape aCut = itSub1.Value();
-        // tools
-        TopTools_ListIteratorOfListOfShape itSub2 (listTools);
-        for (; itSub2.More(); itSub2.Next()) {
-          TopoDS_Shape aTool = itSub2.Value();
-          BRepAlgoAPI_Cut BO (aCut, aTool);
-          if (!BO.IsDone()) {
-            StdFail_NotDone::Raise("Cut operation can not be performed on the given shapes");
-          }
-          aCut = BO.Shape();
+  aFunction->SetValue(aShape);
+
+  log.SetTouched(Label());
+
+  return 1;
+}
+
+//=======================================================================
+//function : performOperation
+//purpose  :
+//=======================================================================
+TopoDS_Shape GEOMImpl_BooleanDriver::performOperation
+                               (const TopoDS_Shape theShape1,
+                                const TopoDS_Shape theShape2,
+                                const Standard_Integer theType)const
+{
+  TopoDS_Shape aShape;
+
+  // perform COMMON operation
+  if (theType == BOOLEAN_COMMON) {
+    BRep_Builder B;
+    TopoDS_Compound C;
+    B.MakeCompound(C);
+
+    TopTools_ListOfShape listShape1, listShape2;
+    GEOMUtils::AddSimpleShapes(theShape1, listShape1);
+    GEOMUtils::AddSimpleShapes(theShape2, listShape2);
+
+    Standard_Boolean isCompound =
+      (listShape1.Extent() > 1 || listShape2.Extent() > 1);
+
+    TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
+    for (; itSub1.More(); itSub1.Next()) {
+      TopoDS_Shape aValue1 = itSub1.Value();
+      TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
+      for (; itSub2.More(); itSub2.Next()) {
+        TopoDS_Shape aValue2 = itSub2.Value();
+        BRepAlgoAPI_Common BO (aValue1, aValue2);
+        if (!BO.IsDone()) {
+          StdFail_NotDone::Raise("Common operation can not be performed on the given shapes");
         }
         if (isCompound) {
+          TopoDS_Shape aStepResult = BO.Shape();
+
           // check result of this step: if it is a compound (boolean operations
           // allways return a compound), we add all sub-shapes of it.
           // This allows to avoid adding empty compounds,
-          // resulting from CUT of parts
-          if (aCut.ShapeType() == TopAbs_COMPOUND) {
-            TopoDS_Iterator aCompIter (aCut);
+          // resulting from COMMON on two non-intersecting shapes.
+          if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
+            TopoDS_Iterator aCompIter (aStepResult);
             for (; aCompIter.More(); aCompIter.Next()) {
               // add shape in a result
               B.Add(C, aCompIter.Value());
@@ -212,200 +253,163 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const
           }
           else {
             // add shape in a result
-            B.Add(C, aCut);
+            B.Add(C, aStepResult);
           }
         }
         else
-          aShape = aCut;
+          aShape = BO.Shape();
       }
+    }
 
-      if (isCompound) {
-        /*
-        TopTools_ListOfShape listShapeC;
-        GEOMUtils::AddSimpleShapes(C, listShapeC);
-        TopTools_ListIteratorOfListOfShape itSubC (listShapeC);
-        bool isOnlySolids = true;
-        for (; itSubC.More(); itSubC.Next()) {
-          TopoDS_Shape aValueC = itSubC.Value();
-          if (aValueC.ShapeType() != TopAbs_SOLID) isOnlySolids = false;
-        }
-        if (isOnlySolids)
-          aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion());
-        else
-          aShape = C;
-        */
-
-        // As GlueFaces has been improved to keep all kind of shapes
-        TopExp_Explorer anExp (C, TopAbs_VERTEX);
-        if (anExp.More())
-          aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
-        else
-          aShape = C;
-      }
+    if (isCompound) {
+      // As GlueFaces has been improved to keep all kind of shapes
+      TopExp_Explorer anExp (C, TopAbs_VERTEX);
+      if (anExp.More())
+        aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
+      else
+        aShape = C;
     }
+  }
 
-    // perform FUSE operation
-    else if (aType == BOOLEAN_FUSE) {
-      /* Fix for NPAL15379: refused
-      // Check arguments
-      TopTools_ListOfShape listShape1, listShape2;
-      GEOMUtils::AddSimpleShapes(aShape1, listShape1);
-      GEOMUtils::AddSimpleShapes(aShape2, listShape2);
-
-      Standard_Boolean isIntersect = Standard_False;
-
-      if (listShape1.Extent() > 1 && !isIntersect) {
-        // check intersections inside the first compound
-        TopTools_ListIteratorOfListOfShape it1 (listShape1);
-        for (; it1.More() && !isIntersect; it1.Next()) {
-          TopoDS_Shape aValue1 = it1.Value();
-          TopTools_ListIteratorOfListOfShape it2 (listShape1);
-          for (; it2.More() && !isIntersect; it2.Next()) {
-            TopoDS_Shape aValue2 = it2.Value();
-            if (aValue2 != aValue1) {
-              BRepAlgoAPI_Section BO (aValue1, aValue2);
-              if (BO.IsDone()) {
-                TopoDS_Shape aSect = BO.Shape();
-                TopExp_Explorer anExp (aSect, TopAbs_EDGE);
-                if (anExp.More()) {
-                  isIntersect = Standard_True;
-                }
-              }
-            }
-          }
+  // perform CUT operation
+  else if (theType == BOOLEAN_CUT) {
+    BRep_Builder B;
+    TopoDS_Compound C;
+    B.MakeCompound(C);
+
+    TopTools_ListOfShape listShapes, listTools;
+    GEOMUtils::AddSimpleShapes(theShape1, listShapes);
+    GEOMUtils::AddSimpleShapes(theShape2, listTools);
+
+    Standard_Boolean isCompound = (listShapes.Extent() > 1);
+
+    TopTools_ListIteratorOfListOfShape itSub1 (listShapes);
+    for (; itSub1.More(); itSub1.Next()) {
+      TopoDS_Shape aCut = itSub1.Value();
+      // tools
+      TopTools_ListIteratorOfListOfShape itSub2 (listTools);
+      for (; itSub2.More(); itSub2.Next()) {
+        TopoDS_Shape aTool = itSub2.Value();
+        BRepAlgoAPI_Cut BO (aCut, aTool);
+        if (!BO.IsDone()) {
+          StdFail_NotDone::Raise("Cut operation can not be performed on the given shapes");
         }
+        aCut = BO.Shape();
       }
-
-      if (listShape2.Extent() > 1 && !isIntersect) {
-        // check intersections inside the second compound
-        TopTools_ListIteratorOfListOfShape it1 (listShape2);
-        for (; it1.More() && !isIntersect; it1.Next()) {
-          TopoDS_Shape aValue1 = it1.Value();
-          TopTools_ListIteratorOfListOfShape it2 (listShape2);
-          for (; it2.More() && !isIntersect; it2.Next()) {
-            TopoDS_Shape aValue2 = it2.Value();
-            if (aValue2 != aValue1) {
-              BRepAlgoAPI_Section BO (aValue1, aValue2);
-              if (BO.IsDone()) {
-                TopoDS_Shape aSect = BO.Shape();
-                TopExp_Explorer anExp (aSect, TopAbs_EDGE);
-                if (anExp.More()) {
-                  isIntersect = Standard_True;
-                }
-              }
-            }
+      if (isCompound) {
+        // check result of this step: if it is a compound (boolean operations
+        // allways return a compound), we add all sub-shapes of it.
+        // This allows to avoid adding empty compounds,
+        // resulting from CUT of parts
+        if (aCut.ShapeType() == TopAbs_COMPOUND) {
+          TopoDS_Iterator aCompIter (aCut);
+          for (; aCompIter.More(); aCompIter.Next()) {
+            // add shape in a result
+            B.Add(C, aCompIter.Value());
           }
         }
-      }
-
-      if (isIntersect) {
-        // have intersections inside compounds
-        // check intersections between compounds
-        TopTools_ListIteratorOfListOfShape it1 (listShape1);
-        for (; it1.More(); it1.Next()) {
-          TopoDS_Shape aValue1 = it1.Value();
-          TopTools_ListIteratorOfListOfShape it2 (listShape2);
-          for (; it2.More(); it2.Next()) {
-            TopoDS_Shape aValue2 = it2.Value();
-            if (aValue2 != aValue1) {
-              BRepAlgoAPI_Section BO (aValue1, aValue2);
-              if (BO.IsDone()) {
-                TopoDS_Shape aSect = BO.Shape();
-                TopExp_Explorer anExp (aSect, TopAbs_EDGE);
-                if (anExp.More()) {
-                  StdFail_NotDone::Raise("Bad argument for Fuse: compound with intersecting sub-shapes");
-                }
-              }
-            }
-          }
+        else {
+          // add shape in a result
+          B.Add(C, aCut);
         }
       }
-      */
+      else
+        aShape = aCut;
+    }
 
-      // Perform
-      BRepAlgoAPI_Fuse BO (aShape1, aShape2);
-      if (!BO.IsDone()) {
-        StdFail_NotDone::Raise("Fuse operation can not be performed on the given shapes");
-      }
-      aShape = BO.Shape();
+    if (isCompound) {
+      // As GlueFaces has been improved to keep all kind of shapes
+      TopExp_Explorer anExp (C, TopAbs_VERTEX);
+      if (anExp.More())
+        aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
+      else
+        aShape = C;
     }
+  }
 
-    // perform SECTION operation
-    else if (aType == BOOLEAN_SECTION) {
-      BRep_Builder B;
-      TopoDS_Compound C;
-      B.MakeCompound(C);
-
-      TopTools_ListOfShape listShape1, listShape2;
-      GEOMUtils::AddSimpleShapes(aShape1, listShape1);
-      GEOMUtils::AddSimpleShapes(aShape2, listShape2);
-
-      Standard_Boolean isCompound =
-        (listShape1.Extent() > 1 || listShape2.Extent() > 1);
-
-      TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
-      for (; itSub1.More(); itSub1.Next()) {
-        TopoDS_Shape aValue1 = itSub1.Value();
-        TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
-        for (; itSub2.More(); itSub2.Next()) {
-          TopoDS_Shape aValue2 = itSub2.Value();
-          BRepAlgoAPI_Section BO (aValue1, aValue2, Standard_False);
-          // Set approximation to have an attached 3D BSpline geometry to each edge,
-          // where analytic curve is not possible. Without this flag in some cases
-          // we obtain BSpline curve of degree 1 (C0), which is slowly
-          // processed by some algorithms (Partition for example).
-          BO.Approximation(Standard_True);
-         //modified by NIZNHY-PKV Tue Oct 18 14:34:16 2011f
-         BO.ComputePCurveOn1(Standard_True);
-         BO.ComputePCurveOn2(Standard_True);
-         //modified by NIZNHY-PKV Tue Oct 18 14:34:18 2011t
-         
-          BO.Build();
-          if (!BO.IsDone()) {
-            StdFail_NotDone::Raise("Section operation can not be performed on the given shapes");
-          }
-          if (isCompound) {
-            TopoDS_Shape aStepResult = BO.Shape();
-
-            // check result of this step: if it is a compound (boolean operations
-            // allways return a compound), we add all sub-shapes of it.
-            // This allows to avoid adding empty compounds,
-            // resulting from SECTION on two non-intersecting shapes.
-            if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
-              TopoDS_Iterator aCompIter (aStepResult);
-              for (; aCompIter.More(); aCompIter.Next()) {
-                // add shape in a result
-                B.Add(C, aCompIter.Value());
-              }
-            }
-            else {
+  // perform FUSE operation
+  else if (theType == BOOLEAN_FUSE) {
+    // Perform
+    BRepAlgoAPI_Fuse BO (theShape1, theShape2);
+    if (!BO.IsDone()) {
+      StdFail_NotDone::Raise("Fuse operation can not be performed on the given shapes");
+    }
+    aShape = BO.Shape();
+  }
+
+  // perform SECTION operation
+  else if (theType == BOOLEAN_SECTION) {
+    BRep_Builder B;
+    TopoDS_Compound C;
+    B.MakeCompound(C);
+
+    TopTools_ListOfShape listShape1, listShape2;
+    GEOMUtils::AddSimpleShapes(theShape1, listShape1);
+    GEOMUtils::AddSimpleShapes(theShape2, listShape2);
+
+    Standard_Boolean isCompound =
+      (listShape1.Extent() > 1 || listShape2.Extent() > 1);
+
+    TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
+    for (; itSub1.More(); itSub1.Next()) {
+      TopoDS_Shape aValue1 = itSub1.Value();
+      TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
+      for (; itSub2.More(); itSub2.Next()) {
+        TopoDS_Shape aValue2 = itSub2.Value();
+        BRepAlgoAPI_Section BO (aValue1, aValue2, Standard_False);
+        // Set approximation to have an attached 3D BSpline geometry to each edge,
+        // where analytic curve is not possible. Without this flag in some cases
+        // we obtain BSpline curve of degree 1 (C0), which is slowly
+        // processed by some algorithms (Partition for example).
+        BO.Approximation(Standard_True);
+        //modified by NIZNHY-PKV Tue Oct 18 14:34:16 2011f
+        BO.ComputePCurveOn1(Standard_True);
+        BO.ComputePCurveOn2(Standard_True);
+        //modified by NIZNHY-PKV Tue Oct 18 14:34:18 2011t
+  
+        BO.Build();
+        if (!BO.IsDone()) {
+          StdFail_NotDone::Raise("Section operation can not be performed on the given shapes");
+        }
+        if (isCompound) {
+          TopoDS_Shape aStepResult = BO.Shape();
+
+          // check result of this step: if it is a compound (boolean operations
+          // allways return a compound), we add all sub-shapes of it.
+          // This allows to avoid adding empty compounds,
+          // resulting from SECTION on two non-intersecting shapes.
+          if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
+            TopoDS_Iterator aCompIter (aStepResult);
+            for (; aCompIter.More(); aCompIter.Next()) {
               // add shape in a result
-              B.Add(C, aStepResult);
+              B.Add(C, aCompIter.Value());
             }
           }
-          else
-            aShape = BO.Shape();
+          else {
+            // add shape in a result
+            B.Add(C, aStepResult);
+          }
         }
-      }
-
-      if (isCompound) {
-        //aShape = C;
-
-        // As GlueFaces has been improved to keep all kind of shapes
-        TopExp_Explorer anExp (C, TopAbs_VERTEX);
-        if (anExp.More())
-          aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
         else
-          aShape = C;
+          aShape = BO.Shape();
       }
     }
 
-    // UNKNOWN operation
-    else {
+    if (isCompound) {
+      // As GlueFaces has been improved to keep all kind of shapes
+      TopExp_Explorer anExp (C, TopAbs_VERTEX);
+      if (anExp.More())
+        aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
+      else
+        aShape = C;
     }
   }
 
-  if (aShape.IsNull()) return 0;
+  // UNKNOWN operation
+  else {
+  }
+
+  if (aShape.IsNull()) return aShape;
 
   // as boolean operations always produce compound, lets simplify it
   // for the case, if it contains only one sub-shape
@@ -413,7 +417,7 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const
   GEOMUtils::AddSimpleShapes(aShape, listShapeRes);
   if (listShapeRes.Extent() == 1) {
     aShape = listShapeRes.First();
-    if (aShape.IsNull()) return 0;
+    if (aShape.IsNull()) return aShape;
   }
 
   // 08.07.2008 skl for bug 19761 from Mantis
@@ -430,9 +434,6 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const
     if (!ana.IsValid())
       Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result");
   }
-  //if (!BRepAlgo::IsValid(aShape)) {
-  //  Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result");
-  //}
 
   // BEGIN: Mantis issue 0021060: always limit tolerance of BOP result
   // 1. Get shape parameters for comparison
@@ -506,24 +507,9 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const
   }
   // END: Mantis issue 0021060
 
-  //Alternative case to check shape result Mantis 0020604: EDF 1172
-/*  TopoDS_Iterator It (aShape, Standard_True, Standard_True);
-  int nbSubshapes=0;
-  for (; It.More(); It.Next())
-    nbSubshapes++;
-  if (!nbSubshapes)
-    Standard_ConstructionError::Raise("Boolean operation aborted : result object is empty compound");*/
-  //end of 0020604: EDF 1172
-  //! the changes temporary commented because of customer needs (see the same mantis bug)
-
-  aFunction->SetValue(aShape);
-
-  log.SetTouched(Label());
-
-  return 1;
+  return aShape;
 }
 
-
 //=======================================================================
 //function :  GEOMImpl_BooleanDriver_Type_
 //purpose  :
index 80e57116ca5964635c2df8bd9177285c596cd553..6bc1af7f20322cca728af8b0fed8a00d35239b1a 100644 (file)
 #include <Handle_TFunction_Driver.hxx>
 #endif
 
+#ifndef _TopoDS_Shape_HeaderFile
+#include <TopoDS_Shape.hxx>
+#endif
+
+
 class Standard_Transient;
 class Handle_Standard_Type;
 class Handle(TFunction_Driver);
@@ -156,6 +161,12 @@ Standard_EXPORT const Handle(Standard_Type)& DynamicType() const  { return STAND
 Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)& AType) const { return (STANDARD_TYPE(GEOMImpl_BooleanDriver) == AType || TFunction_Driver::IsKind(AType)); } 
 
 
+private:
+
+  TopoDS_Shape performOperation(const TopoDS_Shape theShape1,
+                                const TopoDS_Shape theShape2,
+                                const Standard_Integer theType) const;
+
 };
 
 #endif
index 54c24674085b2480d8b40bb9e81a45d0c8d2fe7d..46d5c8e482e02934abba0328d636d360243327c7 100644 (file)
 //NOTE: This is an intreface to a function for the Common, Cut and Fuse creation.
 //
 #include "GEOM_Function.hxx"
+#include "TColStd_HSequenceOfTransient.hxx"
 
 #define BOOL_ARG_SHAPE1  1
 #define BOOL_ARG_SHAPE2  2
+#define BOOL_ARG_SHAPES  3
 
 class GEOMImpl_IBoolean
 {
@@ -35,9 +37,13 @@ class GEOMImpl_IBoolean
 
   void SetShape1(Handle(GEOM_Function) theRef) { _func->SetReference(BOOL_ARG_SHAPE1, theRef); }
   void SetShape2(Handle(GEOM_Function) theRef) { _func->SetReference(BOOL_ARG_SHAPE2, theRef); }
+  void SetShapes(const Handle(TColStd_HSequenceOfTransient)& theShapes)
+  { _func->SetReferenceList(BOOL_ARG_SHAPES, theShapes); }
 
   Handle(GEOM_Function) GetShape1() { return _func->GetReference(BOOL_ARG_SHAPE1); }
   Handle(GEOM_Function) GetShape2() { return _func->GetReference(BOOL_ARG_SHAPE2); }
+  Handle(TColStd_HSequenceOfTransient) GetShapes()
+  { return _func->GetReferenceList(BOOL_ARG_SHAPES); }
 
  private:
 
index 3db2537ec97a5aa4b531d1876ce31e7165cbb0a5..a96b1810bf54d3cd0680e0ca0a9a851d3baf3508 100644 (file)
@@ -139,6 +139,185 @@ Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeBoolean (Handle(GEOM_Object
   return aBool;
 }
 
+//=============================================================================
+/*!
+ *  MakeFuseList
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeFuseList
+                  (const Handle(TColStd_HSequenceOfTransient)& theShapes)
+{
+  SetErrorCode(KO);
+
+  if (theShapes.IsNull()) return NULL;
+
+  //Add a new Boolean object
+  Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
+
+  //Add a new Boolean function
+  Handle(GEOM_Function) aFunction =
+    aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_FUSE_LIST);
+
+  if (aFunction.IsNull()) return NULL;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
+
+  GEOMImpl_IBoolean aCI (aFunction);
+
+  TCollection_AsciiString aDescription;
+  Handle(TColStd_HSequenceOfTransient) aShapesSeq =
+    getShapeFunctions(theShapes, aDescription);
+
+  if (aShapesSeq.IsNull()) return NULL;
+
+  aCI.SetShapes(aShapesSeq);
+
+  //Compute the Boolean value
+  try {
+#if OCC_VERSION_LARGE > 0x06010000
+    OCC_CATCH_SIGNALS;
+#endif
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("Boolean driver failed");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure) {
+    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+    SetErrorCode(aFail->GetMessageString());
+    return NULL;
+  }
+
+  //Make a Python command
+  GEOM::TPythonDump(aFunction) << aBool <<
+    " = geompy.MakeFuseList([" << aDescription.ToCString() << "])";
+
+  SetErrorCode(OK);
+  return aBool;
+}
+
+//=============================================================================
+/*!
+ *  MakeCommonList
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeCommonList
+                  (const Handle(TColStd_HSequenceOfTransient)& theShapes)
+{
+  SetErrorCode(KO);
+
+  if (theShapes.IsNull()) return NULL;
+
+  //Add a new Boolean object
+  Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
+
+  //Add a new Boolean function
+  Handle(GEOM_Function) aFunction =
+    aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_COMMON_LIST);
+
+  if (aFunction.IsNull()) return NULL;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
+
+  GEOMImpl_IBoolean aCI (aFunction);
+
+  TCollection_AsciiString aDescription;
+  Handle(TColStd_HSequenceOfTransient) aShapesSeq =
+    getShapeFunctions(theShapes, aDescription);
+
+  if (aShapesSeq.IsNull()) return NULL;
+
+  aCI.SetShapes(aShapesSeq);
+
+  //Compute the Boolean value
+  try {
+#if OCC_VERSION_LARGE > 0x06010000
+    OCC_CATCH_SIGNALS;
+#endif
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("Boolean driver failed");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure) {
+    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+    SetErrorCode(aFail->GetMessageString());
+    return NULL;
+  }
+
+  //Make a Python command
+  GEOM::TPythonDump(aFunction) << aBool <<
+    " = geompy.MakeCommonList([" << aDescription.ToCString() << "])";
+
+  SetErrorCode(OK);
+  return aBool;
+}
+
+//=============================================================================
+/*!
+ *  MakeCutList
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeCutList
+                  (Handle(GEOM_Object) theMainShape,
+                   const Handle(TColStd_HSequenceOfTransient)& theShapes)
+{
+  SetErrorCode(KO);
+
+  if (theShapes.IsNull()) return NULL;
+
+  //Add a new Boolean object
+  Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
+
+  //Add a new Boolean function
+  Handle(GEOM_Function) aFunction =
+    aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_CUT_LIST);
+
+  if (aFunction.IsNull()) return NULL;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
+
+  GEOMImpl_IBoolean aCI (aFunction);
+  Handle(GEOM_Function) aMainRef = theMainShape->GetLastFunction();
+
+  if (aMainRef.IsNull()) return NULL;
+
+  TCollection_AsciiString aDescription;
+  Handle(TColStd_HSequenceOfTransient) aShapesSeq =
+    getShapeFunctions(theShapes, aDescription);
+
+  if (aShapesSeq.IsNull()) return NULL;
+
+  aCI.SetShape1(aMainRef);
+  aCI.SetShapes(aShapesSeq);
+
+  //Compute the Boolean value
+  try {
+#if OCC_VERSION_LARGE > 0x06010000
+    OCC_CATCH_SIGNALS;
+#endif
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("Boolean driver failed");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure) {
+    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+    SetErrorCode(aFail->GetMessageString());
+    return NULL;
+  }
+
+  //Make a Python command
+  GEOM::TPythonDump(aFunction) << aBool << " = geompy.MakeCutList("
+    << theMainShape << ", [" << aDescription.ToCString() << "])";
+
+  SetErrorCode(OK);
+  return aBool;
+}
+
 //=============================================================================
 /*!
  *  MakePartition
@@ -173,85 +352,47 @@ Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakePartition
 
   GEOMImpl_IPartition aCI (aFunction);
 
-  Handle(TColStd_HSequenceOfTransient) aShapesSeq  = new TColStd_HSequenceOfTransient;
-  Handle(TColStd_HSequenceOfTransient) aToolsSeq   = new TColStd_HSequenceOfTransient;
-  Handle(TColStd_HSequenceOfTransient) aKeepInsSeq = new TColStd_HSequenceOfTransient;
-  Handle(TColStd_HSequenceOfTransient) aRemInsSeq  = new TColStd_HSequenceOfTransient;
-
-  Standard_Integer ind, aLen;
-  TCollection_AsciiString anEntry;
+  Handle(TColStd_HSequenceOfTransient) aShapesSeq;
+  Handle(TColStd_HSequenceOfTransient) aToolsSeq;
+  Handle(TColStd_HSequenceOfTransient) aKeepInsSeq;
+  Handle(TColStd_HSequenceOfTransient) aRemInsSeq;
   TCollection_AsciiString aShapesDescr, aToolsDescr, aKeepInsDescr, aRemoveInsDescr;
 
   // Shapes
-  aLen = theShapes->Length();
-  for (ind = 1; ind <= aLen; ind++) {
-    Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theShapes->Value(ind));
-    Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
-    if (aRefSh.IsNull()) {
-      SetErrorCode("NULL shape for Partition");
-      return NULL;
-    }
-    aShapesSeq->Append(aRefSh);
+  aShapesSeq = getShapeFunctions(theShapes, aShapesDescr);
 
-    // For Python command
-    TDF_Tool::Entry(anObj->GetEntry(), anEntry);
-    if (ind > 1) aShapesDescr += ", ";
-    aShapesDescr += anEntry;
+  if (aShapesSeq.IsNull()) {
+    SetErrorCode("NULL shape for Partition");
+    return NULL;
   }
-  aCI.SetShapes(aShapesSeq);
 
   // Tools
-  aLen = theTools->Length();
-  for (ind = 1; ind <= aLen; ind++) {
-    Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theTools->Value(ind));
-    Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
-    if (aRefSh.IsNull()) {
-      SetErrorCode("NULL tool shape for Partition");
-      return NULL;
-    }
-    aToolsSeq->Append(aRefSh);
+  aToolsSeq = getShapeFunctions(theTools, aToolsDescr);
 
-    // For Python command
-    TDF_Tool::Entry(anObj->GetEntry(), anEntry);
-    if (ind > 1) aToolsDescr += ", ";
-    aToolsDescr += anEntry;
+  if (aToolsSeq.IsNull()) {
+    SetErrorCode("NULL tool shape for Partition");
+    return NULL;
   }
-  aCI.SetTools(aToolsSeq);
 
   // Keep Inside
-  aLen = theKeepIns->Length();
-  for (ind = 1; ind <= aLen; ind++) {
-    Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theKeepIns->Value(ind));
-    Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
-    if (aRefSh.IsNull()) {
-      SetErrorCode("NULL <keep inside> shape for Partition");
-      return NULL;
-    }
-    aKeepInsSeq->Append(aRefSh);
+  aKeepInsSeq = getShapeFunctions(theKeepIns, aKeepInsDescr);
 
-    // For Python command
-    TDF_Tool::Entry(anObj->GetEntry(), anEntry);
-    if (ind > 1) aKeepInsDescr += ", ";
-    aKeepInsDescr += anEntry;
+  if (aKeepInsSeq.IsNull()) {
+    SetErrorCode("NULL <keep inside> shape for Partition");
+    return NULL;
   }
-  aCI.SetKeepIns(aKeepInsSeq);
 
   // Remove Inside
-  aLen = theRemoveIns->Length();
-  for (ind = 1; ind <= aLen; ind++) {
-    Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theRemoveIns->Value(ind));
-    Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
-    if (aRefSh.IsNull()) {
-      SetErrorCode("NULL <remove inside> shape for Partition");
-      return NULL;
-    }
-    aRemInsSeq->Append(aRefSh);
+  aRemInsSeq  = getShapeFunctions(theRemoveIns, aRemoveInsDescr);
 
-    // For Python command
-    TDF_Tool::Entry(anObj->GetEntry(), anEntry);
-    if (ind > 1) aRemoveInsDescr += ", ";
-    aRemoveInsDescr += anEntry;
+  if (aRemInsSeq.IsNull()) {
+    SetErrorCode("NULL <remove inside> shape for Partition");
+    return NULL;
   }
+
+  aCI.SetShapes(aShapesSeq);
+  aCI.SetTools(aToolsSeq);
+  aCI.SetKeepIns(aKeepInsSeq);
   aCI.SetRemoveIns(aRemInsSeq);
 
   // Limit
@@ -370,3 +511,46 @@ Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeHalfPartition
   SetErrorCode(OK);
   return aPart;
 }
+
+//=============================================================================
+/*!
+ *  getShapeFunctions
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient)
+  GEOMImpl_IBooleanOperations::getShapeFunctions
+                  (const Handle(TColStd_HSequenceOfTransient)& theObjects,
+                         TCollection_AsciiString &theDescription)
+{
+  Handle(TColStd_HSequenceOfTransient) aResult =
+    new TColStd_HSequenceOfTransient;
+  Standard_Integer aNbObjects = theObjects->Length();
+  Standard_Integer i;
+  TCollection_AsciiString anEntry;
+  Handle(GEOM_Object) anObj;
+  Handle(GEOM_Function) aRefObj;
+
+  // Shapes
+  for (i = 1; i <= aNbObjects; i++) {
+    anObj = Handle(GEOM_Object)::DownCast(theObjects->Value(i));
+    aRefObj = anObj->GetLastFunction();
+
+    if (aRefObj.IsNull()) {
+      aResult.Nullify();
+      break;
+    }
+
+    aResult->Append(aRefObj);
+
+    // For Python command
+    TDF_Tool::Entry(anObj->GetEntry(), anEntry);
+
+    if (i > 1) {
+      theDescription += ", ";
+    }
+
+    theDescription += anEntry;
+  }
+
+  return aResult;
+}
index ff93dcc8983c7e307294827778751b79139f6dde..c1c492c478a68c2b77ab74b444272555391ca053 100644 (file)
@@ -40,6 +40,16 @@ class GEOMImpl_IBooleanOperations : public GEOM_IOperations {
                                                    Handle(GEOM_Object) theShape2,
                                                    Standard_Integer    theOp);
 
+  Standard_EXPORT Handle(GEOM_Object) MakeFuseList
+                  (const Handle(TColStd_HSequenceOfTransient)& theShapes);
+
+  Standard_EXPORT Handle(GEOM_Object) MakeCommonList
+                  (const Handle(TColStd_HSequenceOfTransient)& theShapes);
+
+  Standard_EXPORT Handle(GEOM_Object) MakeCutList
+                  (Handle(GEOM_Object) theMainShape,
+                   const Handle(TColStd_HSequenceOfTransient)& theShapes);
+
   Standard_EXPORT Handle(GEOM_Object) MakePartition
                   (const Handle(TColStd_HSequenceOfTransient)& theShapes,
                    const Handle(TColStd_HSequenceOfTransient)& theTools,
@@ -53,6 +63,13 @@ class GEOMImpl_IBooleanOperations : public GEOM_IOperations {
 
   Standard_EXPORT Handle(GEOM_Object) MakeHalfPartition (Handle(GEOM_Object) theShape,
                                                          Handle(GEOM_Object) thePlane);
+
+private:
+
+  Handle(TColStd_HSequenceOfTransient) getShapeFunctions
+                  (const Handle(TColStd_HSequenceOfTransient)& theObjects,
+                         TCollection_AsciiString &theDescription);
+
 };
 
 #endif
index 8f85c2ac434c98e95e75f2ef64a0bba78c9f42e9..b00671937b6d60b83dc092e4d51177d9d801cc05 100755 (executable)
 #define THRUSECTIONS_RULED 1
 #define THRUSECTIONS_SMOOTHED 2
 
-#define BOOLEAN_COMMON  1
-#define BOOLEAN_CUT     2
-#define BOOLEAN_FUSE    3
-#define BOOLEAN_SECTION 4
+#define BOOLEAN_COMMON      1
+#define BOOLEAN_CUT         2
+#define BOOLEAN_FUSE        3
+#define BOOLEAN_SECTION     4
+#define BOOLEAN_COMMON_LIST 5
+#define BOOLEAN_CUT_LIST    6
+#define BOOLEAN_FUSE_LIST   7
 
 #define PARTITION_PARTITION 1
 #define PARTITION_HALF      2
index 6afade797143a2d02cfc0e3a1f842a26b66f25fb..2cad84b5dbafc9eb51e5c4fe4f1aa46e5d0e7cac 100644 (file)
@@ -85,6 +85,100 @@ GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeBoolean
   return GetObject(anObject);
 }
 
+//=============================================================================
+/*!
+ *  MakeFuseList
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeFuseList
+                                    (const GEOM::ListOfGO& theShapes)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  Handle(TColStd_HSequenceOfTransient) aShapes =
+    GetListOfObjectsImpl(theShapes);
+
+  if (aShapes.IsNull()) {
+    return aGEOMObject._retn();
+  }
+
+  // Make fusion
+  Handle(GEOM_Object) anObject = GetOperations()->MakeFuseList(aShapes);
+
+  if (!GetOperations()->IsDone() || anObject.IsNull())
+    return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  MakeCommonList
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeCommonList
+                                    (const GEOM::ListOfGO& theShapes)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  Handle(TColStd_HSequenceOfTransient) aShapes =
+    GetListOfObjectsImpl(theShapes);
+
+  if (aShapes.IsNull()) {
+    return aGEOMObject._retn();
+  }
+
+  // Make fusion
+  Handle(GEOM_Object) anObject = GetOperations()->MakeCommonList(aShapes);
+
+  if (!GetOperations()->IsDone() || anObject.IsNull())
+    return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  MakeCutList
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeCutList
+                                    (GEOM::GEOM_Object_ptr theMainShape,
+                                     const GEOM::ListOfGO& theShapes)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  Handle(GEOM_Object) aMainShape = GetObjectImpl(theMainShape);
+
+  if (aMainShape.IsNull()) {
+    return aGEOMObject._retn();
+  }
+
+  Handle(TColStd_HSequenceOfTransient) aShapes =
+    GetListOfObjectsImpl(theShapes);
+
+  if (aShapes.IsNull()) {
+    return aGEOMObject._retn();
+  }
+
+  // Make fusion
+  Handle(GEOM_Object) anObject = GetOperations()->MakeCutList(aMainShape, aShapes);
+
+  if (!GetOperations()->IsDone() || anObject.IsNull())
+    return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
 //=============================================================================
 /*!
  *  MakePartition
@@ -105,47 +199,20 @@ GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakePartition
   //Set a not done flag
   GetOperations()->SetNotDone();
 
-  int ind, aLen;
-  Handle(TColStd_HSequenceOfTransient) aShapes  = new TColStd_HSequenceOfTransient;
-  Handle(TColStd_HSequenceOfTransient) aTools   = new TColStd_HSequenceOfTransient;
-  Handle(TColStd_HSequenceOfTransient) aKeepIns = new TColStd_HSequenceOfTransient;
-  Handle(TColStd_HSequenceOfTransient) aRemIns  = new TColStd_HSequenceOfTransient;
+  Handle(TColStd_HSequenceOfTransient) aShapes  = GetListOfObjectsImpl(theShapes);
+  Handle(TColStd_HSequenceOfTransient) aTools   = GetListOfObjectsImpl(theTools);
+  Handle(TColStd_HSequenceOfTransient) aKeepIns = GetListOfObjectsImpl(theKeepIns);
+  Handle(TColStd_HSequenceOfTransient) aRemIns  = GetListOfObjectsImpl(theRemoveIns);
   Handle(TColStd_HArray1OfInteger) aMaterials;
 
-  //Get the shapes
-  aLen = theShapes.length();
-  for (ind = 0; ind < aLen; ind++) {
-    Handle(GEOM_Object) aSh = GetObjectImpl(theShapes[ind]);
-    if (aSh.IsNull()) return aGEOMObject._retn();
-    aShapes->Append(aSh);
-  }
-
-  //Get the tools
-  aLen = theTools.length();
-  for (ind = 0; ind < aLen; ind++) {
-    Handle(GEOM_Object) aSh = GetObjectImpl(theTools[ind]);
-    if (aSh.IsNull()) return aGEOMObject._retn();
-    aTools->Append(aSh);
-  }
-
-  //Get the keep inside shapes
-  aLen = theKeepIns.length();
-  for (ind = 0; ind < aLen; ind++) {
-    Handle(GEOM_Object) aSh = GetObjectImpl(theKeepIns[ind]);
-    if (aSh.IsNull()) return aGEOMObject._retn();
-    aKeepIns->Append(aSh);
-  }
-
-  //Get the remove inside shapes
-  aLen = theRemoveIns.length();
-  for (ind = 0; ind < aLen; ind++) {
-    Handle(GEOM_Object) aSh = GetObjectImpl(theRemoveIns[ind]);
-    if (aSh.IsNull()) return aGEOMObject._retn();
-    aRemIns->Append(aSh);
+  if (aShapes.IsNull() || aTools.IsNull() ||
+      aKeepIns.IsNull() || aRemIns.IsNull()) {
+    return aGEOMObject._retn();
   }
 
   //Get the materials
-  aLen = theMaterials.length();
+  int ind;
+  int aLen = theMaterials.length();
   if ( aLen ) {
     aMaterials = new TColStd_HArray1OfInteger (1, aLen);
     for (ind = 0; ind < aLen; ind++) {
@@ -185,47 +252,20 @@ GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakePartitionNonSelfIntersected
   //Set a not done flag
   GetOperations()->SetNotDone();
 
-  int ind, aLen;
-  Handle(TColStd_HSequenceOfTransient) aShapes  = new TColStd_HSequenceOfTransient;
-  Handle(TColStd_HSequenceOfTransient) aTools   = new TColStd_HSequenceOfTransient;
-  Handle(TColStd_HSequenceOfTransient) aKeepIns = new TColStd_HSequenceOfTransient;
-  Handle(TColStd_HSequenceOfTransient) aRemIns  = new TColStd_HSequenceOfTransient;
+  Handle(TColStd_HSequenceOfTransient) aShapes  = GetListOfObjectsImpl(theShapes);
+  Handle(TColStd_HSequenceOfTransient) aTools   = GetListOfObjectsImpl(theTools);
+  Handle(TColStd_HSequenceOfTransient) aKeepIns = GetListOfObjectsImpl(theKeepIns);
+  Handle(TColStd_HSequenceOfTransient) aRemIns  = GetListOfObjectsImpl(theRemoveIns);
   Handle(TColStd_HArray1OfInteger) aMaterials;
 
-  //Get the shapes
-  aLen = theShapes.length();
-  for (ind = 0; ind < aLen; ind++) {
-    Handle(GEOM_Object) aSh = GetObjectImpl(theShapes[ind]);
-    if (aSh.IsNull()) return aGEOMObject._retn();
-    aShapes->Append(aSh);
-  }
-
-  //Get the tools
-  aLen = theTools.length();
-  for (ind = 0; ind < aLen; ind++) {
-    Handle(GEOM_Object) aSh = GetObjectImpl(theTools[ind]);
-    if (aSh.IsNull()) return aGEOMObject._retn();
-    aTools->Append(aSh);
-  }
-
-  //Get the keep inside shapes
-  aLen = theKeepIns.length();
-  for (ind = 0; ind < aLen; ind++) {
-    Handle(GEOM_Object) aSh = GetObjectImpl(theKeepIns[ind]);
-    if (aSh.IsNull()) return aGEOMObject._retn();
-    aKeepIns->Append(aSh);
-  }
-
-  //Get the remove inside shapes
-  aLen = theRemoveIns.length();
-  for (ind = 0; ind < aLen; ind++) {
-    Handle(GEOM_Object) aSh = GetObjectImpl(theRemoveIns[ind]);
-    if (aSh.IsNull()) return aGEOMObject._retn();
-    aRemIns->Append(aSh);
+  if (aShapes.IsNull() || aTools.IsNull() ||
+      aKeepIns.IsNull() || aRemIns.IsNull()) {
+    return aGEOMObject._retn();
   }
 
   //Get the materials
-  aLen = theMaterials.length();
+  int ind;
+  int aLen = theMaterials.length();
   if ( aLen ) {
     aMaterials = new TColStd_HArray1OfInteger (1, aLen);
     for (ind = 0; ind < aLen; ind++) {
index 81885d879f12302ee4638ee55f1b1b34a8393232..3150fcd56ac3fadb97087784d2d0b238d572fd2b 100644 (file)
@@ -46,6 +46,13 @@ class GEOM_I_EXPORT GEOM_IBooleanOperations_i :
                                     GEOM::GEOM_Object_ptr theShape2,
                                     CORBA::Long           theOp);
 
+  GEOM::GEOM_Object_ptr MakeFuseList (const GEOM::ListOfGO& theShapes);
+
+  GEOM::GEOM_Object_ptr MakeCommonList (const GEOM::ListOfGO& theShapes);
+
+  GEOM::GEOM_Object_ptr MakeCutList (GEOM::GEOM_Object_ptr theMainShape,
+                                     const GEOM::ListOfGO& theShapes);
+
   GEOM::GEOM_Object_ptr MakePartition (const GEOM::ListOfGO&   theShapes,
                                       const GEOM::ListOfGO&   theTools,
                                       const GEOM::ListOfGO&   theKeepInside,
index 090bf8e823158d269b35de4ee3de7731089cf00b..059e751ae5ebb4face84d2e3232ee43adcc22f0c 100644 (file)
@@ -160,6 +160,34 @@ Handle(GEOM_Object) GEOM_IOperations_i::GetObjectImpl(GEOM::GEOM_Object_ptr theO
   return anImpl;
 }
 
+//=============================================================================
+/*!
+ *  GetListOfObjectsImpl
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOM_IOperations_i::GetListOfObjectsImpl
+              (const GEOM::ListOfGO& theObjects)
+{
+  Handle(TColStd_HSequenceOfTransient) aResult =
+    new TColStd_HSequenceOfTransient;
+
+  int i;
+  int aNbObj = theObjects.length();
+
+  for (i = 0; i < aNbObj; i++) {
+    Handle(GEOM_Object) anObj = GetObjectImpl(theObjects[i]);
+
+    if (anObj.IsNull()) {
+      aResult.Nullify();
+      break;
+    }
+
+    aResult->Append(anObj);
+  }
+
+  return aResult;
+}
+
 //=============================================================================
 /*!
  *  UpdateGUIForObject
index 8fa579842295c01ff2e7fbb459ea9fdf571e340c..4d8757cd8331ae99210df05ab7e86f3186862b98 100644 (file)
@@ -50,6 +50,9 @@ class GEOM_I_EXPORT GEOM_IOperations_i : public virtual POA_GEOM::GEOM_IOperatio
   virtual GEOM::GEOM_Object_ptr GetObject(Handle(GEOM_Object) theObject);
   virtual Handle(GEOM_Object) GetObjectImpl(GEOM::GEOM_Object_ptr theObject);
 
+  virtual Handle(TColStd_HSequenceOfTransient)
+               GetListOfObjectsImpl(const GEOM::ListOfGO& theObjects);
+
   virtual void StartOperation();
 
   virtual void FinishOperation();
index 8fa5964b568a2836251378ebadd7fe6cce660f7a..0a8ab0413dbb624c3bb8fe2a9cf5f0c1af59f859 100644 (file)
@@ -163,17 +163,29 @@ def TestOtherOperations (geompy, math):
   id_Orientation = geompy.addToStudy(Orientation, "OrientationChange")
 
   # MakeCommon, MakeCut, MakeFuse, MakeSection
+  p1 = geompy.MakeVertex(60, 120, 0)
+  p2 = geompy.MakeVertex( 0,  0, 0)
+  v = geompy.MakeVector(p1, p2)
+  height = 90
+  radius1 = 50
+  cylinder = geompy.MakeCylinder(p1, v, radius1, height)
   Sphere = geompy.MakeSphereR(100)
 
-  Common  = geompy.MakeCommon (Box, Sphere)
-  Cut     = geompy.MakeCut    (Box, Sphere)
-  Fuse    = geompy.MakeFuse   (Box, Sphere)
-  Section = geompy.MakeSection(Box, Sphere)
-
-  id_Common  = geompy.addToStudy(Common,  "Common")
-  id_Cut     = geompy.addToStudy(Cut,     "Cut")
-  id_Fuse    = geompy.addToStudy(Fuse,    "Fuse")
+  Common1 = geompy.MakeCommon    (Box, Sphere)
+  Cut1    = geompy.MakeCut       (Box, Sphere)
+  Fuse1   = geompy.MakeFuse      (Box, Sphere)
+  Section = geompy.MakeSection   (Box, Sphere)
+  Common2 = geompy.MakeCommonList([Box, Sphere, cylinder])
+  Cut2    = geompy.MakeCutList   (Box, [Sphere, cylinder])
+  Fuse2   = geompy.MakeFuseList  ([Box, Sphere, cylinder])
+
+  id_Common1 = geompy.addToStudy(Common1,  "Common_1")
+  id_Cut1    = geompy.addToStudy(Cut1,     "Cut_1")
+  id_Fuse1   = geompy.addToStudy(Fuse1,    "Fuse_1")
   id_Section = geompy.addToStudy(Section, "Section")
+  id_Common2 = geompy.addToStudy(Common2,  "Common_2")
+  id_Cut2    = geompy.addToStudy(Cut2,     "Cut_2")
+  id_Fuse2   = geompy.addToStudy(Fuse2,    "Fuse_2")
 
   # Partition
   p100 = geompy.MakeVertex(100, 100, 100)
@@ -713,10 +725,9 @@ def TestOtherOperations (geompy, math):
   sph2 = geompy.MakeSphere(50, 50, -50, 40)
   pcyl = geompy.MakeVertex(50, 50, -50)
   cyli = geompy.MakeCylinder(pcyl, vz, 40, 100)
-  fuse = geompy.MakeFuse(sph1, cyli)
-  sh_1 = geompy.MakeFuse(fuse, sph2)
+  sh_1 = geompy.MakeFuseList([sph1, cyli, sph2])
   # As after Fuse we have a compound, we need to obtain a solid from it
-  #shsh = geompy.SubShapeAll(fuse, geompy.ShapeType["SOLID"])
+  #shsh = geompy.SubShapeAll(sh_1, geompy.ShapeType["SOLID"])
   #sh_1 = shsh[0]
   geompy.addToStudy(sh_1, "sh_1")
 
index 6b9058dbd2c55686f242d8e5ff95d1f03f00cfc8..28dab6b5e21cdc6210fd83a0f90c10306d791cea 100644 (file)
@@ -6637,6 +6637,98 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
             # note: auto-publishing is done in self.MakeBoolean()
             return self.MakeBoolean(theShape1, theShape2, 4, theName)
 
+        ## Perform Fuse boolean operation on the list of shapes.
+        #  @param theShapesList Shapes to be fused.
+        #  @param theName Object name; when specified, this parameter is used
+        #         for result publication in the study. Otherwise, if automatic
+        #         publication is switched on, default value is used for result name.
+        #
+        #  @return New GEOM.GEOM_Object, containing the result shape.
+        #
+        #  @ref tui_fuse "Example 1"
+        #  \n @ref swig_MakeCommon "Example 2"
+        def MakeFuseList(self, theShapesList, theName=None):
+            """
+            Perform Fuse boolean operation on the list of shapes.
+
+            Parameters: 
+                theShapesList Shapes to be fused.
+                theName Object name; when specified, this parameter is used
+                        for result publication in the study. Otherwise, if automatic
+                        publication is switched on, default value is used for result name.
+
+            Returns:   
+                New GEOM.GEOM_Object, containing the result shape.
+            
+            """
+            # Example: see GEOM_TestOthers.py
+            anObj = self.BoolOp.MakeFuseList(theShapesList)
+            RaiseIfFailed("MakeFuseList", self.BoolOp)
+            self._autoPublish(anObj, theName, "fuse")
+            return anObj
+
+        ## Perform Common boolean operation on the list of shapes.
+        #  @param theShapesList Shapes for Common operation.
+        #  @param theName Object name; when specified, this parameter is used
+        #         for result publication in the study. Otherwise, if automatic
+        #         publication is switched on, default value is used for result name.
+        #
+        #  @return New GEOM.GEOM_Object, containing the result shape.
+        #
+        #  @ref tui_common "Example 1"
+        #  \n @ref swig_MakeCommon "Example 2"
+        def MakeCommonList(self, theShapesList, theName=None):
+            """
+            Perform Common boolean operation on the list of shapes.
+
+            Parameters: 
+                theShapesList Shapes for Common operation.
+                theName Object name; when specified, this parameter is used
+                        for result publication in the study. Otherwise, if automatic
+                        publication is switched on, default value is used for result name.
+
+            Returns:   
+                New GEOM.GEOM_Object, containing the result shape.
+            
+            """
+            # Example: see GEOM_TestOthers.py
+            anObj = self.BoolOp.MakeCommonList(theShapesList)
+            RaiseIfFailed("MakeCommonList", self.BoolOp)
+            self._autoPublish(anObj, theName, "common")
+            return anObj
+
+        ## Perform Cut boolean operation on one object and the list of tools.
+        #  @param theMainShape The object of the operation.
+        #  @param theShapesList The list of tools of the operation.
+        #  @param theName Object name; when specified, this parameter is used
+        #         for result publication in the study. Otherwise, if automatic
+        #         publication is switched on, default value is used for result name.
+        #
+        #  @return New GEOM.GEOM_Object, containing the result shape.
+        #
+        #  @ref tui_cut "Example 1"
+        #  \n @ref swig_MakeCommon "Example 2"
+        def MakeCutList(self, theMainShape, theShapesList, theName=None):
+            """
+            Perform Cut boolean operation on one object and the list of tools.
+
+            Parameters: 
+                theMainShape The object of the operation.
+                theShapesList The list of tools of the operation.
+                theName Object name; when specified, this parameter is used
+                        for result publication in the study. Otherwise, if automatic
+                        publication is switched on, default value is used for result name.
+
+            Returns:   
+                New GEOM.GEOM_Object, containing the result shape.
+            
+            """
+            # Example: see GEOM_TestOthers.py
+            anObj = self.BoolOp.MakeCutList(theMainShape, theShapesList)
+            RaiseIfFailed("MakeCutList", self.BoolOp)
+            self._autoPublish(anObj, theName, "cut")
+            return anObj
+
         # end of l3_boolean
         ## @}