From: jfa Date: Mon, 24 Sep 2012 11:54:41 +0000 (+0000) Subject: Mantis issue 0021703: [CEA 577] Boolean operations on groups. X-Git-Tag: V6_6_0a1~17 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=00621ab4f35ece96476fc358acf598d78ec0a95d;p=modules%2Fgeom.git Mantis issue 0021703: [CEA 577] Boolean operations on groups. --- 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 index 000000000..248eebaa5 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 index 000000000..0109f670c 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 index 000000000..9df9cd651 Binary files /dev/null and b/doc/salome/gui/GEOM/images/groups_union_dlg.png differ diff --git a/doc/salome/gui/GEOM/input/tui_test_others.doc b/doc/salome/gui/GEOM/input/tui_test_others.doc index 2b1b44c7c..e89f89957 100644 --- a/doc/salome/gui/GEOM/input/tui_test_others.doc +++ b/doc/salome/gui/GEOM/input/tui_test_others.doc @@ -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 diff --git a/doc/salome/gui/GEOM/input/tui_working_with_groups.doc b/doc/salome/gui/GEOM/input/tui_working_with_groups.doc index e608a0923..37813417c 100644 --- a/doc/salome/gui/GEOM/input/tui_working_with_groups.doc +++ b/doc/salome/gui/GEOM/input/tui_working_with_groups.doc @@ -2,7 +2,9 @@ \page tui_working_with_groups_page Working with Groups -

Creation of a group

+
+\anchor tui_create_groups_anchor +

Creation of a group

\code import geompy @@ -42,6 +44,8 @@ gg.createAndDisplayGO(id_group1) salome.sg.updateObjBrowser(1) \endcode +\anchor tui_edit_groups_anchor +

Adding an object to the group

\code @@ -107,4 +111,108 @@ gg.createAndDisplayGO(id_group1) salome.sg.updateObjBrowser(1) \endcode +
+\anchor tui_union_groups_anchor +

Union Groups

+ +\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 + +
+\anchor tui_intersect_groups_anchor +

Intersect Groups

+ +\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 + +
+\anchor tui_cut_groups_anchor +

Cut Groups

+ +\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 + */ diff --git a/doc/salome/gui/GEOM/input/working_with_groups.doc b/doc/salome/gui/GEOM/input/working_with_groups.doc index 07838d585..a09865efa 100644 --- a/doc/salome/gui/GEOM/input/working_with_groups.doc +++ b/doc/salome/gui/GEOM/input/working_with_groups.doc @@ -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. -

Create a group

+ + +
+\anchor create_groups_anchor +

Create a group

\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 New entity > Group > Create \n The following menu will appear: @@ -72,19 +84,29 @@ ShapeType), where MainShape is a shape for which the group is created, ShapeType is a type of shapes in the created group. \n Arguments: 1 Shape + Type of sub-shape. +Our TUI Scripts provide you with useful examples of +\ref tui_create_groups_anchor "Create a Group" operation. + Example: \image html image193.png "Groups on a cylinder" - -

Edit a group

+
+\anchor edit_groups_anchor +

Edit a group

\image html image57.png +This functionality is available in OCC viewer only. + To \b Edit an existing group in the main menu select New entity > Group > Edit. This menu is designed in the same way as the Create a group menu. +\n Dialog Box: + +\image html editgroup.png + \n The \b Result of the operation will be a \b GEOM_Object. \n TUI Command: @@ -101,11 +123,80 @@ the sub-shape to be removed from the group. \n Arguments: 1 Shape + its sub-shapes. -\n Dialog Box: +Our TUI Scripts provide you with useful examples of +\ref tui_edit_groups_anchor "Edit a Group" operation. -\image html editgroup.png +
+\anchor union_groups_anchor +

Union of groups

+ +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. + +To union groups: +
    +
  1. In the New Entity menu select the \b Group - Union Groups 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. +
  2. +
  3. Click the \b Apply or Apply and Close button to confirm creation of the group.
  4. +
+ +See Also a sample TUI Script of a +\ref tui_union_groups_anchor "Union of Groups" operation. + +
+\anchor intersect_groups_anchor +

Intersection of groups

+ +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. + +To intersect groups: +
    +
  1. In the New Entity menu select the \b Group - Intersect Groups 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. +
  2. +
  3. Click the \b Apply or Apply and Close button to confirm creation of the group.
  4. +
+ +See Also a sample TUI Script of an +\ref tui_intersect_groups_anchor "Intersection of Groups" operation. + +
+\anchor cut_groups_anchor +

Cut of groups

+ +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. + +To cut groups: +
    +
  1. In the New Entity menu select the \b Group - Cut Groups 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. +
  2. +
  3. Click the \b Apply or Apply and Close button to confirm creation of the +group.
  4. +
