]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
Mantis issue 0021703: [CEA 577] Boolean operations on groups.
authorjfa <jfa@opencascade.com>
Mon, 24 Sep 2012 11:54:41 +0000 (11:54 +0000)
committerjfa <jfa@opencascade.com>
Mon, 24 Sep 2012 11:54:41 +0000 (11:54 +0000)
21 files changed:
doc/salome/gui/GEOM/images/groups_cut_dlg.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/groups_intersect_dlg.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/groups_union_dlg.png [new file with mode: 0644]
doc/salome/gui/GEOM/input/tui_test_others.doc
doc/salome/gui/GEOM/input/tui_working_with_groups.doc
doc/salome/gui/GEOM/input/working_with_groups.doc
idl/GEOM_Gen.idl
src/GEOMGUI/GEOM_images.ts
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GeometryGUI.cxx
src/GEOMGUI/GeometryGUI_Operations.h
src/GEOMImpl/GEOMImpl_IGroupOperations.cxx
src/GEOMImpl/GEOMImpl_IGroupOperations.hxx
src/GEOM_I/GEOM_IGroupOperations_i.cc
src/GEOM_I/GEOM_IGroupOperations_i.hh
src/GEOM_SWIG/GEOM_TestOthers.py
src/GEOM_SWIG/geompyDC.py
src/GroupGUI/GroupGUI.cxx
src/GroupGUI/GroupGUI_BooleanDlg.cxx [new file with mode: 0644]
src/GroupGUI/GroupGUI_BooleanDlg.h [new file with mode: 0644]
src/GroupGUI/Makefile.am

diff --git a/doc/salome/gui/GEOM/images/groups_cut_dlg.png b/doc/salome/gui/GEOM/images/groups_cut_dlg.png
new file mode 100644 (file)
index 0000000..248eeba
Binary files /dev/null and b/doc/salome/gui/GEOM/images/groups_cut_dlg.png differ
diff --git a/doc/salome/gui/GEOM/images/groups_intersect_dlg.png b/doc/salome/gui/GEOM/images/groups_intersect_dlg.png
new file mode 100644 (file)
index 0000000..0109f67
Binary files /dev/null and b/doc/salome/gui/GEOM/images/groups_intersect_dlg.png differ
diff --git a/doc/salome/gui/GEOM/images/groups_union_dlg.png b/doc/salome/gui/GEOM/images/groups_union_dlg.png
new file mode 100644 (file)
index 0000000..9df9cd6
Binary files /dev/null and b/doc/salome/gui/GEOM/images/groups_union_dlg.png differ
index 2b1b44c7c108d889954405d7072155267000af3d..e89f8995785fd25352681be1541ebee094d81c6a 100644 (file)
@@ -79,6 +79,9 @@
 \anchor swig_UnionIDs
 \until print " ", ObjectID
 
+\anchor swig_bop_on_groups
+\until Box, Group_CL_2_4
+
 \anchor swig_GetType
 \until Type of elements
 
index e608a092358cf69fb4a42cb1fda76d45efd5e788..37813417c41ad96f5432df931976de9a0fc40326 100644 (file)
@@ -2,7 +2,9 @@
 
 \page tui_working_with_groups_page Working with Groups
 
-<br><h2>Creation of a group</h2>
+<br>
+\anchor tui_create_groups_anchor
+<h2>Creation of a group</h2>
 
 \code
 import geompy
@@ -42,6 +44,8 @@ gg.createAndDisplayGO(id_group1)
 salome.sg.updateObjBrowser(1)
 \endcode
 
+\anchor tui_edit_groups_anchor
+
 <br><h2>Adding an object to the group</h2>
 
 \code
@@ -107,4 +111,108 @@ gg.createAndDisplayGO(id_group1)
 salome.sg.updateObjBrowser(1) 
 \endcode
 
+<br>
+\anchor tui_union_groups_anchor
+<h2>Union Groups</h2>
+
+\code
+import geompy
+import salome
+
+# create a box and some groups of faces on it
+Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+Group_1 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_1, [13, 23])
+Group_2 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_2, [3, 27])
+Group_3 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_3, [33, 23])
+Group_4 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_4, [31, 27])
+
+# union groups
+Group_U_1_2 = geompy.UnionGroups(Group_1, Group_2)
+Group_UL_3_4 = geompy.UnionListOfGroups([Group_3, Group_4])
+
+# publish shapes
+geompy.addToStudy(Box_1, 'Box_1')
+geompy.addToStudyInFather(Box_1, Group_1, 'Group_1')
+geompy.addToStudyInFather(Box_1, Group_2, 'Group_2')
+geompy.addToStudyInFather(Box_1, Group_3, 'Group_3')
+geompy.addToStudyInFather(Box_1, Group_4, 'Group_4')
+geompy.addToStudyInFather(Box_1, Group_U_1_2, 'Group_U_1_2')
+geompy.addToStudyInFather(Box_1, Group_UL_3_4, 'Group_UL_3_4')
+salome.sg.updateObjBrowser(1) 
+\endcode
+
+<br>
+\anchor tui_intersect_groups_anchor
+<h2>Intersect Groups</h2>
+
+\code
+import geompy
+import salome
+
+# create a box and some groups of faces on it
+Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+Group_1 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_1, [13, 23])
+Group_2 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_2, [3, 27])
+Group_3 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_3, [33, 23])
+Group_4 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_4, [31, 27])
+
+# intersect groups
+Group_I_1_3 = geompy.IntersectGroups(Group_1, Group_3)
+Group_IL_1_3 = geompy.IntersectListOfGroups([Group_1, Group_3])
+
+# publish shapes
+geompy.addToStudy(Box_1, 'Box_1')
+geompy.addToStudyInFather(Box_1, Group_1, 'Group_1')
+geompy.addToStudyInFather(Box_1, Group_2, 'Group_2')
+geompy.addToStudyInFather(Box_1, Group_3, 'Group_3')
+geompy.addToStudyInFather(Box_1, Group_4, 'Group_4')
+geompy.addToStudyInFather(Box_1, Group_I_1_3, 'Group_I_1_3')
+geompy.addToStudyInFather(Box_1, Group_IL_1_3, 'Group_IL_1_3')
+salome.sg.updateObjBrowser(1) 
+
+\endcode
+
+<br>
+\anchor tui_cut_groups_anchor
+<h2>Cut Groups</h2>
+
+\code
+import geompy
+import salome
+
+# create a box and some groups of faces on it
+Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+Group_1 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_1, [13, 23])
+Group_2 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_2, [3, 27])
+Group_3 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_3, [33, 23])
+Group_4 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+geompy.UnionIDs(Group_4, [31, 27])
+
+# cut groups
+Group_C_2_4 = geompy.CutGroups(Group_2, Group_4)
+Group_CL_2_4 = geompy.CutListOfGroups([Group_2], [Group_4])
+
+# publish shapes
+geompy.addToStudy(Box_1, 'Box_1')
+geompy.addToStudyInFather(Box_1, Group_1, 'Group_1')
+geompy.addToStudyInFather(Box_1, Group_2, 'Group_2')
+geompy.addToStudyInFather(Box_1, Group_3, 'Group_3')
+geompy.addToStudyInFather(Box_1, Group_4, 'Group_4')
+geompy.addToStudyInFather(Box_1, Group_C_2_4, 'Group_C_2_4')
+geompy.addToStudyInFather(Box_1, Group_CL_2_4, 'Group_CL_2_4')
+salome.sg.updateObjBrowser(1) 
+
+\endcode
+
 */
index 07838d585bbb74f1f7217f1e0226074d3315fdee..a09865efa9a46bc1f19e8078c89cc51f64208aa8 100644 (file)
@@ -3,13 +3,25 @@
 \page work_with_groups_page Working with groups
 
 Creation and editing groups of sub-shapes of a geometrical object makes
-handling sub-shapes much easier. This functionality is available in OCC
-viewer only.
+handling sub-shapes much easier. Also some Boolean operations on
+groups are available.
 
-<br><h2>Create a group</h2>
+<ul>
+<li>\ref create_groups_anchor "Create a Group"</li>
+<li>\ref edit_groups_anchor "Edit a Group"</li>
+<li>\ref union_groups_anchor "Union Groups"</li>
+<li>\ref intersect_groups_anchor "Intersect Groups"</li>
+<li>\ref cut_groups_anchor "Cut Groups"</li>
+</ul>
+
+<br>
+\anchor create_groups_anchor
+<h2>Create a group</h2>
 
 \image html image56.png
 
+This functionality is available in OCC viewer only.
+
 To create a group of sub-shapes of a geometrical object in the main
 menu select <b>New entity > Group > Create</b>
 \n The following menu will appear:
@@ -72,19 +84,29 @@ ShapeType),</em> where MainShape is a shape for which the group is
 created, ShapeType is a type of shapes in the created group.
 \n <b>Arguments:</b> 1 Shape + Type of sub-shape.
 
+Our <b>TUI Scripts</b> provide you with useful examples of 
+\ref tui_create_groups_anchor "Create a Group" operation.
+
 <b>Example:</b>
 
 \image html image193.png "Groups on a cylinder"
 
-
-<br><h2>Edit a group</h2>
+<br>
+\anchor edit_groups_anchor
+<h2>Edit a group</h2>
 
 \image html image57.png
 
+This functionality is available in OCC viewer only.
+
 To \b Edit an existing group in the main menu select <b>New entity >
 Group > Edit</b>. This menu is designed in the same way as the
 <b>Create a group</b> menu.
 
+\n <b>Dialog Box:</b> 
+
+\image html editgroup.png
+
 \n The \b Result of the operation will be a \b GEOM_Object.
 
 \n <b>TUI Command:</b>
@@ -101,11 +123,80 @@ the sub-shape to be removed from the group.</li>
 
 \n <b>Arguments:</b> 1 Shape + its sub-shapes.
 
-\n <b>Dialog Box:</b> 
+Our <b>TUI Scripts</b> provide you with useful examples of 
+\ref tui_edit_groups_anchor "Edit a Group" operation.
 
-\image html editgroup.png
+<br>
+\anchor union_groups_anchor
+<h2>Union of groups</h2>
+
+This operation allows to create a new group in such a way that all
+sub-shapes that are present in the initial groups will be added to
+the new one.
+
+<em>To union groups:</em>
+<ol>
+<li>In the <b>New Entity</b> menu select the \b Group - <b>Union Groups</b> item.
+The following dialog box will appear:
+
+\image html groups_union_dlg.png
+
+In this dialog box you should specify the name of the resulting group
+and set of groups which will be united.
+</li>
+<li>Click the \b Apply or <b>Apply and Close</b> button to confirm creation of the group.</li>
+</ol>
+
+<b>See Also</b> a sample TUI Script of a 
+\ref tui_union_groups_anchor "Union of Groups" operation.
+
+<br>
+\anchor intersect_groups_anchor
+<h2>Intersection of groups</h2>
+
+This operation allows to create a new group in such a way that only
+sub-shapes that are present in all initial groups together are added to the
+new one.
+
+<em>To intersect groups:</em>
+<ol>
+<li>In the <b>New Entity</b> menu select the \b Group - <b>Intersect Groups</b> item.
+The following dialog box will appear:
+
+\image html groups_intersect_dlg.png
+
+In this dialog box you should specify the name of the resulting group
+and set of groups which will be intersected.
+</li>
+<li>Click the \b Apply or <b>Apply and Close</b> button to confirm creation of the group.</li>
+</ol>
+
+<b>See Also</b> a sample TUI Script of an  
+\ref tui_intersect_groups_anchor "Intersection of Groups" operation.
+
+<br>
+\anchor cut_groups_anchor
+<h2>Cut of groups</h2>
+
+This operation allows to create a new group in such a way that all
+sub-shapes that are present in the main groups but are absent in the
+tool groups are added to the new one.
+
+<em>To cut groups:</em>
+<ol>
+<li>In the <b>New Entity</b> menu select the \b Group - <b>Cut Groups</b> item.
+The following dialog box will appear:
+
+\image html groups_cut_dlg.png
+
+In this dialog box you should specify the name of the resulting group
+and groups which will be cut.
+</li>
+<li>Click the \b Apply or <b>Apply and Close</b> button to confirm creation of the
+group.</li>
+</ol>
 
 Our <b>TUI Scripts</b> provide you with useful examples of 
