Salome HOME
IPAL54678: TC-9.5.0: Sub-mesh priority: not all sub-meshes are displayed in the dialog
authoreap <eap@opencascade.com>
Tue, 26 May 2020 16:20:30 +0000 (19:20 +0300)
committereap <eap@opencascade.com>
Tue, 26 May 2020 16:20:30 +0000 (19:20 +0300)
+ 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

14 files changed:
resources/CMakeLists.txt
resources/mesh_auto_colors.png [new file with mode: 0644]
resources/mesh_compute_error.png [new file with mode: 0644]
resources/mesh_export.png [new file with mode: 0644]
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
src/SMESHGUI/SMESHGUI_ComputeDlg.h
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESHGUI_Operations.h
src/SMESHGUI/SMESHGUI_Selection.cxx
src/SMESHGUI/SMESHGUI_Selection.h
src/SMESHGUI/SMESH_images.ts
src/SMESHGUI/SMESH_msg_en.ts
src/SMESH_I/SMESH_Mesh_i.cxx

index e6d26d4..fe0d107 100644 (file)
@@ -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 (file)
index 0000000..7c4dc29
Binary files /dev/null and b/resources/mesh_auto_colors.png differ
diff --git a/resources/mesh_compute_error.png b/resources/mesh_compute_error.png
new file mode 100644 (file)
index 0000000..0cea548
Binary files /dev/null and b/resources/mesh_compute_error.png differ
diff --git a/resources/mesh_export.png b/resources/mesh_export.png
new file mode 100644 (file)
index 0000000..3b0d820
Binary files /dev/null and b/resources/mesh_export.png differ
index 2886278..f638d03 100644 (file)
@@ -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;
   }
 
index 76b91dd..a7cb0d0 100644 (file)
@@ -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();
@@ -667,6 +685,23 @@ SMESH::SMESH_Mesh_ptr SMESHGUI_BaseComputeOp::getMesh()
 
 //================================================================================
 /*!
+ * \brief check the same operations on the same mesh
+ */
+//================================================================================
+
+bool SMESHGUI_BaseComputeOp::isValid(  SUIT_Operation* theOp  ) const
+{
+  SMESHGUI_BaseComputeOp* baseOp = dynamic_cast<SMESHGUI_BaseComputeOp*>( 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
  * \purpose Init dialog fields, connect signals and slots, show dialog
  */
@@ -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 ) {
@@ -1554,23 +1590,6 @@ void SMESHGUI_ComputeOp::startOperation()
 
 //================================================================================
 /*!
- * \brief check the same operations on the same mesh
- */
-//================================================================================
-
-bool SMESHGUI_BaseComputeOp::isValid(  SUIT_Operation* theOp  ) const
-{
-  SMESHGUI_BaseComputeOp* baseOp = dynamic_cast<SMESHGUI_BaseComputeOp*>( 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
  * \retval LightApp_Dialog* - pointer to 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;
+}
index bcac87d..c72fb09 100644 (file)
@@ -72,6 +72,7 @@ public:
   virtual ~SMESHGUI_BaseComputeOp();
 
   SMESH::SMESH_Mesh_ptr          getMesh();
+  virtual LightApp_Dialog*       dlg() const;
 
 protected:
   virtual void                   startOperation();
@@ -205,6 +206,20 @@ 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;
index cb3185b..f143b01 100644 (file)
@@ -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;
 }
 
index b817815..2782458 100644 (file)
@@ -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
index 6f59abd..fdf9a8d 100644 (file)
@@ -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<int,int> 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
index 5d23e76..b972710 100644 (file)
@@ -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;
index 9f0e4a7..932d60f 100644 (file)
             <translation>mesh_compute.png</translation>
         </message>
         <message>
+            <source>ICON_SHOW_ERRORS</source>
+            <translation>mesh_compute_error.png</translation>
+        </message>
+        <message>
             <source>ICON_OVL_MESH_QUALITY</source>
             <translation>mesh_quality.png</translation>
         </message>
             <translation>mesh_cutquad.png</translation>
         </message>
         <message>
+            <source>ICON_EXPORT</source>
+            <translation>mesh_export.png</translation>
+        </message>
+        <message>
+            <source>ICON_AUTO_COLOR</source>
+            <translation>mesh_auto_colors.png</translation>
+        </message>
+        <message>
+            <source>ICON_DISABLE_AUTO_COLOR</source>
+            <translation>mesh_auto_colors.png</translation>
+        </message>
+        <message>
             <source>ICON_DELETE</source>
             <translation>delete.png</translation>
         </message>
index eba5718..ccad871 100644 (file)
         <translation>Compute</translation>
     </message>
     <message>
+        <source>MEN_RE_COMPUTE</source>
+        <translation>Clear + Compute</translation>
+    </message>
+    <message>
+        <source>MEN_SHOW_ERRORS</source>
+        <translation>Show Compute Errors</translation>
+    </message>
+    <message>
         <source>MEN_COMPUTE_SUBMESH</source>
         <translation>Compute Sub-mesh</translation>
     </message>
index 52f7e9e..b24e3ba 100644 (file)
@@ -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<const SMESHDS_Hypothesis*> _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 <const SMESHDS_Hypothesis*>& 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 <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
+        // the submesh can concurrent at <dim> (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++ )