From 19720c1ef8ed1ff65a87ae63b7fff432b924b2f3 Mon Sep 17 00:00:00 2001 From: eap Date: Tue, 26 May 2020 19:20:30 +0300 Subject: [PATCH] IPAL54678: TC-9.5.0: Sub-mesh priority: not all sub-meshes are displayed in the dialog + Small improvement of a mesh context menu: * Add "Clear + Compute" for a non-empty mesh * Add "Show Compute Errors" for a failed meshing * Remove "Compute" for a fully computed mesh * Add an icon for "Export" item --- resources/CMakeLists.txt | 3 + resources/mesh_auto_colors.png | Bin 0 -> 652 bytes resources/mesh_compute_error.png | Bin 0 -> 724 bytes resources/mesh_export.png | Bin 0 -> 196 bytes src/SMESHGUI/SMESHGUI.cxx | 131 ++++++++++++++++----------- src/SMESHGUI/SMESHGUI_ComputeDlg.cxx | 97 ++++++++++++++++---- src/SMESHGUI/SMESHGUI_ComputeDlg.h | 16 ++++ src/SMESHGUI/SMESHGUI_MeshOp.cxx | 5 + src/SMESHGUI/SMESHGUI_Operations.h | 2 + src/SMESHGUI/SMESHGUI_Selection.cxx | 60 ++++++++++-- src/SMESHGUI/SMESHGUI_Selection.h | 2 + src/SMESHGUI/SMESH_images.ts | 16 ++++ src/SMESHGUI/SMESH_msg_en.ts | 8 ++ src/SMESH_I/SMESH_Mesh_i.cxx | 42 +++++---- 14 files changed, 281 insertions(+), 101 deletions(-) create mode 100644 resources/mesh_auto_colors.png create mode 100644 resources/mesh_compute_error.png create mode 100644 resources/mesh_export.png diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index e6d26d4e4..fe0d107fb 100644 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -44,6 +44,7 @@ SET(SMESH_RESOURCES_FILES mesh_area.png mesh_aspect.png mesh_aspect_3d.png + mesh_auto_colors.png mesh_ball.png mesh_biquad_quadrangle.png mesh_biquad_triangle.png @@ -53,6 +54,7 @@ SET(SMESH_RESOURCES_FILES mesh_choose_all.png mesh_clear.png mesh_compute.png + mesh_compute_error.png mesh_conv_to_quad.png mesh_cutGroups.png mesh_cutquad.png @@ -71,6 +73,7 @@ SET(SMESH_RESOURCES_FILES mesh_equal_node.png mesh_equal_volume.png mesh_evaluate.png + mesh_export.png mesh_extmeth_face_offset.png mesh_extmeth_node_offset.png mesh_extmeth_surf_offset_smooth.png diff --git a/resources/mesh_auto_colors.png b/resources/mesh_auto_colors.png new file mode 100644 index 0000000000000000000000000000000000000000..7c4dc29c7a82236d0727989d77c6502d482747bc GIT binary patch literal 652 zcmV;70(1R|P)+@2%^*T> zWbAa@*Sd0!dhzO6QPOaqj;D_@M@^4HxLY~arQjTRDVWV3d%hzUPeGxNf@2jD-$u`e zea7U58jX)L!6uZ+r0$yB9w0}&D6pWDj?~3t5W9gXfmX1p3#ZOf=N-!&NhB^+MPn2vToHp~Xd{xB zXjLX^nOUisWrjLB4z?g#SeOI-ENu2`ayVsaPSGYZUkzxABZo|_g<~hIh}1;-=rGw5 mjAQF7{)-h!T~dVxCx+ipF(s5UoPtXL0000cOXqAi^Sg>mdjvEdNJDrIjDl6JAo3;OcfB#yWP2fKlv0QPcbI)-e z8Ro*~zRUj%n7vVR(QMm%MidfYoRgP|TL#bmHNexpYoorX^tr`m0$3XKt2lh`>9Ud& z4`2Kd;O(l@5R}Pjty*79dqW^d1FXh*xJDu_f#WxnwDhNz2VAdeu-fbH%`dvqF;I>~ zibd-|1{T(f$;aNtO|65D-vWF+wMH^)RWz%zP|=4^1>knS!_(fiik=#tMKUg!N{=~W zzXbTZYC83m2by#%{ED{OM-hoeF+WhC=;#80i4o7u?dQgue*y%$Yu9KCwtOJ-NvL_J za+YWJK;Q*1y%9xosSLaxVKDPHSkQ0>AAbaN?i@F4vsH1CXD}LgG1R(+Q$(tr;IVYH~y_6ljGLwZ6fdT~L3S)YL^X8;q< zK;xmFq(cD&udSwa_4{%~-%E(18X9$aV%Mz+8KA<^y(`lWVjPI12)$Z`{=V7B{`OcV z5xk&2sovXkRb~1NX(V`BpD#x&62@5DB#h>KBqDM&R)mfO=(!mBhw0Nq zw7Z-ocT`X!{YIWa$__XfjdJcO7qXA60}^or9bQm4v}ZpFo7JWHrN@(=KHi5|UgH zdHLmeNshrH?3e$Gq=LpkAQqz_aB@xVkt7K|CZY4t$(ApME-q$n32K7?0000<>&pIwRg_t^fc4 literal 0 HcmV?d00001 diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 28862787d..f638d0391 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -2870,8 +2870,24 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case SMESHOp::OpComputeSubMesh: case SMESHOp::OpPreCompute: case SMESHOp::OpEvaluate: + case SMESHOp::OpShowErrors: startOperation( theCommandID ); break; + case SMESHOp::OpRecompute: + { + if ( isStudyLocked() ) + break; + SALOME_ListIO selected; + if ( LightApp_SelectionMgr *sel = selectionMgr() ) + sel->selectedObjects( selected ); + if ( selected.Extent() == 1 ) { + SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( selected.First() ); + if ( !aMesh->_is_nil() ) + aMesh->Clear(); + startOperation( SMESHOp::OpCompute ); + } + } + break; case SMESHOp::OpCopyMesh: { if (isStudyLocked()) break; @@ -3998,7 +4014,7 @@ void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QStr if ( !icon_id.isEmpty() ) pix = resMgr->loadPixmap( "SMESH", tr( icon_id.toLatin1().data() ) ); else - pix = resMgr->loadPixmap( "SMESH", tr( QString( "ICO_%1" ).arg( po_id ).toLatin1().data() ), false ); + pix = resMgr->loadPixmap( "SMESH", tr( QString( "ICON_%1" ).arg( po_id ).toLatin1().data() ), false ); if ( !pix.isNull() ) icon = QIcon( pix ); @@ -4105,7 +4121,9 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( SMESHOp::OpCopyMesh, "COPY_MESH", "ICON_COPY_MESH" ); createSMESHAction( SMESHOp::OpCompute, "COMPUTE", "ICON_COMPUTE" ); createSMESHAction( SMESHOp::OpComputeSubMesh, "COMPUTE_SUBMESH", "ICON_COMPUTE" ); + createSMESHAction( SMESHOp::OpRecompute, "RE_COMPUTE", "ICON_COMPUTE" ); createSMESHAction( SMESHOp::OpPreCompute, "PRECOMPUTE", "ICON_PRECOMPUTE" ); + createSMESHAction( SMESHOp::OpShowErrors, "SHOW_ERRORS", "ICON_SHOW_ERRORS" ); createSMESHAction( SMESHOp::OpEvaluate, "EVALUATE", "ICON_EVALUATE" ); createSMESHAction( SMESHOp::OpMeshOrder, "MESH_ORDER", "ICON_MESH_ORDER"); createSMESHAction( SMESHOp::OpCreateGroup, "CREATE_GROUP", "ICON_CREATE_GROUP" ); @@ -4659,20 +4677,22 @@ void SMESHGUI::initialize( CAM_Application* app ) hasVolumes("({'Volume'} in elemTypes)"), hasFacesOrVolumes("(({'Face'} in elemTypes) || ({'Volume'} in elemTypes)) "); - createPopupItem( SMESHOp::OpFileInformation, OB, mesh, "&& selcount=1 && isImported" ); - createPopupItem( SMESHOp::OpCreateSubMesh, OB, mesh, "&& hasGeomReference"); createPopupItem( SMESHOp::OpEditMesh, OB, mesh, "&& selcount=1" ); + createPopupItem( SMESHOp::OpCreateSubMesh, OB, mesh, "&& hasGeomReference"); + createPopupItem( SMESHOp::OpMeshOrder, OB, mesh, "&& selcount=1 && hasAlgo && hasGeomReference" ); createPopupItem( SMESHOp::OpEditSubMesh, OB, subMesh, "&& selcount=1 && hasGeomReference" ); createPopupItem( SMESHOp::OpEditGroup, OB, group ); createPopupItem( SMESHOp::OpEditGeomGroupAsGroup, OB, group, "&& groupType != 'Group'" ); popupMgr()->insert( separator(), -1, 0 ); - createPopupItem( SMESHOp::OpCompute, OB, mesh, "&& selcount=1 && isComputable" ); - createPopupItem( SMESHOp::OpComputeSubMesh, OB, subMesh, "&& selcount=1 && isComputable" ); - createPopupItem( SMESHOp::OpPreCompute, OB, mesh, "&& selcount=1 && isPreComputable" ); - createPopupItem( SMESHOp::OpEvaluate, OB, mesh, "&& selcount=1 && isComputable" ); - createPopupItem( SMESHOp::OpMeshOrder, OB, mesh, "&& selcount=1 && isComputable && hasGeomReference" ); - createPopupItem( SMESHOp::OpUpdate, OB, mesh_part ); + createPopupItem( SMESHOp::OpCompute, OB, mesh, "&& selcount=1 && hasAlgo && isComputable" ); + createPopupItem( SMESHOp::OpRecompute, OB, mesh, "&& selcount=1 && hasAlgo && " + isNotEmpty ); + createPopupItem( SMESHOp::OpShowErrors, OB, mesh, "&& selcount=1 && hasErrors" ); + createPopupItem( SMESHOp::OpComputeSubMesh, OB, subMesh, "&& selcount=1 && hasAlgo && isComputable" ); + createPopupItem( SMESHOp::OpPreCompute, OB, mesh, "&& selcount=1 && hasAlgo && isPreComputable" ); + createPopupItem( SMESHOp::OpEvaluate, OB, mesh, "&& selcount=1 && hasAlgo && isComputable" ); + popupMgr()->insert( separator(), -1, 0 ); + createPopupItem( SMESHOp::OpFileInformation, OB, mesh, "&& selcount=1 && isImported" ); createPopupItem( SMESHOp::OpMeshInformation, OB, mesh_part ); createPopupItem( SMESHOp::OpFindElementByPoint,OB, mesh_group, "&& selcount=1" ); createPopupItem( SMESHOp::OpOverallMeshQuality,OB, mesh_part ); @@ -4686,8 +4706,8 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert( separator(), -1, 0 ); createPopupItem( SMESHOp::OpConvertMeshToQuadratic, OB, mesh_submesh ); createPopupItem( SMESHOp::OpCreateBoundaryElements, OB, mesh_group, "&& selcount=1 && dim>=2"); - popupMgr()->insert( separator(), -1, 0 ); - createPopupItem( SMESHOp::OpClearMesh, OB, mesh ); + //popupMgr()->insert( separator(), -1, 0 ); + //popupMgr()->insert( separator(), -1, 0 ); QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc ); @@ -4695,6 +4715,7 @@ void SMESHGUI::initialize( CAM_Application* app ) QString only_one_2D = only_one_non_empty + " && dim>1"; int anId = popupMgr()->insert( tr( "MEN_EXPORT" ), -1, -1 ); // EXPORT submenu + popupMgr()->findMenu( anId )->menuAction()->setIcon( resourceMgr()->loadPixmap( "SMESH", tr( "ICON_EXPORT" ))); createPopupItem( SMESHOp::OpPopupExportMED, OB, mesh_group, multiple_non_empty, anId ); createPopupItem( SMESHOp::OpPopupExportUNV, OB, mesh_group, only_one_non_empty, anId ); createPopupItem( SMESHOp::OpPopupExportSTL, OB, mesh_group, only_one_2D, anId ); @@ -4704,8 +4725,6 @@ void SMESHGUI::initialize( CAM_Application* app ) createPopupItem( SMESHOp::OpPopupExportSAUV, OB, mesh_group, only_one_non_empty, anId ); createPopupItem( SMESHOp::OpPopupExportGMF, OB, mesh_group, only_one_non_empty, anId ); createPopupItem( SMESHOp::OpPopupExportDAT, OB, mesh_group, only_one_non_empty, anId ); - createPopupItem( SMESHOp::OpDelete, OB, mesh_part + " " + hyp_alg ); - createPopupItem( SMESHOp::OpDeleteGroup, OB, group ); anId = popupMgr()->insert( tr( "MEN_IMPORT" ), -1, -1 ); // IMPORT submenu createPopupItem( SMESHOp::OpPopupImportMED, OB, smesh, "", anId ); @@ -4719,18 +4738,22 @@ void SMESHGUI::initialize( CAM_Application* app ) createPopupItem( SMESHOp::OpPopupImportDAT, OB, smesh, "", anId ); popupMgr()->insert( separator(), -1, 0 ); + createPopupItem( SMESHOp::OpClearMesh, OB, mesh ); + createPopupItem( SMESHOp::OpDelete, OB, mesh_part + " " + hyp_alg ); + createPopupItem( SMESHOp::OpDeleteGroup, OB, group ); + // popup for viewer createPopupItem( SMESHOp::OpEditGroup, View, group ); createPopupItem( SMESHOp::OpAddElemGroupPopup, View, elems, "&& guiState = 800" ); createPopupItem( SMESHOp::OpRemoveElemGroupPopup, View, elems, "&& guiState = 800" ); popupMgr()->insert( separator(), -1, 0 ); - createPopupItem( SMESHOp::OpUpdate, View, mesh_part ); createPopupItem( SMESHOp::OpMeshInformation, View, mesh_part ); createPopupItem( SMESHOp::OpOverallMeshQuality, View, mesh_part ); createPopupItem( SMESHOp::OpFindElementByPoint, View, mesh ); popupMgr()->insert( separator(), -1, 0 ); + createPopupItem( SMESHOp::OpUpdate, OB + " " + View, mesh_part ); createPopupItem( SMESHOp::OpAutoColor, OB + " " + View, mesh, "&& (not isAutoColor)" ); createPopupItem( SMESHOp::OpDisableAutoColor, OB + " " + View, mesh, "&& isAutoColor" ); popupMgr()->insert( separator(), -1, 0 ); @@ -5079,7 +5102,7 @@ bool SMESHGUI::isSelectionCompatible() bool SMESHGUI::reusableOperation( const int id ) { // compute, evaluate and precompute are not reusable operations - return ( id == SMESHOp::OpCompute || id == SMESHOp::OpPreCompute || id == SMESHOp::OpEvaluate ) ? false : SalomeApp_Module::reusableOperation( id ); + return ( id == SMESHOp::OpCompute || id == SMESHOp::OpPreCompute || id == SMESHOp::OpEvaluate || id == SMESHOp::OpRecompute ) ? false : SalomeApp_Module::reusableOperation( id ); } bool SMESHGUI::activateModule( SUIT_Study* study ) @@ -5831,55 +5854,55 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const // to do : create operation here switch( id ) { - case SMESHOp::OpSplitBiQuadratic: - op = new SMESHGUI_SplitBiQuadOp(); + case SMESHOp::OpSplitBiQuadratic: + op = new SMESHGUI_SplitBiQuadOp(); break; - case SMESHOp::OpConvertMeshToQuadratic: - op = new SMESHGUI_ConvToQuadOp(); + case SMESHOp::OpConvertMeshToQuadratic: + op = new SMESHGUI_ConvToQuadOp(); break; - case SMESHOp::OpCreateBoundaryElements: // create 2D mesh as boundary on 3D - op = new SMESHGUI_Make2DFrom3DOp(); + case SMESHOp::OpCreateBoundaryElements: // create 2D mesh as boundary on 3D + op = new SMESHGUI_Make2DFrom3DOp(); break; - case SMESHOp::OpReorientFaces: - op = new SMESHGUI_ReorientFacesOp(); - break; - case SMESHOp::OpCreateMesh: - op = new SMESHGUI_MeshOp( true, true ); + case SMESHOp::OpReorientFaces: + op = new SMESHGUI_ReorientFacesOp(); break; - case SMESHOp::OpCreateSubMesh: - op = new SMESHGUI_MeshOp( true, false ); + case SMESHOp::OpCreateMesh: + op = new SMESHGUI_MeshOp( true, true ); break; - case SMESHOp::OpEditMeshOrSubMesh: - case SMESHOp::OpEditMesh: - case SMESHOp::OpEditSubMesh: - op = new SMESHGUI_MeshOp( false ); + case SMESHOp::OpCreateSubMesh: + op = new SMESHGUI_MeshOp( true, false ); break; - case SMESHOp::OpCompute: - case SMESHOp::OpComputeSubMesh: - op = new SMESHGUI_ComputeOp(); + case SMESHOp::OpEditMeshOrSubMesh: + case SMESHOp::OpEditMesh: + case SMESHOp::OpEditSubMesh: + op = new SMESHGUI_MeshOp( false ); break; - case SMESHOp::OpPreCompute: - op = new SMESHGUI_PrecomputeOp(); + case SMESHOp::OpCompute: + case SMESHOp::OpComputeSubMesh: + op = new SMESHGUI_ComputeOp(); break; - case SMESHOp::OpEvaluate: - op = new SMESHGUI_EvaluateOp(); + case SMESHOp::OpPreCompute: + op = new SMESHGUI_PrecomputeOp(); break; - case SMESHOp::OpMeshOrder: - op = new SMESHGUI_MeshOrderOp(); + case SMESHOp::OpEvaluate: + op = new SMESHGUI_EvaluateOp(); break; - case SMESHOp::OpCreateGeometryGroup: - op = new SMESHGUI_GroupOnShapeOp(); - break; - case SMESHOp::OpFindElementByPoint: - op = new SMESHGUI_FindElemByPointOp(); - break; - case SMESHOp::OpMoveNode: // Make mesh pass through point - op = new SMESHGUI_MakeNodeAtPointOp(); - break; - case SMESHOp::OpElem0DOnElemNodes: // Create 0D elements on all nodes - op = new SMESHGUI_Add0DElemsOnAllNodesOp(); - break; - default: + case SMESHOp::OpMeshOrder: + op = new SMESHGUI_MeshOrderOp(); + break; + case SMESHOp::OpCreateGeometryGroup: + op = new SMESHGUI_GroupOnShapeOp(); + break; + case SMESHOp::OpFindElementByPoint: + op = new SMESHGUI_FindElemByPointOp(); + break; + case SMESHOp::OpMoveNode: // Make mesh pass through point + op = new SMESHGUI_MakeNodeAtPointOp(); + break; + case SMESHOp::OpElem0DOnElemNodes: // Create 0D elements on all nodes + op = new SMESHGUI_Add0DElemsOnAllNodesOp(); + break; + default: break; } diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx index 76b91dd9a..a7cb0d0dc 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx @@ -656,6 +656,24 @@ SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp() myHelpFileName = "about_meshes.html"; // V4 } +//================================================================================ +/*! + * \brief Gets dialog of this operation + * \retval LightApp_Dialog* - pointer to dialog of this operation + */ +//================================================================================ + +LightApp_Dialog* SMESHGUI_BaseComputeOp::dlg() const +{ + return myCompDlg; +} + +//================================================================================ +/*! + * \brief Return a selected mesh + */ +//================================================================================ + SMESH::SMESH_Mesh_ptr SMESHGUI_BaseComputeOp::getMesh() { LightApp_SelectionMgr* Sel = selectionMgr(); @@ -665,6 +683,23 @@ SMESH::SMESH_Mesh_ptr SMESHGUI_BaseComputeOp::getMesh() return myMesh->_is_nil() ? aMesh._retn() : SMESH::SMESH_Mesh::_duplicate( myMesh ); } +//================================================================================ +/*! + * \brief check the same operations on the same mesh + */ +//================================================================================ + +bool SMESHGUI_BaseComputeOp::isValid( SUIT_Operation* theOp ) const +{ + SMESHGUI_BaseComputeOp* baseOp = dynamic_cast( theOp ); + bool ret = true; + if ( !myMesh->_is_nil() && baseOp ) { + SMESH::SMESH_Mesh_var aMesh = baseOp->getMesh(); + if ( !aMesh->_is_nil() && aMesh->GetId() == myMesh->GetId() ) ret = false; + } + return ret; +} + //================================================================================ /*! * \brief Start operation @@ -720,6 +755,8 @@ void SMESHGUI_BaseComputeOp::startOperation() return; } + myCompDlg->myMeshName->setText( SMESH::GetName( myIObject )); + myMainShape = myMesh->GetShapeToMesh(); SMESHGUI_Operation::startOperation(); @@ -883,7 +920,6 @@ void SMESHGUI_BaseComputeOp::computeMesh() bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape; if ( shapeOK ) { - myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() ); SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen(); SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape); if ( errors->length() > 0 ) { @@ -1552,23 +1588,6 @@ void SMESHGUI_ComputeOp::startOperation() computeMesh(); } -//================================================================================ -/*! - * \brief check the same operations on the same mesh - */ -//================================================================================ - -bool SMESHGUI_BaseComputeOp::isValid( SUIT_Operation* theOp ) const -{ - SMESHGUI_BaseComputeOp* baseOp = dynamic_cast( theOp ); - bool ret = true; - if ( !myMesh->_is_nil() && baseOp ) { - SMESH::SMESH_Mesh_var aMesh = baseOp->getMesh(); - if ( !aMesh->_is_nil() && aMesh->GetId() == myMesh->GetId() ) ret = false; - } - return ret; -} - //================================================================================ /*! * \brief Gets dialog of this operation @@ -1956,7 +1975,6 @@ void SMESHGUI_PrecomputeOp::onPreview() bool computeFailed = true, memoryLack = false; SMESHGUI_ComputeDlg* aCompDlg = computeDlg(); - aCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() ); SMESHGUI* gui = getSMESHGUI(); SMESH::SMESH_Gen_var gen = gui->GetSMESHGen(); @@ -2203,7 +2221,6 @@ void SMESHGUI_BaseComputeOp::evaluateMesh() bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape; if ( shapeOK ) { - myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() ); SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen(); SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape); if ( errors->length() > 0 ) { @@ -2407,3 +2424,43 @@ SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::evaluateDlg() const return myCompDlg; } +//================================================================================ +/*! + * \brief SMESHGUI_BaseComputeOp constructor + */ +//================================================================================ + +SMESHGUI_ShowErrorsOp::SMESHGUI_ShowErrorsOp(): + SMESHGUI_BaseComputeOp() +{ +} + +//================================================================================ +/*! + * \brief Start SMESHGUI_ShowErrorsOp + */ +//================================================================================ + +void SMESHGUI_ShowErrorsOp::startOperation() +{ + SMESHGUI_BaseComputeOp::startOperation(); + + if ( myMesh->_is_nil() ) + return; + + SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen(); + SMESH::compute_error_array_var compErrors = gen->GetComputeErrors( myMesh, myMainShape ); + QString hypErrors; + if ( compErrors->length() == 0 ) + return; + + showComputeResult( /*MemoryLack=*/false, /*NoCompError=*/false, compErrors, + /*NoHypoError=*/true, hypErrors ); + + SMESHGUI_ComputeDlg* aCompDlg = computeDlg(); + aCompDlg->setWindowTitle( tr( "SMESH_WRN_COMPUTE_FAILED" )); + aCompDlg->myFullInfo->hide(); + aCompDlg->myBriefInfo->hide(); + + return; +} diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.h b/src/SMESHGUI/SMESHGUI_ComputeDlg.h index bcac87d09..c72fb097b 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.h +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.h @@ -72,6 +72,7 @@ public: virtual ~SMESHGUI_BaseComputeOp(); SMESH::SMESH_Mesh_ptr getMesh(); + virtual LightApp_Dialog* dlg() const; protected: virtual void startOperation(); @@ -204,6 +205,20 @@ protected: protected slots: }; +/*! + * \brief Operation to show meshing errors + */ +class SMESHGUI_EXPORT SMESHGUI_ShowErrorsOp: public SMESHGUI_BaseComputeOp +{ + Q_OBJECT + +public: + SMESHGUI_ShowErrorsOp(); + +protected: + virtual void startOperation(); +}; + /*! * \brief Dialog to compute a mesh and show computation errors */ @@ -236,6 +251,7 @@ protected: friend class SMESHGUI_BaseComputeOp; friend class SMESHGUI_PrecomputeOp; + friend class SMESHGUI_ShowErrorsOp; }; class SMESHGUI_MeshOrderBox; diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOp.cxx index cb3185b88..f143b0136 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshOp.cxx @@ -1913,6 +1913,7 @@ void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName ) if ( aHypoSet->toUseCommonSize() && !getAverageSize( myAverageSize )) return; + int maxDim = -1; for ( int isAlgo = 1; isAlgo >= 0; --isAlgo ) for ( aHypoSet->init( isAlgo, setType ); aHypoSet->more(); aHypoSet->next() ) { @@ -1930,6 +1931,7 @@ void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName ) { setCurrentHyp( myDim, Algo, index ); onAlgoSelected( index, myDim ); + maxDim = Max( maxDim, myDim ); } } else @@ -1963,6 +1965,9 @@ void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName ) } } + if ( maxDim > 0 ) + myDlg->setCurrentTab( maxDim ); + return; } diff --git a/src/SMESHGUI/SMESHGUI_Operations.h b/src/SMESHGUI/SMESHGUI_Operations.h index b81781593..2782458aa 100644 --- a/src/SMESHGUI/SMESHGUI_Operations.h +++ b/src/SMESHGUI/SMESHGUI_Operations.h @@ -77,6 +77,8 @@ namespace SMESHOp { OpPreCompute = 2042, // MENU MESH - PREVIEW OpEvaluate = 2043, // MENU MESH - EVALUATE OpMeshOrder = 2044, // MENU MESH - CHANGE SUBMESH PRIORITY + OpRecompute = 2045, // MENU MESH - Clear + COMPUTE + OpShowErrors = 2046, // MENU MESH - Show compute errors OpCreateGroup = 2050, // MENU MESH - CREATE GROUP OpCreateGeometryGroup = 2051, // MENU MESH - CREATE GROUPS FROM GEOMETRY OpConstructGroup = 2052, // MENU MESH - CONSTRUCT GROUP diff --git a/src/SMESHGUI/SMESHGUI_Selection.cxx b/src/SMESHGUI/SMESHGUI_Selection.cxx index 6f59abd8c..fdf9a8d1c 100644 --- a/src/SMESHGUI/SMESHGUI_Selection.cxx +++ b/src/SMESHGUI/SMESHGUI_Selection.cxx @@ -129,6 +129,8 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const else if ( p=="entityMode" ) val = QVariant( entityMode( ind ) ); else if ( p=="isNumFunctor" ) val = QVariant( isNumFunctor( ind ) ); else if ( p=="displayMode" ) val = QVariant( displayMode( ind ) ); + else if ( p=="hasAlgo" ) val = QVariant( hasAlgo( ind ) ); + else if ( p=="hasErrors" ) val = QVariant( hasErrors( ind ) ); else if ( p=="isComputable" ) val = QVariant( isComputable( ind ) ); else if ( p=="isPreComputable" ) val = QVariant( isPreComputable( ind ) ); else if ( p=="hasGeomReference" ) val = QVariant( hasGeomReference( ind ) ); @@ -548,22 +550,17 @@ int SMESHGUI_Selection::dim( int ind ) const } //======================================================================= -//function : isComputable -//purpose : return true for a ready-to-compute mesh +//function : hasAlgo +//purpose : return true for a ready-to-compute [sub-]mesh //======================================================================= -bool SMESHGUI_Selection::isComputable( int ind ) const +bool SMESHGUI_Selection::hasAlgo( int ind ) const { if ( ind >= 0 && ind < myTypes.count() && ( myTypes[ind] == "Mesh" || myTypes[ind].startsWith("Mesh " ))) { QMap modeMap; - _PTR(SObject) meshSO = SMESH::getStudy()->FindObjectID( entry( ind ).toUtf8().data() ); - - _PTR(SComponent) component = meshSO->GetFatherComponent(); - if ( meshSO->Depth() - component->Depth() > 1 ) // sub-mesh, get a mesh - while ( meshSO->Depth() - component->Depth() > 1 ) - meshSO = meshSO->GetFather(); + _PTR(SObject) meshSO = SMESH::getStudy()->FindObjectID( entry( ind ).toStdString() ); SMESHGUI_PrecomputeOp::getAssignedAlgos( meshSO, modeMap ); return modeMap.size() > 0; @@ -571,6 +568,51 @@ bool SMESHGUI_Selection::isComputable( int ind ) const return false; } + +//======================================================================= +//function : hasAlgo +//purpose : return true if a mesh was computed with errors +//======================================================================= + +bool SMESHGUI_Selection::hasErrors( int ind ) const +{ + if ( ind >= 0 && ind < myTypes.count() && ( myTypes[ind] == "Mesh")) + { + _PTR(SObject) meshSO = SMESH::getStudy()->FindObjectID( entry( ind ).toStdString() ); + CORBA::Object_var obj = SMESH::SObjectToObject( meshSO ); + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj ); + if ( !CORBA::is_nil( mesh ) ) + { + SMESH::SMESH_Gen_var gen = SMESHGUI::GetSMESHGUI()->GetSMESHGen(); + GEOM::GEOM_Object_var geom = mesh->GetShapeToMesh(); + SMESH::compute_error_array_var compErrors = gen->GetComputeErrors( mesh, geom ); + return compErrors->length(); + } + } + return false; +} + +//======================================================================= +//function : isComputable +//purpose : Return true if a [sub-]mesh does not have "computed" icon +//======================================================================= + +bool SMESHGUI_Selection::isComputable( int ind ) const +{ + if ( ind >= 0 && ind < myTypes.count() && ( myTypes[ind] == "Mesh" || + myTypes[ind].startsWith("Mesh " ))) + { + _PTR(GenericAttribute) attr; + if ( _PTR(SObject) meshSO = SMESH::getStudy()->FindObjectID( entry( ind ).toStdString() )) + if ( meshSO->FindAttribute( attr, "AttributePixMap" )) + { + _PTR(AttributePixMap) pixmap = attr; + return ( pixmap->GetPixMap() != "ICON_SMESH_TREE_MESH" ); + } + } + return false; +} + //======================================================================= //function : isPreComputable //purpose : returns true for a mesh with algorithms diff --git a/src/SMESHGUI/SMESHGUI_Selection.h b/src/SMESHGUI/SMESHGUI_Selection.h index 5d23e768f..b9727108f 100644 --- a/src/SMESHGUI/SMESHGUI_Selection.h +++ b/src/SMESHGUI/SMESHGUI_Selection.h @@ -58,6 +58,8 @@ public: virtual int numberOfNodes( int ) const; virtual int dim( int ) const; virtual bool isComputable( int ) const; + virtual bool hasAlgo( int ) const; + virtual bool hasErrors( int ) const; virtual bool isPreComputable( int ) const; virtual bool hasGeomReference( int ) const; virtual bool isEditableHyp( int ) const; diff --git a/src/SMESHGUI/SMESH_images.ts b/src/SMESHGUI/SMESH_images.ts index 9f0e4a777..932d60f07 100644 --- a/src/SMESHGUI/SMESH_images.ts +++ b/src/SMESHGUI/SMESH_images.ts @@ -43,6 +43,10 @@ ICON_COMPUTE mesh_compute.png + + ICON_SHOW_ERRORS + mesh_compute_error.png + ICON_OVL_MESH_QUALITY mesh_quality.png @@ -91,6 +95,18 @@ ICON_CUTQUAD mesh_cutquad.png + + ICON_EXPORT + mesh_export.png + + + ICON_AUTO_COLOR + mesh_auto_colors.png + + + ICON_DISABLE_AUTO_COLOR + mesh_auto_colors.png + ICON_DELETE delete.png diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index eba5718ed..ccad8714f 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -308,6 +308,14 @@ MEN_COMPUTE Compute + + MEN_RE_COMPUTE + Clear + Compute + + + MEN_SHOW_ERRORS + Show Compute Errors + MEN_COMPUTE_SUBMESH Compute Sub-mesh diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 52f7e9e9c..b24e3ba2d 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -568,7 +568,7 @@ namespace //================================================================================ /*! - * \brief Import data from a GMF file and Return an error description + * \brief Import data from a GMF file and return an error description */ //================================================================================ @@ -4972,7 +4972,7 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) //============================================================================= /*! * Return ID of nodes for given sub-mesh - * If param all==true - Return all nodes, else - + * If param all==true - return all nodes, else - * Return only nodes on shapes. */ //============================================================================= @@ -5079,7 +5079,7 @@ CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() //============================================================================= /*! * Get XYZ coordinates of node as list of double - * If there is not node for given ID - Return empty list + * If there is not node for given ID - return empty list */ //============================================================================= @@ -5109,8 +5109,8 @@ SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id) //============================================================================= /*! - * For given node Return list of IDs of inverse elements - * If there is not node for given ID - Return empty list + * For given node return list of IDs of inverse elements + * If there is not node for given ID - return empty list */ //============================================================================= @@ -5243,8 +5243,8 @@ SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID) //============================================================================= /*! - * If given element is node Return IDs of shape from position - * If there is not node for given ID - Return -1 + * If given element is node return IDs of shape from position + * If there is not node for given ID - return -1 */ //============================================================================= @@ -5271,7 +5271,7 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id) /*! * For given element return ID of result shape after * ::FindShape() from SMESH_MeshEditor - * If there is not element for given ID - Return -1 + * If there is not element for given ID - return -1 */ //============================================================================= @@ -5301,7 +5301,7 @@ CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id) //============================================================================= /*! * Return number of nodes for given element - * If there is not element for given ID - Return -1 + * If there is not element for given ID - return -1 */ //============================================================================= @@ -5322,8 +5322,8 @@ CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id) //============================================================================= /*! * Return ID of node by given index for given element - * If there is not element for given ID - Return -1 - * If there is not node for given index - Return -2 + * If there is not element for given ID - return -1 + * If there is not node for given index - return -2 */ //============================================================================= @@ -6045,7 +6045,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh() //================================================================================ /*! - * \brief Return false if GetMeshInfo() Return incorrect information that may + * \brief Return false if GetMeshInfo() return incorrect information that may * happen if mesh data is not yet fully loaded from the file of study. * * @@ -6425,7 +6425,7 @@ class SMESH_DimHyp //! fields int _dim; //!< a dimension the algo can build (concurrent dimension) int _ownDim; //!< dimension of shape of _subMesh (>=_dim) - TopTools_MapOfShape _shapeMap; + TopTools_MapOfShape _shapeMap; //!< [sub-]shapes of dimension == _dim SMESH_subMesh* _subMesh; list _hypotheses; //!< algo is first, then its parameters @@ -6522,9 +6522,11 @@ class SMESH_DimHyp bool isSame = checkAlgo( a1, a2 ); if ( !isSame ) { - if ( !a1 || !a2 ) - return false; // pb? - return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency ! + return true; + // commented off for IPAL54678 + // if ( !a1 || !a2 ) + // return false; // pb? + // return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency ! } // check hypothesises for concurrence (skip first as algorithm) @@ -6565,6 +6567,9 @@ void addDimHypInstance(const int theDim, const list & theHypList, TDimHypList* theDimHypListArr ) { + if ( !theAlgo->NeedDiscreteBoundary() && + theAlgo->NeedLowerHyps( theDim )) // IPAL54678 + return; TDimHypList& listOfdimHyp = theDimHypListArr[theDim]; if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) { SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape ); @@ -6707,7 +6712,7 @@ CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID) //============================================================================= /*! - * \brief Return submesh objects list in meshing order + * \brief Return sub-mesh objects list in meshing order */ //============================================================================= @@ -6776,7 +6781,8 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() continue; // no algorithm assigned to a current submesh int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp) - // the submesh can concurrent at (or lower dims if !anAlgo->NeedDiscreteBoundary()) + // the submesh can concurrent at (or lower dims if !anAlgo->NeedDiscreteBoundary() + // and !anAlgo->NeedLowerHyps( dim )) // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ ) -- 2.30.2