-\ref tui_working_with_groups_page "Working with Groups".
+\ref tui_cut_groups_anchor "Cut of Groups" operation.
 
 */
index be98cf9eb2b32e43f5b451f8459f42ff3ea35a04..e8c5cc4dce93980f3bd910f5b74e47278b05dc42 100644 (file)
@@ -3695,6 +3695,65 @@ module GEOM
      */
     void DifferenceIDs (in GEOM_Object theGroup, in ListOfLong theSubShapes);
 
+    /*!
+     *  \brief Union of two groups.
+     *  New group is created. It will contain all entities
+     *  which are present in groups theGroup1 and theGroup2.
+     *  \param theGroup1, theGroup2 are the initial GEOM groups
+     *                              to create the united group from.
+     *  \return a newly created GEOM group.
+     */
+    GEOM_Object UnionGroups (in GEOM_Object theGroup1, in GEOM_Object theGroup2);
+
+    /*!
+     *  \brief Intersection of two groups.
+     *  New group is created. It will contain only those entities
+     *  which are present in both groups theGroup1 and theGroup2.
+     *  \param theGroup1, theGroup2 are the initial GEOM groups to get common part of.
+     *  \return a newly created GEOM group.
+     */
+    GEOM_Object IntersectGroups (in GEOM_Object theGroup1, in GEOM_Object theGroup2);
+
+    /*!
+     *  \brief Cut of two groups.
+     *  New group is created. It will contain entities which are
+     *  present in group theGroup1 but are not present in group theGroup2.
+     *  \param theGroup1 is a GEOM group to include elements of.
+     *  \param theGroup2 is a GEOM group to exclude elements of.
+     *  \return a newly created GEOM group.
+     */
+    GEOM_Object CutGroups (in GEOM_Object theGroup1, in GEOM_Object theGroup2);
+
+    /*!
+     *  \brief Union of list of groups.
+     *  New group is created. It will contain all entities that are
+     *  present in groups listed in theGList.
+     *  \param theGList is a list of GEOM groups to create the united group from.
+     *  \return a newly created GEOM group.
+     */
+    GEOM_Object UnionListOfGroups (in ListOfGO theGList);
+
+    /*!
+     *  \brief Intersection of list of groups.
+     *  New group is created. It will contain only entities
+     *  which are simultaneously present in the groups listed in theGList.
+     *  \param theGList is a list of GEOM groups to get common part of.
+     *  \return a newly created GEOM group.
+     */
+    GEOM_Object IntersectListOfGroups (in ListOfGO theGList);
+
+    /*!
+     *  \brief Cut of lists of groups.
+     *  New group is created. It will contain only entities
+     *  which are present in groups listed in theGList1 but 
+     *  are not present in groups from theGList2.
+     *  \param theGList1 is a list of GEOM groups to include elements of.
+     *  \param theGList2 is a list of GEOM groups to exclude elements of.
+     *  \return a newly created GEOM group.
+     */
+    GEOM_Object CutListOfGroups (in ListOfGO theGList1,
+                                 in ListOfGO theGList2);
+
     /*!
      *  \brief Returns a type of sub-objects stored in the group
      *  \param theGroup is a GEOM group which type is returned.
index d9459fdc23d630dab355a05eb77c8d0fd809d5c3..96b164f7bc053034eb16a836c70689ee635b104e 100644 (file)
             <source>ICO_COMMON</source>
             <translation>common.png</translation>
         </message>
+        <message>
+            <source>ICO_GROUP_INTERSECT</source>
+            <translation>common.png</translation>
+        </message>
         <message>
             <source>ICO_COMPOUND</source>
             <translation>build_compound.png</translation>
             <source>ICO_CUT</source>
             <translation>cut.png</translation>
         </message>
+        <message>
+            <source>ICO_GROUP_CUT</source>
+            <translation>cut.png</translation>
+        </message>
         <message>
             <source>ICO_CYLINDER</source>
             <translation>cylinder.png</translation>
             <source>ICO_FUSE</source>
             <translation>fuse.png</translation>
         </message>
+        <message>
+            <source>ICO_GROUP_UNION</source>
+            <translation>fuse.png</translation>
+        </message>
         <message>
             <source>ICO_GLUE_FACES</source>
             <translation>glue.png</translation>
index 26c1f8b80f5389f4d9dac6ccb87f5a2af6f6e4a0..71fe07144d037a90ad30a2af01e8a2e44b3a23e2 100644 (file)
@@ -2574,6 +2574,18 @@ Please, select face, shell or solid and try again</translation>
         <source>MEN_GROUP_EDIT</source>
         <translation>Edit</translation>
     </message>
+    <message>
+        <source>MEN_GROUP_UNION</source>
+        <translation>Union Groups</translation>
+    </message>
+    <message>
+        <source>MEN_GROUP_INTERSECT</source>
+        <translation>Intersect Groups</translation>
+    </message>
+    <message>
+        <source>MEN_GROUP_CUT</source>
+        <translation>Cut Groups</translation>
+    </message>
     <message>
         <source>MEN_RELOAD_IMPORTED</source>
         <translation>Reload From Disk</translation>
@@ -3350,6 +3362,18 @@ Please, select face, shell or solid and try again</translation>
         <source>STB_GROUP_EDIT</source>
         <translation>Edit a group</translation>
     </message>
+    <message>
+        <source>STB_GROUP_UNION</source>
+        <translation>Union Groups</translation>
+    </message>
+    <message>
+        <source>STB_GROUP_INTERSECT</source>
+        <translation>Intersect Groups</translation>
+    </message>
+    <message>
+        <source>STB_GROUP_CUT</source>
+        <translation>Cut Groups</translation>
+    </message>
     <message>
         <source>STB_RELOAD_IMPORTED</source>
         <translation>Reload imported shape from its original place on disk</translation>
@@ -3950,6 +3974,18 @@ Please, select face, shell or solid and try again</translation>
         <source>TOP_GROUP_EDIT</source>
         <translation>Edit a group</translation>
     </message>
+    <message>
+        <source>TOP_GROUP_UNION</source>
+        <translation>Union Groups</translation>
+    </message>
+    <message>
+        <source>TOP_GROUP_INTERSECT</source>
+        <translation>Intersect Groups</translation>
+    </message>
+    <message>
+        <source>TOP_GROUP_CUT</source>
+        <translation>Cut Groups</translation>
+    </message>
     <message>
         <source>TOP_HEX_SOLID</source>
         <translation>Hexahedral Solid</translation>
@@ -5069,6 +5105,45 @@ Number of sketch points too small</translation>
         <translation>Please, select a group to edit</translation>
     </message>
 </context>
+<context>
+    <name>GroupGUI_BooleanDlg</name>
+    <message>
+        <source>GEOM_UNION</source>
+        <translation>Union</translation>
+    </message>
+    <message>
+        <source>GEOM_UNION_TITLE</source>
+        <translation>Union Groups</translation>
+    </message>
+    <message>
+        <source>GEOM_INTERSECT</source>
+        <translation>Intersect</translation>
+    </message>
+    <message>
+        <source>GEOM_INTERSECT_TITLE</source>
+        <translation>Intersect Groups</translation>
+    </message>
+    <message>
+        <source>GEOM_CUT</source>
+        <translation>Cut</translation>
+    </message>
+    <message>
+        <source>GEOM_CUT_TITLE</source>
+        <translation>Cut Groups</translation>
+    </message>
+    <message>
+        <source>GEOM_GROUPS</source>
+        <translation>Groups</translation>
+    </message>
+    <message>
+        <source>GEOM_MAIN_GROUPS</source>
+        <translation>Main Groups</translation>
+    </message>
+    <message>
+        <source>GEOM_TOOL_GROUPS</source>
+        <translation>Tool Groups</translation>
+    </message>
+</context>
 <context>
     <name>GroupGUI_GroupDlg</name>
     <message>
index b59220aadd3e107e3714b956c9c80f096c92cc97..10eae69106333849523607439f689b2dab18300c 100644 (file)
@@ -557,6 +557,9 @@ void GeometryGUI::OnGUIEvent( int id )
   case GEOMOp::OpGroupCreate:        // MENU GROUP - CREATE
   case GEOMOp::OpGroupCreatePopup:   // POPUP MENU - CREATE GROUP
   case GEOMOp::OpGroupEdit:          // MENU GROUP - EDIT
+  case GEOMOp::OpGroupUnion:         // MENU GROUP - UNION
+  case GEOMOp::OpGroupIntersect:     // MENU GROUP - INTERSECT
+  case GEOMOp::OpGroupCut:           // MENU GROUP - CUT
     libName = "GroupGUI";
     break;
   case GEOMOp::OpHexaSolid:          // MENU BLOCKS - HEXAHEDRAL SOLID
@@ -749,6 +752,9 @@ void GeometryGUI::initialize( CAM_Application* app )
 
   createGeomAction( GEOMOp::OpGroupCreate, "GROUP_CREATE" );
   createGeomAction( GEOMOp::OpGroupEdit,   "GROUP_EDIT" );
+  createGeomAction( GEOMOp::OpGroupUnion,  "GROUP_UNION" );
+  createGeomAction( GEOMOp::OpGroupIntersect, "GROUP_INTERSECT" );
+  createGeomAction( GEOMOp::OpGroupCut,    "GROUP_CUT" );
 
   createGeomAction( GEOMOp::OpReimport,    "RELOAD_IMPORTED" );
 
@@ -949,8 +955,11 @@ void GeometryGUI::initialize( CAM_Application* app )
   createMenu( separator(), newEntId, -1 );
 
   int groupId = createMenu( tr( "MEN_GROUP" ), newEntId, -1 );
-  createMenu( GEOMOp::OpGroupCreate, groupId, -1 );
-  createMenu( GEOMOp::OpGroupEdit,   groupId, -1 );
+  createMenu( GEOMOp::OpGroupCreate,    groupId, -1 );
+  createMenu( GEOMOp::OpGroupEdit,      groupId, -1 );
+  createMenu( GEOMOp::OpGroupUnion,     groupId, -1 );
+  createMenu( GEOMOp::OpGroupIntersect, groupId, -1 );
+  createMenu( GEOMOp::OpGroupCut,       groupId, -1 );
 
   createMenu( separator(), newEntId, -1 );
 
@@ -1201,7 +1210,7 @@ void GeometryGUI::initialize( CAM_Application* app )
   createTool( GEOMOp::OpCheckCompound,    measureTbId );
   createTool( GEOMOp::OpGetNonBlocks,     measureTbId );
   createTool( GEOMOp::OpCheckSelfInters,  measureTbId );
-  
+
   int picturesTbId = createTool( tr( "TOOL_PICTURES" ) );
   createTool( GEOMOp::OpPictureImport,    picturesTbId );
   #ifdef WITH_OPENCV
index 9cb259b5d1771117a33b14fa8da44644db2cb051..89bb954d5ea8c22b618806268096dd18973287a7 100644 (file)
@@ -176,6 +176,9 @@ namespace GEOMOp {
     OpGroupCreate         = 6000,   // MENU GROUP - CREATE
     OpGroupEdit           = 6001,   // MENU GROUP - EDIT
     OpGroupCreatePopup    = 6002,   // POPUP MENU - CREATE GROUP
+    OpGroupUnion          = 6003,   // POPUP MENU - UNION GROUPS
+    OpGroupIntersect      = 6004,   // POPUP MENU - INTERSECT GROUPS
+    OpGroupCut            = 6005,   // POPUP MENU - CUT GROUPS
     // BlocksGUI -------------------//--------------------------------
     OpHexaSolid           = 6100,   // MENU BLOCKS - HEXAHEDRAL SOLID
     OpMultiTransform      = 6101,   // MENU BLOCKS - MULTI-TRANSFORMATION
index db55c72b69a00730bec477a132f0d097da5ff99f..dc47e1f0e5e0581cc7803a5ff45175fbeb2f23e6 100644 (file)
@@ -18,7 +18,6 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
 
 #include <Standard_Stream.hxx>
 
@@ -511,10 +510,10 @@ void GEOMImpl_IGroupOperations::DifferenceList (Handle(GEOM_Object) theGroup,
     if ( aLength - aRemLength > 0 ) {
       aNewSeq = new TColStd_HArray1OfInteger(1, aLength - aRemLength);
       for (j = 1; j <= aLength; j++) {
-       if (!mapIDsToRemove.Contains(aSeq->Value(j))) {
-         aNewSeq->SetValue(k, aSeq->Value(j));
-         k++;
-       }
+        if (!mapIDsToRemove.Contains(aSeq->Value(j))) {
+          aNewSeq->SetValue(k, aSeq->Value(j));
+          k++;
+        }
       }
     }
     else {
@@ -716,10 +715,10 @@ void GEOMImpl_IGroupOperations::DifferenceIDs (Handle(GEOM_Object) theGroup,
     if ( aLength - aRemLength > 0 ) {
       aNewSeq = new TColStd_HArray1OfInteger(1, aLength - aRemLength);
       for (j = 1; j <= aLength; j++) {
-       if (!mapIDsToRemove.Contains(aSeq->Value(j))) {
-         aNewSeq->SetValue(k, aSeq->Value(j));
-         k++;
-       }
+        if (!mapIDsToRemove.Contains(aSeq->Value(j))) {
+          aNewSeq->SetValue(k, aSeq->Value(j));
+          k++;
+        }
       }
     }
     else {
@@ -750,6 +749,743 @@ void GEOMImpl_IGroupOperations::DifferenceIDs (Handle(GEOM_Object) theGroup,
   SetErrorCode(OK);
 }
 
+//=============================================================================
+/*!
+ *  UnionGroups
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IGroupOperations::UnionGroups (Handle(GEOM_Object) theGroup1,
+                                                            Handle(GEOM_Object) theGroup2)
+{
+  SetErrorCode(KO);
+  if (theGroup1.IsNull() || theGroup2.IsNull()) return NULL;
+
+  // Get group type
+  TopAbs_ShapeEnum aType1 = GetType(theGroup1);
+  TopAbs_ShapeEnum aType2 = GetType(theGroup2);
+  TopAbs_ShapeEnum aType = aType1;
+  if (aType1 != aType2) {
+    if (aType1 != TopAbs_SHAPE && aType1 != TopAbs_COMPOUND) {
+      if (aType2 == TopAbs_SHAPE || aType2 == TopAbs_COMPOUND)
+        aType = aType2;
+      else {
+        SetErrorCode("Error: UnionGroups cannot be performed on groups of different type");
+        return NULL;
+      }
+    }
+  }
+
+  // Get Main Shape
+  Handle(GEOM_Function) aFunction1 = theGroup1->GetLastFunction();
+  Handle(GEOM_Function) aFunction2 = theGroup2->GetLastFunction();
+  if (aFunction1.IsNull() || aFunction2.IsNull()) return NULL;
+
+  GEOM_ISubShape aSSI1 (aFunction1);
+  GEOM_ISubShape aSSI2 (aFunction2);
+
+  Handle(GEOM_Function) aMainShapeFunc1 = aSSI1.GetMainShape();
+  Handle(GEOM_Function) aMainShapeFunc2 = aSSI2.GetMainShape();
+  if (aMainShapeFunc1.IsNull() || aMainShapeFunc2.IsNull()) return NULL;
+
+  TDF_Label aLabel1 = aMainShapeFunc1->GetOwnerEntry();
+  TDF_Label aLabel2 = aMainShapeFunc2->GetOwnerEntry();
+  if (aLabel1.IsRoot() || aLabel2.IsRoot()) {
+    SetErrorCode("Error: UnionGroups can be performed only on groups");
+    return NULL;
+  }
+
+  if (aLabel1 != aLabel2) {
+    SetErrorCode("Error: UnionGroups cannot be performed on groups, built on different main shapes");
+    return NULL;
+  }
+
+  Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel1);
+  if (aMainObj.IsNull()) return NULL;
+
+  // New contents of the group
+  TColStd_ListOfInteger aNewIDs;
+  TColStd_MapOfInteger mapIDs;
+
+  Handle(TColStd_HArray1OfInteger) aSeq1 = aSSI1.GetIndices();
+  Handle(TColStd_HArray1OfInteger) aSeq2 = aSSI2.GetIndices();
+  if (aSeq1.IsNull() || aSeq2.IsNull()) return NULL;
+
+  Standard_Integer j, val_j;
+  Standard_Integer aLength1 = aSeq1->Length();
+  Standard_Integer aLength2 = aSeq2->Length();
+
+  for (j = 1; j <= aLength1; j++) {
+    val_j = aSeq1->Value(j);
+    if (val_j > 0 && mapIDs.Add(val_j)) {
+      aNewIDs.Append(val_j);
+    }
+  }
+  for (j = 1; j <= aLength2; j++) {
+    val_j = aSeq2->Value(j);
+    if (val_j > 0 && mapIDs.Add(val_j)) {
+      aNewIDs.Append(val_j);
+    }
+  }
+
+  if (aNewIDs.Extent() < 1) {
+    SetErrorCode("Error: UnionGroups cannot be performed on two empty groups");
+    return NULL;
+  }
+
+  // Put new indices from the list into an array
+  Standard_Integer k = 1;
+  TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
+  Handle(TColStd_HArray1OfInteger) aNewArr = new TColStd_HArray1OfInteger (1, aNewIDs.Extent());
+  for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
+    aNewArr->SetValue(k, aNewIDsIter.Value());
+  }
+
+  // Create the Group
+  Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(aMainObj, aNewArr);
+  aGroup->SetType(GEOM_GROUP);
+  TDF_Label aFreeLabel = aGroup->GetFreeLabel();
+  TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aType);
+
+  // Make a Python command
+  Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
+  GEOM::TPythonDump(aFunction) << aGroup << " = geompy.UnionGroups("
+                               << theGroup1 << ", " << theGroup2 << ")";
+
+  SetErrorCode(OK);
+  return aGroup;
+}
+
+//=============================================================================
+/*!
+ *  IntersectGroups
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IGroupOperations::IntersectGroups (Handle(GEOM_Object) theGroup1,
+                                                                Handle(GEOM_Object) theGroup2)
+{
+  SetErrorCode(KO);
+  if (theGroup1.IsNull() || theGroup2.IsNull()) return NULL;
+
+  // Get group type
+  TopAbs_ShapeEnum aType1 = GetType(theGroup1);
+  TopAbs_ShapeEnum aType2 = GetType(theGroup2);
+  TopAbs_ShapeEnum aType = aType1;
+  if (aType1 != aType2) {
+    if (aType1 != TopAbs_SHAPE && aType1 != TopAbs_COMPOUND) {
+      if (aType2 == TopAbs_SHAPE || aType2 == TopAbs_COMPOUND)
+        aType = aType2;
+      else {
+        SetErrorCode("Error: IntersectGroups cannot be performed on groups of different type");
+        return NULL;
+      }
+    }
+  }
+
+  // Get Main Shape
+  Handle(GEOM_Function) aFunction1 = theGroup1->GetLastFunction();
+  Handle(GEOM_Function) aFunction2 = theGroup2->GetLastFunction();
+  if (aFunction1.IsNull() || aFunction2.IsNull()) return NULL;
+
+  GEOM_ISubShape aSSI1 (aFunction1);
+  GEOM_ISubShape aSSI2 (aFunction2);
+
+  Handle(GEOM_Function) aMainShapeFunc1 = aSSI1.GetMainShape();
+  Handle(GEOM_Function) aMainShapeFunc2 = aSSI2.GetMainShape();
+  if (aMainShapeFunc1.IsNull() || aMainShapeFunc2.IsNull()) return NULL;
+
+  TDF_Label aLabel1 = aMainShapeFunc1->GetOwnerEntry();
+  TDF_Label aLabel2 = aMainShapeFunc2->GetOwnerEntry();
+  if (aLabel1.IsRoot() || aLabel2.IsRoot()) {
+    SetErrorCode("Error: UnionGroups can be performed only on groups");
+    return NULL;
+  }
+
+  if (aLabel1 != aLabel2) {
+    SetErrorCode("Error: IntersectGroups cannot be performed on groups, built on different main shapes");
+    return NULL;
+  }
+
+  Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel1);
+  if (aMainObj.IsNull()) return NULL;
+
+  // New contents of the group
+  TColStd_ListOfInteger aNewIDs;
+  TColStd_MapOfInteger mapIDs;
+
+  Handle(TColStd_HArray1OfInteger) aSeq1 = aSSI1.GetIndices();
+  Handle(TColStd_HArray1OfInteger) aSeq2 = aSSI2.GetIndices();
+  if (aSeq1.IsNull() || aSeq2.IsNull()) return NULL;
+
+  Standard_Integer j, val_j;
+  Standard_Integer aLength1 = aSeq1->Length();
+  Standard_Integer aLength2 = aSeq2->Length();
+
+  for (j = 1; j <= aLength1; j++) {
+    mapIDs.Add(aSeq1->Value(j));
+  }
+  for (j = 1; j <= aLength2; j++) {
+    val_j = aSeq2->Value(j);
+    if (val_j > 0 && !mapIDs.Add(val_j)) {
+      // add index, if it is in mapIDs (filled from Group_1)
+      aNewIDs.Append(val_j);
+    }
+  }
+
+  Handle(TColStd_HArray1OfInteger) aNewArr;
+  if (aNewIDs.Extent() < 1) {
+    aNewArr = new TColStd_HArray1OfInteger (1, 1);
+    aNewArr->SetValue(1, -1);
+  }
+  else {
+    // Put new indices from the list into an array
+    Standard_Integer k = 1;
+    TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
+    aNewArr = new TColStd_HArray1OfInteger (1, aNewIDs.Extent());
+    for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
+      aNewArr->SetValue(k, aNewIDsIter.Value());
+    }
+  }
+
+  // Create the Group
+  Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(aMainObj, aNewArr);
+  aGroup->SetType(GEOM_GROUP);
+  TDF_Label aFreeLabel = aGroup->GetFreeLabel();
+  TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aType);
+
+  // Make a Python command
+  Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
+  GEOM::TPythonDump(aFunction) << aGroup << " = geompy.IntersectGroups("
+                               << theGroup1 << ", " << theGroup2 << ")";
+
+  SetErrorCode(OK);
+  return aGroup;
+}
+
+//=============================================================================
+/*!
+ *  CutGroups
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IGroupOperations::CutGroups (Handle(GEOM_Object) theGroup1,
+                                                          Handle(GEOM_Object) theGroup2)
+{
+  SetErrorCode(KO);
+  if (theGroup1.IsNull() || theGroup2.IsNull()) return NULL;
+
+  // Get group type
+  TopAbs_ShapeEnum aType1 = GetType(theGroup1);
+  TopAbs_ShapeEnum aType2 = GetType(theGroup2);
+  TopAbs_ShapeEnum aType = aType1;
+  if (aType1 != aType2) {
+    if (aType1 != TopAbs_SHAPE && aType1 != TopAbs_COMPOUND) {
+      if (aType2 == TopAbs_SHAPE || aType2 == TopAbs_COMPOUND)
+        aType = aType2;
+      else {
+        SetErrorCode("Error: CutGroups cannot be performed on groups of different type");
+        return NULL;
+      }
+    }
+  }
+
+  // Get Main Shape
+  Handle(GEOM_Function) aFunction1 = theGroup1->GetLastFunction();
+  Handle(GEOM_Function) aFunction2 = theGroup2->GetLastFunction();
+  if (aFunction1.IsNull() || aFunction2.IsNull()) return NULL;
+
+  GEOM_ISubShape aSSI1 (aFunction1);
+  GEOM_ISubShape aSSI2 (aFunction2);
+
+  Handle(GEOM_Function) aMainShapeFunc1 = aSSI1.GetMainShape();
+  Handle(GEOM_Function) aMainShapeFunc2 = aSSI2.GetMainShape();
+  if (aMainShapeFunc1.IsNull() || aMainShapeFunc2.IsNull()) return NULL;
+
+  TDF_Label aLabel1 = aMainShapeFunc1->GetOwnerEntry();
+  TDF_Label aLabel2 = aMainShapeFunc2->GetOwnerEntry();
+  if (aLabel1.IsRoot() || aLabel2.IsRoot()) {
+    SetErrorCode("Error: UnionGroups can be performed only on groups");
+    return NULL;
+  }
+
+  if (aLabel1 != aLabel2) {
+    SetErrorCode("Error: CutGroups cannot be performed on groups, built on different main shapes");
+    return NULL;
+  }
+
+  Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel1);
+  if (aMainObj.IsNull()) return NULL;
+
+  // New contents of the group
+  TColStd_ListOfInteger aNewIDs;
+  TColStd_MapOfInteger mapIDs;
+
+  Handle(TColStd_HArray1OfInteger) aSeq1 = aSSI1.GetIndices();
+  Handle(TColStd_HArray1OfInteger) aSeq2 = aSSI2.GetIndices();
+  if (aSeq1.IsNull() || aSeq2.IsNull()) return NULL;
+
+  Standard_Integer j, val_j;
+  Standard_Integer aLength1 = aSeq1->Length();
+  Standard_Integer aLength2 = aSeq2->Length();
+
+  for (j = 1; j <= aLength2; j++) {
+    mapIDs.Add(aSeq2->Value(j));
+  }
+  for (j = 1; j <= aLength1; j++) {
+    val_j = aSeq1->Value(j);
+    if (val_j > 0 && mapIDs.Add(val_j)) {
+      // add index, if it is not in mapIDs (filled from Group_2)
+      aNewIDs.Append(val_j);
+    }
+  }
+
+  Handle(TColStd_HArray1OfInteger) aNewArr;
+  if (aNewIDs.Extent() < 1) {
+    aNewArr = new TColStd_HArray1OfInteger (1, 1);
+    aNewArr->SetValue(1, -1);
+  }
+  else {
+    // Put new indices from the list into an array
+    Standard_Integer k = 1;
+    TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
+    aNewArr = new TColStd_HArray1OfInteger (1, aNewIDs.Extent());
+    for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
+      aNewArr->SetValue(k, aNewIDsIter.Value());
+    }
+  }
+
+  // Create the Group
+  Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(aMainObj, aNewArr);
+  aGroup->SetType(GEOM_GROUP);
+  TDF_Label aFreeLabel = aGroup->GetFreeLabel();
+  TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aType);
+
+  // Make a Python command
+  Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
+  GEOM::TPythonDump(aFunction) << aGroup << " = geompy.CutGroups("
+                               << theGroup1 << ", " << theGroup2 << ")";
+
+  SetErrorCode(OK);
+  return aGroup;
+}
+
+//=============================================================================
+/*!
+ *  UnionListOfGroups
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IGroupOperations::UnionListOfGroups
+                         (const Handle(TColStd_HSequenceOfTransient)& theGList)
+{
+  SetErrorCode(KO);
+  if (theGList.IsNull()) return NULL;
+
+  Standard_Integer i, aLen = theGList->Length();
+  if (aLen < 1) {
+    SetErrorCode("UnionListOfGroups error: the list of groups is empty");
+    return NULL;
+  }
+
+  TopAbs_ShapeEnum aType, aType_i;
+  TDF_Label aLabel, aLabel_i;
+  TColStd_ListOfInteger aNewIDs;
+  TColStd_MapOfInteger mapIDs;
+
+  // Iterate on the initial groups
+  for (i = 1; i <= aLen; i++) {
+    Handle(GEOM_Object) aGr_i = Handle(GEOM_Object)::DownCast(theGList->Value(i));
+
+    // Get group type
+    aType_i = GetType(aGr_i);
+    if (i == 1)
+      aType = aType_i;
+    else {
+      if (aType_i != aType) {
+        if (aType != TopAbs_SHAPE && aType != TopAbs_COMPOUND) {
+          if (aType_i == TopAbs_SHAPE || aType_i == TopAbs_COMPOUND)
+            aType = aType_i;
+          else {
+            SetErrorCode("Error: UnionListOfGroups cannot be performed on groups of different type");
+            return NULL;
+          }
+        }
+      }
+    }
+
+    // Get Main Shape
+    Handle(GEOM_Function) aFunction_i = aGr_i->GetLastFunction();
+    if (aFunction_i.IsNull()) return NULL;
+    GEOM_ISubShape aSSI (aFunction_i);
+    Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
+    if (aMainShapeFunc.IsNull()) return NULL;
+    aLabel_i = aMainShapeFunc->GetOwnerEntry();
+    if (aLabel_i.IsRoot()) {
+      SetErrorCode("Error: UnionGroups can be performed only on groups");
+      return NULL;
+    }
+    if (i == 1)
+      aLabel = aLabel_i;
+    else {
+      if (aLabel_i != aLabel) {
+        SetErrorCode("Error: UnionListOfGroups cannot be performed on groups, built on different main shapes");
+        return NULL;
+      }
+    }
+
+    // New contents of the group
+    Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
+    if (aSeq.IsNull()) return NULL;
+
+    Standard_Integer j, val_j, aLength = aSeq->Length();
+    for (j = 1; j <= aLength; j++) {
+      val_j = aSeq->Value(j);
+      if (val_j > 0 && mapIDs.Add(val_j)) {
+        aNewIDs.Append(val_j);
+      }
+    }
+  }
+
+  // Check the resulting list of indices
+  if (aNewIDs.Extent() < 1) {
+    SetErrorCode("Error: UnionListOfGroups cannot be performed on all empty groups");
+    return NULL;
+  }
+
+  Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
+  if (aMainObj.IsNull()) return NULL;
+
+  // Put new indices from the list into an array
+  Standard_Integer k = 1;
+  TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
+  Handle(TColStd_HArray1OfInteger) aNewArr = new TColStd_HArray1OfInteger (1, aNewIDs.Extent());
+  for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
+    aNewArr->SetValue(k, aNewIDsIter.Value());
+  }
+
+  // Create the Group
+  Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(aMainObj, aNewArr);
+  aGroup->SetType(GEOM_GROUP);
+  TDF_Label aFreeLabel = aGroup->GetFreeLabel();
+  TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aType);
+
+  //Make a Python command
+  Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
+  GEOM::TPythonDump pd (aFunction);
+  pd << aGroup << " = geompy.UnionListOfGroups([";
+  for (i = 1; i <= aLen; i++) {
+    Handle(GEOM_Object) aGr_i = Handle(GEOM_Object)::DownCast(theGList->Value(i));
+    pd << aGr_i << ((i < aLen) ? ", " : "])");
+  }
+
+  SetErrorCode(OK);
+  return aGroup;
+}
+
+//=============================================================================
+/*!
+ *  IntersectListOfGroups
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IGroupOperations::IntersectListOfGroups
+                         (const Handle(TColStd_HSequenceOfTransient)& theGList)
+{
+  SetErrorCode(KO);
+  if (theGList.IsNull()) return NULL;
+
+  Standard_Integer i, aLen = theGList->Length();
+  if (aLen < 1) {
+    SetErrorCode("IntersectListOfGroups error: the list of groups is empty");
+    return NULL;
+  }
+
+  TopAbs_ShapeEnum aType, aType_i;
+  TDF_Label aLabel, aLabel_i;
+  TColStd_ListOfInteger aNewIDs;
+  TColStd_MapOfInteger mapIDs;
+
+  // Iterate on the initial groups
+  for (i = 1; i <= aLen; i++) {
+    Handle(GEOM_Object) aGr_i = Handle(GEOM_Object)::DownCast(theGList->Value(i));
+
+    // Get group type
+    aType_i = GetType(aGr_i);
+    if (i == 1)
+      aType = aType_i;
+    else {
+      if (aType_i != aType) {
+        if (aType != TopAbs_SHAPE && aType != TopAbs_COMPOUND) {
+          if (aType_i == TopAbs_SHAPE || aType_i == TopAbs_COMPOUND)
+            aType = aType_i;
+          else {
+            SetErrorCode("Error: IntersectListOfGroups cannot be performed on groups of different type");
+            return NULL;
+          }
+        }
+      }
+    }
+
+    // Get Main Shape
+    Handle(GEOM_Function) aFunction_i = aGr_i->GetLastFunction();
+    if (aFunction_i.IsNull()) return NULL;
+    GEOM_ISubShape aSSI (aFunction_i);
+    Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
+    if (aMainShapeFunc.IsNull()) return NULL;
+    aLabel_i = aMainShapeFunc->GetOwnerEntry();
+    if (aLabel_i.IsRoot()) {
+     SetErrorCode("Error: UnionGroups can be performed only on groups");
+     return NULL;
+    }
+    if (i == 1)
+      aLabel = aLabel_i;
+    else {
+      if (aLabel_i != aLabel) {
+        SetErrorCode("Error: IntersectListOfGroups cannot be performed on groups, built on different main shapes");
+        return NULL;
+      }
+    }
+
+    // New contents of the group
+    Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
+    if (aSeq.IsNull()) return NULL;
+
+    Standard_Integer j, val_j, aLength = aSeq->Length();
+    for (j = 1; j <= aLength; j++) {
+      val_j = aSeq->Value(j);
+      if (val_j > 0) {
+        if (i == 1) {
+          // get all elements of the first group
+          if (mapIDs.Add(val_j))
+            aNewIDs.Append(val_j);
+        }
+        else {
+          // get only elements, present in all previously processed groups
+          if (!mapIDs.Add(val_j))
+            aNewIDs.Append(val_j);
+        }
+      }
+    }
+
+    // refill the map with only validated elements
+    if (i > 1) {
+      mapIDs.Clear();
+      TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
+      for (; aNewIDsIter.More(); aNewIDsIter.Next()) {
+        mapIDs.Add(aNewIDsIter.Value());
+      }
+    }
+    // clear the resulting list before starting the next sycle
+    if (i < aLen) {
+      aNewIDs.Clear();
+    }
+  }
+
+  Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
+  if (aMainObj.IsNull()) return NULL;
+
+  Handle(TColStd_HArray1OfInteger) aNewArr;
+  if (aNewIDs.Extent() < 1) {
+    aNewArr = new TColStd_HArray1OfInteger (1, 1);
+    aNewArr->SetValue(1, -1);
+  }
+  else {
+    // Put new indices from the list into an array
+    Standard_Integer k = 1;
+    TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
+    aNewArr = new TColStd_HArray1OfInteger (1, aNewIDs.Extent());
+    for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
+      aNewArr->SetValue(k, aNewIDsIter.Value());
+    }
+  }
+
+  // Create the Group
+  Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(aMainObj, aNewArr);
+  aGroup->SetType(GEOM_GROUP);
+  TDF_Label aFreeLabel = aGroup->GetFreeLabel();
+  TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aType);
+
+  //Make a Python command
+  Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
+  GEOM::TPythonDump pd (aFunction);
+  pd << aGroup << " = geompy.IntersectListOfGroups([";
+  for (i = 1; i <= aLen; i++) {
+    Handle(GEOM_Object) aGr_i = Handle(GEOM_Object)::DownCast(theGList->Value(i));
+    pd << aGr_i << ((i < aLen) ? ", " : "])");
+  }
+
+  SetErrorCode(OK);
+  return aGroup;
+}
+
+//=============================================================================
+/*!
+ *  CutListOfGroups
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IGroupOperations::CutListOfGroups
+                        (const Handle(TColStd_HSequenceOfTransient)& theGList1,
+                         const Handle(TColStd_HSequenceOfTransient)& theGList2)
+{
+  SetErrorCode(KO);
+  if (theGList1.IsNull() || theGList2.IsNull()) return NULL;
+
+  Standard_Integer i;
+  Standard_Integer aLen1 = theGList1->Length();
+  Standard_Integer aLen2 = theGList2->Length();
+  if (aLen1 < 1) {
+    SetErrorCode("CutListOfGroups error: the first list of groups is empty");
+    return NULL;
+  }
+
+  TopAbs_ShapeEnum aType, aType_i;
+  TDF_Label aLabel, aLabel_i;
+  TColStd_ListOfInteger aNewIDs;
+  TColStd_MapOfInteger mapIDs;
+
+  // 1. Collect indices to be excluded (from theGList2) into the mapIDs
+  for (i = 1; i <= aLen2; i++) {
+    Handle(GEOM_Object) aGr_i = Handle(GEOM_Object)::DownCast(theGList2->Value(i));
+
+    // Get group type
+    aType_i = GetType(aGr_i);
+    if (i == 1)
+      aType = aType_i;
+    else {
+      if (aType_i != aType) {
+        if (aType != TopAbs_SHAPE && aType != TopAbs_COMPOUND) {
+          if (aType_i == TopAbs_SHAPE || aType_i == TopAbs_COMPOUND)
+            aType = aType_i;
+          else {
+            SetErrorCode("Error: CutListOfGroups cannot be performed on groups of different type");
+            return NULL;
+          }
+        }
+      }
+    }
+
+    // Get Main Shape
+    Handle(GEOM_Function) aFunction_i = aGr_i->GetLastFunction();
+    if (aFunction_i.IsNull()) return NULL;
+    GEOM_ISubShape aSSI (aFunction_i);
+    Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
+    if (aMainShapeFunc.IsNull()) return NULL;
+    aLabel_i = aMainShapeFunc->GetOwnerEntry();
+    if (aLabel_i.IsRoot()) {
+      SetErrorCode("Error: UnionGroups can be performed only on groups");
+      return NULL;
+    }
+    if (i == 1)
+      aLabel = aLabel_i;
+    else {
+      if (aLabel_i != aLabel) {
+        SetErrorCode("Error: CutListOfGroups cannot be performed on groups, built on different main shapes");
+        return NULL;
+      }
+    }
+
+    // Indiced to exclude
+    Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
+    if (aSeq.IsNull()) return NULL;
+
+    Standard_Integer j, aLength = aSeq->Length();
+    for (j = 1; j <= aLength; j++) {
+      mapIDs.Add(aSeq->Value(j));
+    }
+  }
+
+  // 2. Collect indices from theGList1, avoiding indices from theGList2 (mapIDs)
+  for (i = 1; i <= aLen1; i++) {
+    Handle(GEOM_Object) aGr_i = Handle(GEOM_Object)::DownCast(theGList1->Value(i));
+
+    // Get group type
+    aType_i = GetType(aGr_i);
+    if (i == 1 && aLen2 < 1)
+      aType = aType_i;
+    else {
+      if (aType_i != aType) {
+        if (aType != TopAbs_SHAPE && aType != TopAbs_COMPOUND) {
+          if (aType_i == TopAbs_SHAPE || aType_i == TopAbs_COMPOUND)
+            aType = aType_i;
+          else {
+            SetErrorCode("Error: CutListOfGroups cannot be performed on groups of different type");
+            return NULL;
+          }
+        }
+      }
+    }
+
+    // Get Main Shape
+    Handle(GEOM_Function) aFunction_i = aGr_i->GetLastFunction();
+    if (aFunction_i.IsNull()) return NULL;
+    GEOM_ISubShape aSSI (aFunction_i);
+    Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
+    if (aMainShapeFunc.IsNull()) return NULL;
+    aLabel_i = aMainShapeFunc->GetOwnerEntry();
+    if (aLabel_i.IsRoot()) {
+      SetErrorCode("Error: UnionGroups can be performed only on groups");
+      return NULL;
+    }
+    if (i == 1 && aLen2 < 1)
+      aLabel = aLabel_i;
+    else {
+      if (aLabel_i != aLabel) {
+        SetErrorCode("Error: CutListOfGroups cannot be performed on groups, built on different main shapes");
+        return NULL;
+      }
+    }
+
+    // New contents of the group
+    Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
+    if (aSeq.IsNull()) return NULL;
+
+    Standard_Integer j, val_j, aLength = aSeq->Length();
+    for (j = 1; j <= aLength; j++) {
+      val_j = aSeq->Value(j);
+      if (val_j > 0 && mapIDs.Add(val_j)) {
+        // get only elements, not present in mapIDs (theGList2)
+        aNewIDs.Append(val_j);
+      }
+    }
+  }
+
+  Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
+  if (aMainObj.IsNull()) return NULL;
+
+  Handle(TColStd_HArray1OfInteger) aNewArr;
+  if (aNewIDs.Extent() < 1) {
+    aNewArr = new TColStd_HArray1OfInteger (1, 1);
+    aNewArr->SetValue(1, -1);
+  }
+  else {
+    // Put new indices from the list into an array
+    Standard_Integer k = 1;
+    TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
+    aNewArr = new TColStd_HArray1OfInteger (1, aNewIDs.Extent());
+    for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
+      aNewArr->SetValue(k, aNewIDsIter.Value());
+    }
+  }
+
+  // Create the Group
+  Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(aMainObj, aNewArr);
+  aGroup->SetType(GEOM_GROUP);
+  TDF_Label aFreeLabel = aGroup->GetFreeLabel();
+  TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aType);
+
+  //Make a Python command
+  Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
+  GEOM::TPythonDump pd (aFunction);
+  pd << aGroup << " = geompy.CutListOfGroups([";
+  for (i = 1; i <= aLen1; i++) {
+    Handle(GEOM_Object) aGr_i = Handle(GEOM_Object)::DownCast(theGList1->Value(i));
+    pd << aGr_i << ((i < aLen1) ? ", " : "], [");
+  }
+  for (i = 1; i <= aLen2; i++) {
+    Handle(GEOM_Object) aGr_i = Handle(GEOM_Object)::DownCast(theGList2->Value(i));
+    pd << aGr_i << ((i < aLen2) ? ", " : "])");
+  }
+
+  SetErrorCode(OK);
+  return aGroup;
+}
+
 //=============================================================================
 /*!
  *  GetType
index 0b6a89110704b208663d45c76af6518a9bb51c28..6b8d485eccc07b72a045173bf1ba0b618d4aec41 100644 (file)
@@ -18,7 +18,6 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
 
 #ifndef _GEOMImpl_IGroupOperations_HXX_
 #define _GEOMImpl_IGroupOperations_HXX_
@@ -28,7 +27,7 @@
 #include "GEOM_Engine.hxx"
 #include "GEOM_Object.hxx"
 #include <TDocStd_Document.hxx>
-#include <TColStd_HArray1OfInteger.hxx> 
+#include <TColStd_HArray1OfInteger.hxx>
 #include <TColStd_HSequenceOfInteger.hxx>
 #include <TopAbs.hxx>
 
@@ -55,6 +54,20 @@ class GEOMImpl_IGroupOperations : public GEOM_IOperations {
   Standard_EXPORT void DifferenceIDs (Handle(GEOM_Object) theGroup,
                       const Handle(TColStd_HSequenceOfInteger)& theSubShapes);
 
+  Standard_EXPORT Handle(GEOM_Object) UnionGroups (Handle(GEOM_Object) theGroup1,
+                                                   Handle(GEOM_Object) theGroup2);
+  Standard_EXPORT Handle(GEOM_Object) IntersectGroups (Handle(GEOM_Object) theGroup1,
+                                                       Handle(GEOM_Object) theGroup2);
+  Standard_EXPORT Handle(GEOM_Object) CutGroups (Handle(GEOM_Object) theGroup1,
+                                                 Handle(GEOM_Object) theGroup2);
+
+  Standard_EXPORT Handle(GEOM_Object) UnionListOfGroups
+                                                      (const Handle(TColStd_HSequenceOfTransient)& theGList);
+  Standard_EXPORT Handle(GEOM_Object) IntersectListOfGroups
+                                                      (const Handle(TColStd_HSequenceOfTransient)& theGList);
+  Standard_EXPORT Handle(GEOM_Object) CutListOfGroups (const Handle(TColStd_HSequenceOfTransient)& theGList1,
+                                                       const Handle(TColStd_HSequenceOfTransient)& theGList2);
+
   Standard_EXPORT TopAbs_ShapeEnum GetType(Handle(GEOM_Object) theGroup);
 
   Standard_EXPORT Handle(GEOM_Object) GetMainShape(Handle(GEOM_Object) theGroup);
index 3a8cef597d2d833c0ae93d92d2682e1c2c1cd1aa..60a26e129bece1f5fd8fdf3bfe7d60900f3aead4 100644 (file)
@@ -18,7 +18,6 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
 
 #include <Standard_Stream.hxx>
 
@@ -202,7 +201,6 @@ void GEOM_IGroupOperations_i::UnionIDs (GEOM::GEOM_Object_ptr   theGroup,
 
   //Perform the operation
   GetOperations()->UnionIDs(aGroupRef, aSubShapes);
-  return;
 }
 
 //=============================================================================
@@ -230,7 +228,176 @@ void GEOM_IGroupOperations_i::DifferenceIDs (GEOM::GEOM_Object_ptr   theGroup,
 
   //Perform the operation
   GetOperations()->DifferenceIDs(aGroupRef, aSubShapes);
-  return;
+}
+
+//=============================================================================
+/*!
+ *  UnionGroups
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IGroupOperations_i::UnionGroups (GEOM::GEOM_Object_ptr theGroup1,
+                                                            GEOM::GEOM_Object_ptr theGroup2)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  //Get the reference groups
+  Handle(GEOM_Object) aGroupRef1 = GetObjectImpl(theGroup1);
+  Handle(GEOM_Object) aGroupRef2 = GetObjectImpl(theGroup2);
+  if (aGroupRef1.IsNull() || aGroupRef2.IsNull()) return aGEOMObject._retn();
+
+  //Perform the operation
+  Handle(GEOM_Object) anObject = GetOperations()->UnionGroups(aGroupRef1, aGroupRef2);
+  if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  IntersectGroups
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IGroupOperations_i::IntersectGroups (GEOM::GEOM_Object_ptr theGroup1,
+                                                                GEOM::GEOM_Object_ptr theGroup2)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  //Get the reference groups
+  Handle(GEOM_Object) aGroupRef1 = GetObjectImpl(theGroup1);
+  Handle(GEOM_Object) aGroupRef2 = GetObjectImpl(theGroup2);
+  if (aGroupRef1.IsNull() || aGroupRef2.IsNull()) return aGEOMObject._retn();
+
+  //Perform the operation
+  Handle(GEOM_Object) anObject = GetOperations()->IntersectGroups(aGroupRef1, aGroupRef2);
+  if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  CutGroups
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IGroupOperations_i::CutGroups (GEOM::GEOM_Object_ptr theGroup1,
+                                                          GEOM::GEOM_Object_ptr theGroup2)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  //Get the reference groups
+  Handle(GEOM_Object) aGroupRef1 = GetObjectImpl(theGroup1);
+  Handle(GEOM_Object) aGroupRef2 = GetObjectImpl(theGroup2);
+  if (aGroupRef1.IsNull() || aGroupRef2.IsNull()) return aGEOMObject._retn();
+
+  //Perform the operation
+  Handle(GEOM_Object) anObject = GetOperations()->CutGroups(aGroupRef1, aGroupRef2);
+  if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  UnionListOfGroups
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IGroupOperations_i::UnionListOfGroups (const GEOM::ListOfGO& theGList)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  //Get the reference groups
+  Handle(TColStd_HSequenceOfTransient) aGroups = new TColStd_HSequenceOfTransient;
+
+  int ind, aLen = theGList.length();
+  for (ind = 0; ind < aLen; ind++) {
+    Handle(GEOM_Object) aGr = GetObjectImpl(theGList[ind]);
+    if (aGr.IsNull()) return aGEOMObject._retn();
+    aGroups->Append(aGr);
+  }
+
+  //Perform the operation
+  Handle(GEOM_Object) anObject = GetOperations()->UnionListOfGroups(aGroups);
+  if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  IntersectListOfGroups
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IGroupOperations_i::IntersectListOfGroups (const GEOM::ListOfGO& theGList)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  //Get the reference groups
+  Handle(TColStd_HSequenceOfTransient) aGroups = new TColStd_HSequenceOfTransient;
+
+  int ind, aLen = theGList.length();
+  for (ind = 0; ind < aLen; ind++) {
+    Handle(GEOM_Object) aGr = GetObjectImpl(theGList[ind]);
+    if (aGr.IsNull()) return aGEOMObject._retn();
+    aGroups->Append(aGr);
+  }
+
+  //Perform the operation
+  Handle(GEOM_Object) anObject = GetOperations()->IntersectListOfGroups(aGroups);
+  if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  CutListOfGroups
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IGroupOperations_i::CutListOfGroups (const GEOM::ListOfGO& theGList1,
+                                                                const GEOM::ListOfGO& theGList2)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  //Get the reference groups
+  Handle(TColStd_HSequenceOfTransient) aGroups1 = new TColStd_HSequenceOfTransient;
+  Handle(TColStd_HSequenceOfTransient) aGroups2 = new TColStd_HSequenceOfTransient;
+
+  int ind, aLen = theGList1.length();
+  for (ind = 0; ind < aLen; ind++) {
+    Handle(GEOM_Object) aGr = GetObjectImpl(theGList1[ind]);
+    if (aGr.IsNull()) return aGEOMObject._retn();
+    aGroups1->Append(aGr);
+  }
+  aLen = theGList2.length();
+  for (ind = 0; ind < aLen; ind++) {
+    Handle(GEOM_Object) aGr = GetObjectImpl(theGList2[ind]);
+    if (aGr.IsNull()) return aGEOMObject._retn();
+    aGroups2->Append(aGr);
+  }
+
+  //Perform the operation
+  Handle(GEOM_Object) anObject = GetOperations()->CutListOfGroups(aGroups1, aGroups2);
+  if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn();
+
+  return GetObject(anObject);
 }
 
 //=============================================================================
index b3871e0fe9122318c4b9c537918a6b626cfd0106..f213e8be2c4ff620999861da0523932bbad9dc61 100644 (file)
@@ -18,7 +18,6 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
 
 #ifndef _GEOM_IGroupOperations_i_HeaderFile
 #define _GEOM_IGroupOperations_i_HeaderFile
 
 #include "GEOMImpl_IGroupOperations.hxx"
 
-class GEOM_I_EXPORT GEOM_IGroupOperations_i : 
+class GEOM_I_EXPORT GEOM_IGroupOperations_i :
     public virtual POA_GEOM::GEOM_IGroupOperations,
     public virtual GEOM_IOperations_i
 {
  public:
   GEOM_IGroupOperations_i (PortableServer::POA_ptr thePOA, GEOM::GEOM_Gen_ptr theEngine,
-                          ::GEOMImpl_IGroupOperations* theImpl);
+                           ::GEOMImpl_IGroupOperations* theImpl);
   ~GEOM_IGroupOperations_i();
 
-  GEOM::GEOM_Object_ptr CreateGroup  (GEOM::GEOM_Object_ptr theMainShape, CORBA::Long theShapeType);
+  GEOM::GEOM_Object_ptr CreateGroup (GEOM::GEOM_Object_ptr theMainShape, CORBA::Long theShapeType);
+
   void AddObject (GEOM::GEOM_Object_ptr theGroup, CORBA::Long theSubShapeId);
 
   void RemoveObject (GEOM::GEOM_Object_ptr theGroup, CORBA::Long theSubShapeId);
@@ -56,8 +55,16 @@ class GEOM_I_EXPORT GEOM_IGroupOperations_i :
 
   void DifferenceIDs (GEOM::GEOM_Object_ptr theGroup, const GEOM::ListOfLong& theSubShapes);
 
+  GEOM::GEOM_Object_ptr UnionGroups (GEOM::GEOM_Object_ptr theGroup1, GEOM::GEOM_Object_ptr theGroup2);
+  GEOM::GEOM_Object_ptr IntersectGroups (GEOM::GEOM_Object_ptr theGroup1, GEOM::GEOM_Object_ptr theGroup2);
+  GEOM::GEOM_Object_ptr CutGroups (GEOM::GEOM_Object_ptr theGroup1, GEOM::GEOM_Object_ptr theGroup2);
+
+  GEOM::GEOM_Object_ptr UnionListOfGroups (const GEOM::ListOfGO& theGList);
+  GEOM::GEOM_Object_ptr IntersectListOfGroups (const GEOM::ListOfGO& theGList);
+  GEOM::GEOM_Object_ptr CutListOfGroups (const GEOM::ListOfGO& theGList1, const GEOM::ListOfGO& theGList2);
+
   CORBA::Long GetType (GEOM::GEOM_Object_ptr theGroup);
-  
+
   GEOM::GEOM_Object_ptr GetMainShape (GEOM::GEOM_Object_ptr theGroup);
 
   GEOM::ListOfLong* GetObjects (GEOM::GEOM_Object_ptr theGroup);
index 73d91287d3483359cbffd71b065950ad8e772493..9eee4f171ef58d9a31182a901a135b08845da1ca 100644 (file)
@@ -144,6 +144,7 @@ def TestOtherOperations (geompy, math):
 
   # OrientationChange
   Box = geompy.MakeBoxDXDYDZ(200, 200, 200)
+  geompy.addToStudy(Box, "Box")
   Orientation = geompy.OrientationChange(Box)
   id_Orientation = geompy.addToStudy(Orientation, "OrientationChange")
 
@@ -316,6 +317,42 @@ def TestOtherOperations (geompy, math):
   for ObjectID in GetObjectIDs:
     print " ", ObjectID
 
+  # Boolean Operations on Groups (Union, Intersection, Cut)
+  Group_1 = geompy.CreateGroup(Box, geompy.ShapeType["FACE"])
+  geompy.UnionIDs(Group_1, [13, 23])
+  Group_2 = geompy.CreateGroup(Box, geompy.ShapeType["FACE"])
+  geompy.UnionIDs(Group_2, [3, 27])
+  Group_3 = geompy.CreateGroup(Box, geompy.ShapeType["FACE"])
+  geompy.UnionIDs(Group_3, [33, 23])
+  Group_4 = geompy.CreateGroup(Box, geompy.ShapeType["FACE"])
+  geompy.UnionIDs(Group_4, [31, 27])
+
+  geompy.addToStudyInFather(Box, Group_1, 'Group_1')
+  geompy.addToStudyInFather(Box, Group_2, 'Group_2')
+  geompy.addToStudyInFather(Box, Group_3, 'Group_3')
+  geompy.addToStudyInFather(Box, Group_4, 'Group_4')
+
+  # union groups
+  Group_U_1_2 = geompy.UnionGroups(Group_1, Group_2)
+  Group_UL_3_4 = geompy.UnionListOfGroups([Group_3, Group_4])
+
+  geompy.addToStudyInFather(Box, Group_U_1_2, 'Group_U_1_2')
+  geompy.addToStudyInFather(Box, Group_UL_3_4, 'Group_UL_3_4')
+
+  # intersect groups
+  Group_I_1_3 = geompy.IntersectGroups(Group_1, Group_3)
+  Group_IL_1_3 = geompy.IntersectListOfGroups([Group_1, Group_3])
+
+  geompy.addToStudyInFather(Box, Group_I_1_3, 'Group_I_1_3')
+  geompy.addToStudyInFather(Box, Group_IL_1_3, 'Group_IL_1_3')
+
+  # cut groups
+  Group_C_2_4 = geompy.CutGroups(Group_2, Group_4)
+  Group_CL_2_4 = geompy.CutListOfGroups([Group_2], [Group_4])
+
+  geompy.addToStudyInFather(Box, Group_C_2_4, 'Group_C_2_4')
+  geompy.addToStudyInFather(Box, Group_CL_2_4, 'Group_CL_2_4')
+
   # -----------------------------------------------------------------------------
   # enumeration ShapeTypeString as a dictionary
   # -----------------------------------------------------------------------------
index 33817a1b834e1a6d7e6603cbe4543a6e38dad082..ed0c12272a58d19ab9195725751077afdc5c2774 100644 (file)
@@ -8270,6 +8270,156 @@ class geompyDC(GEOM._objref_GEOM_Gen):
             RaiseIfFailed("DifferenceIDs", self.GroupOp)
             pass
 
+        ## Union of two groups.
+        #  New group is created. It will contain all entities
+        #  which are present in groups theGroup1 and theGroup2.
+        #  @param theGroup1, theGroup2 are the initial GEOM groups
+        #                              to create the united group from.
+        #  @return a newly created GEOM group.
+        #  @ref tui_union_groups_anchor "Example"
+        def UnionGroups (self, theGroup1, theGroup2):
+            """
+            Union of two groups.
+            New group is created. It will contain all entities
+            which are present in groups theGroup1 and theGroup2.
+
+            Parameters:
+                theGroup1, theGroup2 are the initial GEOM groups
+                                     to create the united group from.
+
+            Returns:
+                a newly created GEOM group.
+            """
+            # Example: see GEOM_TestOthers.py
+            aGroup = self.GroupOp.UnionGroups(theGroup1, theGroup2)
+            RaiseIfFailed("UnionGroups", self.GroupOp)
+            return aGroup
+
+        ## Intersection of two groups.
+        #  New group is created. It will contain only those entities
+        #  which are present in both groups theGroup1 and theGroup2.
+        #  @param theGroup1, theGroup2 are the initial GEOM groups to get common part of.
+        #  @return a newly created GEOM group.
+        #  @ref tui_intersect_groups_anchor "Example"
+        def IntersectGroups (self, theGroup1, theGroup2):
+            """
+            Intersection of two groups.
+            New group is created. It will contain only those entities
+            which are present in both groups theGroup1 and theGroup2.
+
+            Parameters:
+                theGroup1, theGroup2 are the initial GEOM groups to get common part of.
+
+            Returns:
+                a newly created GEOM group.
+            """
+            # Example: see GEOM_TestOthers.py
+            aGroup = self.GroupOp.IntersectGroups(theGroup1, theGroup2)
+            RaiseIfFailed("IntersectGroups", self.GroupOp)
+            return aGroup
+
+        ## Cut of two groups.
+        #  New group is created. It will contain entities which are
+        #  present in group theGroup1 but are not present in group theGroup2.
+        #  @param theGroup1 is a GEOM group to include elements of.
+        #  @param theGroup2 is a GEOM group to exclude elements of.
+        #  @return a newly created GEOM group.
+        #  @ref tui_cut_groups_anchor "Example"
+        def CutGroups (self, theGroup1, theGroup2):
+            """
+            Cut of two groups.
+            New group is created. It will contain entities which are
+            present in group theGroup1 but are not present in group theGroup2.
+
+            Parameters:
+                theGroup1 is a GEOM group to include elements of.
+                theGroup2 is a GEOM group to exclude elements of.
+
+            Returns:
+                a newly created GEOM group.
+            """
+            # Example: see GEOM_TestOthers.py
+            aGroup = self.GroupOp.CutGroups(theGroup1, theGroup2)
+            RaiseIfFailed("CutGroups", self.GroupOp)
+            return aGroup
+
+        ## Union of list of groups.
+        #  New group is created. It will contain all entities that are
+        #  present in groups listed in theGList.
+        #  @param theGList is a list of GEOM groups to create the united group from.
+        #  @return a newly created GEOM group.
+        #  @ref tui_union_groups_anchor "Example"
+        def UnionListOfGroups (self, theGList):
+            """
+            Union of list of groups.
+            New group is created. It will contain all entities that are
+            present in groups listed in theGList.
+
+            Parameters:
+                theGList is a list of GEOM groups to create the united group from.
+
+            Returns:
+                a newly created GEOM group.
+            """
+            # Example: see GEOM_TestOthers.py
+            aGroup = self.GroupOp.UnionListOfGroups(theGList)
+            RaiseIfFailed("UnionListOfGroups", self.GroupOp)
+            return aGroup
+
+        ## Cut of lists of groups.
+        #  New group is created. It will contain only entities
+        #  which are present in groups listed in theGList1 but 
+        #  are not present in groups from theGList2.
+        #  @param theGList1 is a list of GEOM groups to include elements of.
+        #  @param theGList2 is a list of GEOM groups to exclude elements of.
+        #  @return a newly created GEOM group.
+        #  @ref tui_intersect_groups_anchor "Example"
+        def IntersectListOfGroups (self, theGList):
+            """
+            Cut of lists of groups.
+            New group is created. It will contain only entities
+            which are present in groups listed in theGList1 but 
+            are not present in groups from theGList2.
+
+            Parameters:
+                theGList1 is a list of GEOM groups to include elements of.
+                theGList2 is a list of GEOM groups to exclude elements of.
+
+            Returns:
+                a newly created GEOM group.
+            """
+            # Example: see GEOM_TestOthers.py
+            aGroup = self.GroupOp.IntersectListOfGroups(theGList)
+            RaiseIfFailed("IntersectListOfGroups", self.GroupOp)
+            return aGroup
+
+        ## Cut of lists of groups.
+        #  New group is created. It will contain only entities
+        #  which are present in groups listed in theGList1 but 
+        #  are not present in groups from theGList2.
+        #  @param theGList1 is a list of GEOM groups to include elements of.
+        #  @param theGList2 is a list of GEOM groups to exclude elements of.
+        #  @return a newly created GEOM group.
+        #  @ref tui_cut_groups_anchor "Example"
+        def CutListOfGroups (self, theGList1, theGList2):
+            """
+            Cut of lists of groups.
+            New group is created. It will contain only entities
+            which are present in groups listed in theGList1 but 
+            are not present in groups from theGList2.
+
+            Parameters:
+                theGList1 is a list of GEOM groups to include elements of.
+                theGList2 is a list of GEOM groups to exclude elements of.
+
+            Returns:
+                a newly created GEOM group.
+            """
+            # Example: see GEOM_TestOthers.py
+            aGroup = self.GroupOp.CutListOfGroups(theGList1, theGList2)
+            RaiseIfFailed("CutListOfGroups", self.GroupOp)
+            return aGroup
+
         ## Returns a list of sub-objects ID stored in the group
         #  @param theGroup is a GEOM group for which a list of IDs is requested
         #
index 990263407f6a530f2765c500c1490758a81923a0..d8f92294fd42526026ca063dd8a62a5b0d0049a2 100644 (file)
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
 
 // GEOM GEOMGUI : GUI for Geometry component
 // File   : GroupGUI.cxx
 // Author : Sergey ANIKIN, Open CASCADE S.A.S. (sergey.anikin@opencascade.com)
-//
+
 #include "GroupGUI.h"
 #include "GroupGUI_GroupDlg.h" 
+#include "GroupGUI_BooleanDlg.h" 
 
 #include <GeometryGUI.h>
 #include "GeometryGUI_Operations.h"
@@ -44,8 +44,8 @@
 // function : GroupGUI()
 // purpose  : Constructor
 //=======================================================================
-GroupGUI::GroupGUI( GeometryGUI* parent )
-  : GEOMGUI( parent )
+GroupGUI::GroupGUI (GeometryGUI* parent)
+  : GEOMGUI(parent)
 {
 }
 
@@ -62,60 +62,67 @@ GroupGUI::~GroupGUI()
 // function : OnGUIEvent()
 // purpose  : 
 //=======================================================================
-bool GroupGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent )
+bool GroupGUI::OnGUIEvent (int theCommandID, SUIT_Desktop* parent)
 {
   SalomeApp_Application* app = getGeometryGUI()->getApp();
-  if ( !app ) return false;
+  if (!app) return false;
 
   getGeometryGUI()->EmitSignalDeactivateDialog();
 
   QDialog* aDlg = 0;
 
-  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
-  if ( !appStudy ) return false;
+  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
+  if (!appStudy) return false;
   _PTR(Study) aStudy = appStudy->studyDS();
 
-  if ( aStudy->GetProperties()->IsLocked() ) {
-    SUIT_MessageBox::warning( parent,
-                              tr( "WRN_WARNING" ), 
-                              tr( "WRN_STUDY_LOCKED" ) );
+  if (aStudy->GetProperties()->IsLocked()) {
+    SUIT_MessageBox::warning(parent, tr("WRN_WARNING"), tr("WRN_STUDY_LOCKED"));
     return false;
   }
 
-  switch ( theCommandID ) {
+  switch (theCommandID) {
   case GEOMOp::OpGroupCreate: 
   case GEOMOp::OpGroupCreatePopup: // CREATE GROUP
-    aDlg = new GroupGUI_GroupDlg( GroupGUI_GroupDlg::CreateGroup, getGeometryGUI(), parent ); 
+    aDlg = new GroupGUI_GroupDlg (GroupGUI_GroupDlg::CreateGroup, getGeometryGUI(), parent); 
     break;
-  case GEOMOp::OpGroupEdit:  // EDIT GROUP
+  case GEOMOp::OpGroupEdit: // EDIT GROUP
     {
       SALOME_ListIO aList;
       aList.Clear();
 
       LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
-      if ( aSelMgr )
-        aSelMgr->selectedObjects( aList );
+      if (aSelMgr)
+        aSelMgr->selectedObjects(aList);
 
-      if ( aList.Extent() == 1 ) {
+      if (aList.Extent() == 1) {
         GEOM::GEOM_Object_var anObj =
-          GEOMBase::ConvertIOinGEOMObject( aList.First() );
+          GEOMBase::ConvertIOinGEOMObject(aList.First());
 
-        if ( !CORBA::is_nil( anObj ) && anObj->GetType() == GEOM_GROUP ) {
-          aDlg = new GroupGUI_GroupDlg( GroupGUI_GroupDlg::EditGroup, getGeometryGUI(), parent ); 
+        if (!CORBA::is_nil(anObj) && anObj->GetType() == GEOM_GROUP) {
+          aDlg = new GroupGUI_GroupDlg (GroupGUI_GroupDlg::EditGroup, getGeometryGUI(), parent); 
           break;
         }
       }
-      SUIT_MessageBox::warning( parent, tr( "WRN_WARNING" ), tr( "NO_GROUP" ) );
-      break;
+      SUIT_MessageBox::warning(parent, tr("WRN_WARNING"), tr("NO_GROUP"));
     }
+    break;
+  case GEOMOp::OpGroupUnion: // UNION GROUPS
+    aDlg = new GroupGUI_BooleanDlg (GroupGUI_BooleanDlg::UNION, getGeometryGUI(), parent); 
+    break;
+  case GEOMOp::OpGroupIntersect: // INTERSECT GROUPS
+    aDlg = new GroupGUI_BooleanDlg (GroupGUI_BooleanDlg::INTERSECT, getGeometryGUI(), parent); 
+    break;
+  case GEOMOp::OpGroupCut: // CUT GROUPS
+    aDlg = new GroupGUI_BooleanDlg (GroupGUI_BooleanDlg::CUT, getGeometryGUI(), parent); 
+    break;
   default: 
-    app->putInfo( tr( "GEOM_PRP_COMMAND" ).arg( theCommandID ) ); 
+    app->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID)); 
     break;
   }
 
-  if ( aDlg ) {
+  if (aDlg) {
     aDlg->updateGeometry();
-    aDlg->resize( aDlg->minimumSizeHint() );
+    aDlg->resize(aDlg->minimumSizeHint());
     aDlg->show();
   }
 
diff --git a/src/GroupGUI/GroupGUI_BooleanDlg.cxx b/src/GroupGUI/GroupGUI_BooleanDlg.cxx
new file mode 100644 (file)
index 0000000..3c227e0
--- /dev/null
@@ -0,0 +1,320 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+
+// GEOM GEOMGUI : GUI for Geometry component
+// File   : GroupGUI_BooleanDlg.cxx
+// Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
+
+#include "GroupGUI_BooleanDlg.h"
+
+#include <DlgRef.h>
+#include <GeometryGUI.h>
+#include <GEOMBase.h>
+
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+#include <SalomeApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+
+#include <GEOMImpl_Types.hxx>
+
+//=================================================================================
+// class    : GroupGUI_BooleanDlg()
+// purpose  : Constructs a GroupGUI_BooleanDlg which is a child of 'parent', with the
+//            name 'name' and widget flags set to 'f'.
+//            The dialog will by default be modeless, unless you set 'modal' to
+//            TRUE to construct a modal dialog.
+//=================================================================================
+GroupGUI_BooleanDlg::GroupGUI_BooleanDlg (const int theOperation, GeometryGUI* theGeometryGUI,
+                                          QWidget* parent, bool modal, Qt::WindowFlags fl)
+  : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl),
+    myOperation(theOperation)
+{
+  QPixmap image0;
+  QString aTitle, aCaption;
+  switch (myOperation) {
+  case UNION:
+    image0 = QPixmap(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_FUSE")));
+    aTitle = tr("GEOM_UNION");
+    aCaption = tr("GEOM_UNION_TITLE");
+    setHelpFileName("work_with_groups_page.html#union_groups_anchor");
+    break;
+  case INTERSECT:
+    image0 = QPixmap(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_COMMON")));
+    aTitle = tr("GEOM_INTERSECT");
+    aCaption = tr("GEOM_INTERSECT_TITLE");
+    setHelpFileName("work_with_groups_page.html#intersect_groups_anchor");
+    break;
+  case CUT:
+    image0 = QPixmap(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_CUT")));
+    aTitle = tr("GEOM_CUT");
+    aCaption = tr("GEOM_CUT_TITLE");
+    setHelpFileName("work_with_groups_page.html#cut_groups_anchor");
+    break;
+  }
+  QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
+
+  setWindowTitle(aCaption);
+
+  /***************************************************************/
+  mainFrame()->GroupConstructors->setTitle(aTitle);
+  mainFrame()->RadioButton1->setIcon(image0);
+  mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose);
+  mainFrame()->RadioButton2->close();
+  mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
+  mainFrame()->RadioButton3->close();
+
+  myGroup = new DlgRef_2Sel (centralWidget());
+
+  myGroup->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
+  if (myOperation == CUT) {
+    myGroup->TextLabel1->setText(tr("GEOM_MAIN_GROUPS"));
+    myGroup->TextLabel2->setText(tr("GEOM_TOOL_GROUPS"));
+  }
+  else {
+    myGroup->TextLabel1->setText(tr("GEOM_GROUPS").arg(1));
+    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);
+
+  QVBoxLayout* layout = new QVBoxLayout (centralWidget());
+  layout->setMargin(0); layout->setSpacing(6);
+  layout->addWidget(myGroup);
+  /***************************************************************/
+
+  // Initialisation
+  Init();
+}
+
+//=================================================================================
+// function : ~GroupGUI_BooleanDlg()
+// purpose  : Destroys the object and frees any allocated resources
+//=================================================================================
+GroupGUI_BooleanDlg::~GroupGUI_BooleanDlg()
+{
+}
+
+//=================================================================================
+// function : Init()
+// purpose  :
+//=================================================================================
+void GroupGUI_BooleanDlg::Init()
+{
+  // init variables
+  myEditCurrentArgument = myGroup->LineEdit1;
+
+  myGroup->LineEdit1->setText("");
+  myGroup->LineEdit2->setText("");
+  myListShapes.length( 0 );
+  myListTools.length( 0 );
+
+  // 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()));
+
+  connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(),
+           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+
+  initName(mainFrame()->GroupConstructors->title());
+
+  setTabOrder(mainFrame()->GroupConstructors, mainFrame()->GroupBoxName);
+  setTabOrder(mainFrame()->GroupBoxName, mainFrame()->GroupMedium);
+  setTabOrder(mainFrame()->GroupMedium, mainFrame()->GroupButtons);
+
+  mainFrame()->RadioButton1->setFocus();
+
+  globalSelection(GEOM_GROUP);
+
+  myGroup->PushButton1->click();
+  SelectionIntoArgument();
+  resize(100,100);
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose  :
+//=================================================================================
+void GroupGUI_BooleanDlg::ClickOnOk()
+{
+  setIsApplyAndClose(true);
+  if (ClickOnApply())
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose  :
+//=================================================================================
+bool GroupGUI_BooleanDlg::ClickOnApply()
+{
+  if (!onAccept())
+    return false;
+
+  initName();
+  // activate selection and connect selection manager
+  myGroup->PushButton1->click();
+  return true;
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection is changed or on dialog initialization or activation
+//=================================================================================
+void GroupGUI_BooleanDlg::SelectionIntoArgument()
+{
+  myEditCurrentArgument->setText("");
+
+  LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
+  SALOME_ListIO aSelList;
+  aSelMgr->selectedObjects(aSelList);
+
+  QString aString = "";
+  GEOMBase::GetNameOfSelectedIObjects(aSelList, aString, true);
+
+  if (myEditCurrentArgument == myGroup->LineEdit1) {
+    GEOMBase::ConvertListOfIOInListOfGO(aSelList, myListShapes, true);
+  }
+  else if ( myEditCurrentArgument == myGroup->LineEdit2 ) {
+    GEOMBase::ConvertListOfIOInListOfGO(aSelList, myListTools, true);
+  }
+
+  myEditCurrentArgument->setText(aString);
+}
+
+//=================================================================================
+// function : SetEditCurrentArgument()
+// purpose  :
+//=================================================================================
+void GroupGUI_BooleanDlg::SetEditCurrentArgument()
+{
+  QPushButton* send = (QPushButton*)sender();
+
+  if (send == myGroup->PushButton1) {
+    myEditCurrentArgument = myGroup->LineEdit1;
+
+    myGroup->PushButton2->setDown(false);
+    myGroup->LineEdit2->setEnabled(false);
+  }
+  else if (send == myGroup->PushButton2) {
+    myEditCurrentArgument = myGroup->LineEdit2;
+
+    myGroup->PushButton1->setDown(false);
+    myGroup->LineEdit1->setEnabled(false);
+  }
+
+  // enable line edit
+  myEditCurrentArgument->setEnabled(true);
+  myEditCurrentArgument->setFocus();
+  // after setFocus(), because it will be setDown(false) when loses focus
+  send->setDown(true);
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose  :
+//=================================================================================
+void GroupGUI_BooleanDlg::ActivateThisDialog()
+{
+  GEOMBase_Skeleton::ActivateThisDialog();
+
+  connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
+           this, SLOT(SelectionIntoArgument()));
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose  : when mouse enter onto the QWidget
+//=================================================================================
+void GroupGUI_BooleanDlg::enterEvent (QEvent*)
+{
+  if (!mainFrame()->GroupConstructors->isEnabled())
+    ActivateThisDialog();
+}
+
+//=================================================================================
+// function : createOperation
+// purpose  :
+//=================================================================================
+GEOM::GEOM_IOperations_ptr GroupGUI_BooleanDlg::createOperation()
+{
+  return getGeomEngine()->GetIGroupOperations(getStudyId());
+}
+
+//=================================================================================
+// function : isValid
+// purpose  :
+//=================================================================================
+bool GroupGUI_BooleanDlg::isValid (QString&)
+{
+  return (myListShapes.length() > 0);
+}
+
+//=================================================================================
+// function : execute
+// purpose  :
+//=================================================================================
+bool GroupGUI_BooleanDlg::execute (ObjectList& objects)
+{
+  GEOM::GEOM_Object_var anObj;
+
+  GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
+  switch (myOperation) {
+  case UNION:
+    anObj = anOper->UnionListOfGroups(myListShapes);
+    break;
+  case INTERSECT:
+    anObj = anOper->IntersectListOfGroups(myListShapes);
+    break;
+  case CUT:
+    anObj = anOper->CutListOfGroups(myListShapes, myListTools);
+    break;
+  default:
+    ;
+  }
+  if (!anObj->_is_nil())
+    objects.push_back(anObj._retn());
+
+  return true;
+}
+
+//================================================================
+// Function : getFather
+// Purpose  : Get father object for object to be added in study
+//            (called with addInStudy method)
+//================================================================
+GEOM::GEOM_Object_ptr GroupGUI_BooleanDlg::getFather(GEOM::GEOM_Object_ptr theObj)
+{
+  GEOM::GEOM_Object_var aFatherObj;
+  if (theObj->GetType() == GEOM_GROUP) {
+    GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
+    aFatherObj = anOper->GetMainShape(theObj);
+  }
+  return aFatherObj._retn();
+}
diff --git a/src/GroupGUI/GroupGUI_BooleanDlg.h b/src/GroupGUI/GroupGUI_BooleanDlg.h
new file mode 100644 (file)
index 0000000..467130e
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+
+// GEOM GEOMGUI : GUI for Geometry component
+// File   : GroupGUI_BooleanDlg.h
+// Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
+
+#ifndef GROUPGUI_BOOLEANDLG_H
+#define GROUPGUI_BOOLEANDLG_H
+
+#include "GEOMBase_Skeleton.h"
+#include "GEOM_GenericObjPtr.h"
+
+class DlgRef_2Sel;
+
+//=================================================================================
+// class    : GroupGUI_BooleanDlg
+// purpose  :
+//=================================================================================
+class GroupGUI_BooleanDlg : public GEOMBase_Skeleton
+{
+  Q_OBJECT
+
+public:
+  enum Operation { UNION = 1, INTERSECT = 2, CUT = 3 };
+
+  GroupGUI_BooleanDlg (const int, GeometryGUI*, QWidget* = 0,
+                       bool = false, Qt::WindowFlags = 0);
+  ~GroupGUI_BooleanDlg();
+
+protected:
+  // redefined from GEOMBase_Helper
+  virtual GEOM::GEOM_IOperations_ptr createOperation();
+  virtual bool                       isValid (QString&);
+  virtual bool                       execute (ObjectList&);
+  virtual GEOM::GEOM_Object_ptr      getFather (GEOM::GEOM_Object_ptr);
+
+private:
+  void                               Init();
+  void                               enterEvent (QEvent*);
+
+private slots:
+  void                               ClickOnOk();
+  bool                               ClickOnApply();
+  void                               SetEditCurrentArgument();
+  void                               SelectionIntoArgument();
+  void                               ActivateThisDialog();
+  
+private:
+  int                                myOperation;
+  
+  GEOM::ListOfGO                     myListShapes;
+  GEOM::ListOfGO                     myListTools;
+  
+  DlgRef_2Sel*                       myGroup;
+};
+
+#endif // GROUPGUI_BOOLEANDLG_H
index 068c3587afde2c761dea5b5ca8e32c2858bb75d2..78e540589ff7105f5d3c606ccac23d088bf441cb 100755 (executable)
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-#
 
-# GEOM GROUPGUI : 
 # File    : Makefile.am
 # Author  : Alexander BORODIN, Open CASCADE S.A.S. (alexander.borodin@opencascade.com)
 # Package : GroupGUI
-#
+
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 # Libraries targets
@@ -30,16 +28,20 @@ lib_LTLIBRARIES = libGroupGUI.la
 # header files 
 salomeinclude_HEADERS =                \
        GroupGUI.h              \
+       GroupGUI_BooleanDlg.h   \
        GroupGUI_GroupDlg.h
 
 dist_libGroupGUI_la_SOURCES =  \
        GroupGUI.h              \
+       GroupGUI_BooleanDlg.h   \
        GroupGUI_GroupDlg.h     \
        GroupGUI.cxx            \
+       GroupGUI_BooleanDlg.cxx \
        GroupGUI_GroupDlg.cxx
 
-MOC_FILES =                    \
-       GroupGUI_moc.cxx        \
+MOC_FILES =                            \
+       GroupGUI_moc.cxx                \
+       GroupGUI_BooleanDlg_moc.cxx     \
        GroupGUI_GroupDlg_moc.cxx 
 
 nodist_libGroupGUI_la_SOURCES =        \