Our TUI Scripts provide you with useful examples of -\ref tui_working_with_groups_page "Working with Groups". +\ref tui_cut_groups_anchor "Cut of Groups" operation. */ diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index be98cf9eb..e8c5cc4dc 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -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. diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index d9459fdc2..96b164f7b 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -771,6 +771,10 @@ ICO_COMMON common.png + + ICO_GROUP_INTERSECT + common.png + ICO_COMPOUND build_compound.png @@ -791,6 +795,10 @@ ICO_CUT cut.png + + ICO_GROUP_CUT + cut.png + ICO_CYLINDER cylinder.png @@ -895,6 +903,10 @@ ICO_FUSE fuse.png + + ICO_GROUP_UNION + fuse.png + ICO_GLUE_FACES glue.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 26c1f8b80..71fe07144 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -2574,6 +2574,18 @@ Please, select face, shell or solid and try again MEN_GROUP_EDIT Edit + + MEN_GROUP_UNION + Union Groups + + + MEN_GROUP_INTERSECT + Intersect Groups + + + MEN_GROUP_CUT + Cut Groups + MEN_RELOAD_IMPORTED Reload From Disk @@ -3350,6 +3362,18 @@ Please, select face, shell or solid and try again STB_GROUP_EDIT Edit a group + + STB_GROUP_UNION + Union Groups + + + STB_GROUP_INTERSECT + Intersect Groups + + + STB_GROUP_CUT + Cut Groups + STB_RELOAD_IMPORTED Reload imported shape from its original place on disk @@ -3950,6 +3974,18 @@ Please, select face, shell or solid and try again TOP_GROUP_EDIT Edit a group + + TOP_GROUP_UNION + Union Groups + + + TOP_GROUP_INTERSECT + Intersect Groups + + + TOP_GROUP_CUT + Cut Groups + TOP_HEX_SOLID Hexahedral Solid @@ -5069,6 +5105,45 @@ Number of sketch points too small Please, select a group to edit + + GroupGUI_BooleanDlg + + GEOM_UNION + Union + + + GEOM_UNION_TITLE + Union Groups + + + GEOM_INTERSECT + Intersect + + + GEOM_INTERSECT_TITLE + Intersect Groups + + + GEOM_CUT + Cut + + + GEOM_CUT_TITLE + Cut Groups + + + GEOM_GROUPS + Groups + + + GEOM_MAIN_GROUPS + Main Groups + + + GEOM_TOOL_GROUPS + Tool Groups + + GroupGUI_GroupDlg diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index b59220aad..10eae6910 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -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 diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index 9cb259b5d..89bb954d5 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -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 diff --git a/src/GEOMImpl/GEOMImpl_IGroupOperations.cxx b/src/GEOMImpl/GEOMImpl_IGroupOperations.cxx index db55c72b6..dc47e1f0e 100644 --- a/src/GEOMImpl/GEOMImpl_IGroupOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IGroupOperations.cxx @@ -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 @@ -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 diff --git a/src/GEOMImpl/GEOMImpl_IGroupOperations.hxx b/src/GEOMImpl/GEOMImpl_IGroupOperations.hxx index 0b6a89110..6b8d485ec 100644 --- a/src/GEOMImpl/GEOMImpl_IGroupOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IGroupOperations.hxx @@ -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 -#include +#include #include #include @@ -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); diff --git a/src/GEOM_I/GEOM_IGroupOperations_i.cc b/src/GEOM_I/GEOM_IGroupOperations_i.cc index 3a8cef597..60a26e129 100644 --- a/src/GEOM_I/GEOM_IGroupOperations_i.cc +++ b/src/GEOM_I/GEOM_IGroupOperations_i.cc @@ -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 @@ -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); } //============================================================================= diff --git a/src/GEOM_I/GEOM_IGroupOperations_i.hh b/src/GEOM_I/GEOM_IGroupOperations_i.hh index b3871e0fe..f213e8be2 100644 --- a/src/GEOM_I/GEOM_IGroupOperations_i.hh +++ b/src/GEOM_I/GEOM_IGroupOperations_i.hh @@ -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 @@ -33,17 +32,17 @@ #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); diff --git a/src/GEOM_SWIG/GEOM_TestOthers.py b/src/GEOM_SWIG/GEOM_TestOthers.py index 73d91287d..9eee4f171 100644 --- a/src/GEOM_SWIG/GEOM_TestOthers.py +++ b/src/GEOM_SWIG/GEOM_TestOthers.py @@ -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 # ----------------------------------------------------------------------------- diff --git a/src/GEOM_SWIG/geompyDC.py b/src/GEOM_SWIG/geompyDC.py index 33817a1b8..ed0c12272 100644 --- a/src/GEOM_SWIG/geompyDC.py +++ b/src/GEOM_SWIG/geompyDC.py @@ -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 # diff --git a/src/GroupGUI/GroupGUI.cxx b/src/GroupGUI/GroupGUI.cxx index 990263407..d8f92294f 100644 --- a/src/GroupGUI/GroupGUI.cxx +++ b/src/GroupGUI/GroupGUI.cxx @@ -18,14 +18,14 @@ // 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 #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( app->activeStudy() ); - if ( !appStudy ) return false; + SalomeApp_Study* appStudy = dynamic_cast(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 index 000000000..3c227e0c7 --- /dev/null +++ b/src/GroupGUI/GroupGUI_BooleanDlg.cxx @@ -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 +#include +#include + +#include +#include +#include +#include + +#include + +//================================================================================= +// 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 index 000000000..467130eec --- /dev/null +++ b/src/GroupGUI/GroupGUI_BooleanDlg.h @@ -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 diff --git a/src/GroupGUI/Makefile.am b/src/GroupGUI/Makefile.am index 068c3587a..78e540589 100755 --- a/src/GroupGUI/Makefile.am +++ b/src/GroupGUI/Makefile.am @@ -15,13 +15,11 @@ # 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 = \