Version: 6.3.1

src/SMESHGUI/SMESHGUI_ComputeDlg.cxx

Go to the documentation of this file.
00001 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 // File   : SMESHGUI_ComputeDlg.cxx
00021 // Author : Edward AGAPOV, Open CASCADE S.A.S.
00022 // SMESH includes
00023 //
00024 #include "SMESHGUI_ComputeDlg.h"
00025 
00026 #include "SMESHGUI.h"
00027 #include "SMESHGUI_GEOMGenUtils.h"
00028 #include "SMESHGUI_MeshUtils.h"
00029 #include "SMESHGUI_VTKUtils.h"
00030 #include "SMESHGUI_MeshInfosBox.h"
00031 #include "SMESHGUI_HypothesesUtils.h"
00032 #include "SMESHGUI_MeshEditPreview.h"
00033 #include "SMESHGUI_MeshOrderOp.h"
00034 #include "SMESHGUI_MeshOrderDlg.h"
00035 
00036 #include "SMESH_ActorUtils.h"
00037 
00038 #include <SMDS_SetIterator.hxx>
00039 #include <SMDS_Mesh.hxx>
00040 
00041 // SALOME GEOM includes
00042 #include <GEOMBase.h>
00043 #include <GEOM_Actor.h>
00044 
00045 // SALOME GUI includes
00046 #include <LightApp_SelectionMgr.h>
00047 #include <LightApp_UpdateFlags.h>
00048 #include <SALOME_ListIO.hxx>
00049 #include <SVTK_ViewWindow.h>
00050 #include <SVTK_ViewModel.h>
00051 #include <SalomeApp_Application.h>
00052 #include <SUIT_ResourceMgr.h>
00053 #include <SUIT_OverrideCursor.h>
00054 #include <SUIT_MessageBox.h>
00055 #include <SUIT_Desktop.h>
00056 #include <QtxComboBox.h>
00057 
00058 // SALOME KERNEL includes
00059 #include <SALOMEDS_SObject.hxx>
00060 #include <SALOMEDSClient_SObject.hxx>
00061 
00062 // OCCT includes
00063 #include <BRep_Tool.hxx>
00064 #include <TopExp.hxx>
00065 #include <TopExp_Explorer.hxx>
00066 #include <TopTools_IndexedMapOfShape.hxx>
00067 #include <TopoDS.hxx>
00068 
00069 #include <TopLoc_Location.hxx>
00070 #include <Poly_Triangulation.hxx>
00071 #include <Bnd_Box.hxx>
00072 #include <BRepBndLib.hxx>
00073 #include <BRepMesh_IncrementalMesh.hxx>
00074 
00075 #include <Standard_ErrorHandler.hxx>
00076 
00077 // Qt includes
00078 #include <QFrame>
00079 #include <QPushButton>
00080 #include <QLabel>
00081 #include <QRadioButton>
00082 #include <QTableWidget>
00083 #include <QHeaderView>
00084 #include <QGridLayout>
00085 #include <QHBoxLayout>
00086 #include <QVBoxLayout>
00087 #include <QButtonGroup>
00088 #include <QCloseEvent>
00089 #include <QTimerEvent>
00090 
00091 // VTK includes
00092 #include <vtkProperty.h>
00093 
00094 // STL includes
00095 #include <vector>
00096 #include <set>
00097 
00098 #define SPACING 6
00099 #define MARGIN  11
00100 
00101 #define COLONIZE(str)   (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" )
00102 
00103 /* OBSOLETE
00104 static void addSeparator( QWidget* parent )
00105 {
00106   QGridLayout* l = qobject_cast<QGridLayout*>( parent->layout() );
00107   int row  = l->rowCount();
00108   int cols = l->columnCount();
00109   for ( int i = 0; i < cols; i++ ) {
00110     QFrame* hline = new QFrame( parent );
00111     hline->setFrameStyle( QFrame::HLine | QFrame::Sunken );
00112     l->addWidget( hline, row, i );
00113   }
00114 }
00115 */
00116 
00117 enum TCol {
00118   COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, COL_BAD_MESH, NB_COLUMNS
00119 };
00120 
00121 //using namespace SMESH;
00122 
00123 namespace SMESH
00124 {
00125   //=============================================================================
00131   //=============================================================================
00132 
00133   struct MemoryReserve
00134   {
00135     char* myBuf;
00136     MemoryReserve(): myBuf( new char[1024*1024*1] ){} // 1M
00137     void release() { delete [] myBuf; myBuf = 0; }
00138     ~MemoryReserve() { release(); }
00139   };
00140 
00141   // =========================================================================================
00145   // =========================================================================================
00146 
00147   class TShapeDisplayer
00148   {
00149   public:
00150     // -----------------------------------------------------------------------
00151     TShapeDisplayer(): myViewWindow(0)
00152     {
00153       myProperty = vtkProperty::New();
00154       myProperty->SetRepresentationToWireframe();
00155       myProperty->SetColor( 250, 0, 250 );
00156       myProperty->SetAmbientColor( 250, 0, 250 );
00157       myProperty->SetDiffuseColor( 250, 0, 250 );
00158       //myProperty->SetSpecularColor( 250, 0, 250 );
00159       myProperty->SetLineWidth( 5 );
00160     }
00161     // -----------------------------------------------------------------------
00162     ~TShapeDisplayer()
00163     {
00164       DeleteActors();
00165       myProperty->Delete();
00166     }
00167     // -----------------------------------------------------------------------
00168     void DeleteActors()
00169     {
00170       if ( hasViewWindow() ) {
00171         TActorIterator actorIt = actorIterator();
00172         while ( actorIt.more() )
00173           if (VTKViewer_Actor* anActor = actorIt.next()) {
00174             myViewWindow->RemoveActor( anActor );
00175             //anActor->Delete();
00176           }
00177       }
00178       myIndexToShape.Clear();
00179       myActors.clear();
00180       myShownActors.clear();
00181       myBuiltSubs.clear();
00182     }
00183     // -----------------------------------------------------------------------
00184     void SetVisibility (bool theVisibility)
00185     {
00186       TActorIterator actorIt = shownIterator();
00187       while ( actorIt.more() )
00188         if (VTKViewer_Actor* anActor = actorIt.next())
00189           anActor->SetVisibility(theVisibility);
00190       SMESH::RepaintCurrentView();
00191     }
00192     // -----------------------------------------------------------------------
00193     bool HasReadyActorsFor (int subShapeID, GEOM::GEOM_Object_var aMainShape )
00194     {
00195       std::string mainEntry;
00196       if ( !aMainShape->_is_nil() )
00197         mainEntry = aMainShape->GetStudyEntry();
00198       return ( myMainEntry == mainEntry &&
00199                myBuiltSubs.find( subShapeID ) != myBuiltSubs.end() );
00200     }
00201     // -----------------------------------------------------------------------
00202     void Show( int subShapeID, GEOM::GEOM_Object_var aMainShape, bool only = false)
00203     {
00204       SVTK_ViewWindow* aViewWindow  = SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() );
00205       std::string mainEntry;
00206       if ( !aMainShape->_is_nil() )
00207         mainEntry = aMainShape->GetStudyEntry();
00208       if ( myMainEntry != mainEntry || aViewWindow != myViewWindow ) { // remove actors
00209         DeleteActors();
00210         TopoDS_Shape aShape;
00211         if ( !aMainShape->_is_nil() && GEOMBase::GetShape(aMainShape, aShape)) {
00212           checkTriangulation( aShape );
00213           TopExp::MapShapes(aShape, myIndexToShape);
00214           myActors.resize( myIndexToShape.Extent(), 0 );
00215           myShownActors.reserve( myIndexToShape.Extent() );
00216         }
00217         myMainEntry  = mainEntry;
00218         myViewWindow = aViewWindow;
00219       }
00220       if ( only ) { // hide shown actors
00221         TActorIterator actorIt = shownIterator();
00222         while ( actorIt.more() )
00223           if (VTKViewer_Actor* anActor = actorIt.next())
00224             anActor->SetVisibility(false);
00225         myShownActors.clear();
00226       }
00227       // find actors to show
00228       TopoDS_Shape aShape = myIndexToShape( subShapeID );
00229       if ( !aShape.IsNull() ) {
00230         TopAbs_ShapeEnum type( aShape.ShapeType() >= TopAbs_WIRE ? TopAbs_EDGE : TopAbs_FACE );
00231         for ( TopExp_Explorer exp( aShape, type ); exp.More(); exp.Next() ) {
00232           //checkTriangulation( exp.Current() );
00233           if ( GEOM_Actor* anActor = getActor( exp.Current() ))
00234             myShownActors.push_back( anActor );
00235         }
00236         if ( type == TopAbs_FACE ) {
00237           for ( TopExp_Explorer exp( aShape, TopAbs_EDGE ); exp.More(); exp.Next() ) {
00238             const TopoDS_Edge & edge = TopoDS::Edge( exp.Current() );
00239             if ( !BRep_Tool::Degenerated( edge ))
00240               if ( GEOM_Actor* anActor = getActor( exp.Current() ))
00241                 myShownActors.push_back( anActor );
00242           }
00243         }
00244       }
00245       myBuiltSubs.insert( subShapeID );
00246       SetVisibility(true);
00247     }
00248     // -----------------------------------------------------------------------
00249 
00250   private:
00251 
00252     typedef std::vector<GEOM_Actor*> TActorVec;
00253     TActorVec                  myActors;
00254     TActorVec                  myShownActors;
00255     TopTools_IndexedMapOfShape myIndexToShape;
00256     std::string                myMainEntry;
00257     SVTK_ViewWindow*           myViewWindow;
00258     vtkProperty*               myProperty;
00259     std::set<int>              myBuiltSubs;
00260 
00261     // -----------------------------------------------------------------------
00262     typedef SMDS_SetIterator< GEOM_Actor*, TActorVec::const_iterator> TActorIterator;
00263     TActorIterator actorIterator() {
00264       return TActorIterator( myActors.begin(), myActors.end() );
00265     }
00266     TActorIterator shownIterator() {
00267       return TActorIterator( myShownActors.begin(), myShownActors.end() );
00268     }
00269     // -----------------------------------------------------------------------
00270     GEOM_Actor* getActor(const TopoDS_Shape& shape)
00271     {
00272       int index = myIndexToShape.FindIndex( shape ) - 1;
00273       if ( index < 0 || index >= myActors.size() )
00274         return 0;
00275       GEOM_Actor* & actor = myActors[ index ];
00276       if ( !actor ) {
00277         actor = GEOM_Actor::New();
00278         if ( actor ) {
00279           actor->SetShape(shape,0,0);
00280           actor->SetProperty(myProperty);
00281           actor->SetShadingProperty(myProperty);
00282           actor->SetWireframeProperty(myProperty);
00283           actor->SetPreviewProperty(myProperty);
00284           actor->PickableOff();
00285           //         if ( shape.ShapeType() == TopAbs_EDGE )
00286           //           actor->SubShapeOn();
00287           myViewWindow->AddActor( actor );
00288         }
00289       }
00290       return actor;
00291     }
00292     // -----------------------------------------------------------------------
00293     void checkTriangulation(const TopoDS_Shape& shape)
00294     {
00295       TopLoc_Location aLoc;
00296       Standard_Boolean alreadymesh = Standard_True;
00297       TopExp_Explorer ex(shape, TopAbs_FACE);
00298       if ( ex.More() )
00299         for ( ; ex.More(); ex.Next()) {
00300           const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
00301           Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
00302           if(aPoly.IsNull()) { alreadymesh = Standard_False; break; }
00303         }
00304       else
00305         for (ex.Init(shape, TopAbs_EDGE); ex.More(); ex.Next()) {
00306           const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
00307           Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D(edge, aLoc);
00308           if(aPoly.IsNull()) { alreadymesh = Standard_False; break; }
00309         }
00310       if (alreadymesh) return;
00311       // Compute default deflection
00312       Bnd_Box B;
00313       BRepBndLib::Add(shape, B);
00314       Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
00315       B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
00316       double deflection = Max( aXmax-aXmin, Max ( aYmax-aYmin, aZmax-aZmin)) * 0.01 *4;
00317       BRepMesh_IncrementalMesh MESH(shape,deflection);
00318     }
00319     // -----------------------------------------------------------------------
00320     bool hasViewWindow() const
00321     {
00322       if ( !myViewWindow ) return false;
00323 
00324       if ( SalomeApp_Application* anApp = SMESHGUI::GetSMESHGUI()->getApp() )
00325         return FindVtkViewWindow( anApp->getViewManager(SVTK_Viewer::Type(), false ),
00326                                   myViewWindow );
00327       return false;
00328     }
00329   };
00330 
00331   // =========================================================================================
00335 #define CASE2TEXT(enum) case SMESH::enum: text = QObject::tr( #enum ); break;
00336   QString errorText(int errCode, const char* comment)
00337   {
00338     QString text;
00339     switch ( errCode ) {
00340       CASE2TEXT( COMPERR_OK            );
00341       CASE2TEXT( COMPERR_BAD_INPUT_MESH);
00342       CASE2TEXT( COMPERR_STD_EXCEPTION );
00343       CASE2TEXT( COMPERR_OCC_EXCEPTION );
00344     case SMESH::COMPERR_SLM_EXCEPTION: break; // avoid double "Salome exception"
00345       CASE2TEXT( COMPERR_EXCEPTION     );
00346       CASE2TEXT( COMPERR_MEMORY_PB     );
00347       CASE2TEXT( COMPERR_BAD_SHAPE     );
00348     case SMESH::COMPERR_ALGO_FAILED:
00349       if ( strlen(comment) == 0 )
00350         text = QObject::tr("COMPERR_ALGO_FAILED");
00351       break;
00352     default:
00353       text = QString("#%1").arg( -errCode );
00354     }
00355     if ( text.length() > 0 ) text += ". ";
00356     return text + comment;
00357   }
00358   // -----------------------------------------------------------------------
00362   _PTR(SObject) getSubShapeSO( int subShapeID, GEOM::GEOM_Object_var aMainShape)
00363   {
00364     _PTR(SObject) so = SMESH::FindSObject(aMainShape);
00365     if ( subShapeID == 1 || !so )
00366       return so;
00367     _PTR(ChildIterator) it;
00368     if (_PTR(Study) study = SMESH::GetActiveStudyDocument())
00369       it =  study->NewChildIterator(so);
00370     _PTR(SObject) subSO;
00371     if ( it ) {
00372       for ( it->InitEx(true); !subSO && it->More(); it->Next() ) {
00373         GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>( it->Value() );
00374         if ( !geom->_is_nil() ) {
00375           GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
00376           if ( list->length() == 1 && list[0] == subShapeID )
00377             subSO = it->Value();
00378         }
00379       }
00380     }
00381     return subSO;
00382   }
00383   // -----------------------------------------------------------------------
00387   GEOM::GEOM_Object_ptr getSubShape( int subShapeID, GEOM::GEOM_Object_var aMainShape)
00388   {
00389     GEOM::GEOM_Object_var aSubShape;
00390     if ( subShapeID == 1 )
00391       aSubShape = aMainShape;
00392     else if ( _PTR(SObject) so = getSubShapeSO( subShapeID, aMainShape ))
00393       aSubShape = SMESH::SObjectToInterface<GEOM::GEOM_Object>( so );
00394     else
00395       aSubShape = SMESH::GetSubShape( aMainShape, subShapeID );
00396     return aSubShape._retn();
00397   }
00398   // -----------------------------------------------------------------------
00402 #define CASE2NAME(enum) case GEOM::enum: name = QObject::tr( "GEOM_" #enum ); break;
00403   QString shapeTypeName(GEOM::GEOM_Object_var aShape, const char* dflt = "" )
00404   {
00405     QString name = dflt;
00406     if ( !aShape->_is_nil() ) {
00407       switch ( aShape->GetShapeType() ) {
00408       CASE2NAME( VERTEX    );
00409       CASE2NAME( EDGE      );
00410       CASE2NAME( WIRE      );
00411       CASE2NAME( FACE      );
00412       CASE2NAME( SHELL     );
00413       CASE2NAME( SOLID     );
00414       CASE2NAME( COMPSOLID );
00415       CASE2NAME( COMPOUND  );
00416       default:;
00417       }
00418     }
00419     return name;
00420   }
00421   // -----------------------------------------------------------------------
00425   QString shapeText(int subShapeID, GEOM::GEOM_Object_var aMainShape )
00426   {
00427     QString text;
00428     if ( _PTR(SObject) aSO = getSubShapeSO( subShapeID, aMainShape ))
00429       text = aSO->GetName().c_str();
00430     else {
00431       text = QString("#%1").arg( subShapeID );
00432       QString typeName = shapeTypeName( getSubShape( subShapeID, aMainShape ));
00433       if ( typeName.length() )
00434         text += QString(" (%1)").arg(typeName);
00435     }
00436     return text;
00437   }
00438   // -----------------------------------------------------------------------
00442   int getSelectedRows(QTableWidget* table, QList<int>& rows)
00443   {
00444     rows.clear();
00445     QList<QTableWidgetSelectionRange> selRanges = table->selectedRanges();
00446     QTableWidgetSelectionRange range;
00447     foreach( range, selRanges )
00448     {
00449       for ( int row = range.topRow(); row <= range.bottomRow(); ++row )
00450         rows.append( row );
00451     }
00452     if ( rows.isEmpty() && table->currentRow() > -1 )
00453       rows.append( table->currentRow() );
00454 
00455     return rows.count();
00456   }
00457 
00458 } // namespace SMESH
00459 
00460 
00461 // =========================================================================================
00465 //=======================================================================
00466 
00467 SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent, bool ForEval )
00468  : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ )
00469 {
00470   QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
00471   aDlgLay->setMargin( 0 );
00472   aDlgLay->setSpacing( SPACING );
00473 
00474   QFrame* aMainFrame = createMainFrame(mainFrame(),ForEval);
00475 
00476   aDlgLay->addWidget(aMainFrame);
00477 
00478   aDlgLay->setStretchFactor(aMainFrame, 1);
00479 }
00480 
00481 // =========================================================================================
00485 //=======================================================================
00486 
00487 SMESHGUI_ComputeDlg::~SMESHGUI_ComputeDlg()
00488 {
00489 }
00490 
00491 //=======================================================================
00492 // function : createMainFrame()
00493 // purpose  : Create frame containing dialog's fields
00494 //=======================================================================
00495 
00496 QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent, bool ForEval)
00497 {
00498   QFrame* aFrame = new QFrame(theParent);
00499 
00500   SUIT_ResourceMgr* rm = resourceMgr();
00501   QPixmap iconCompute (rm->loadPixmap("SMESH", tr("ICON_COMPUTE")));
00502 
00503   // constructor
00504 
00505   QGroupBox* aPixGrp;
00506   if(ForEval) {
00507     aPixGrp = new QGroupBox(tr("EVAL_DLG"), aFrame);
00508   }
00509   else {
00510     aPixGrp = new QGroupBox(tr("CONSTRUCTOR"), aFrame);
00511   }
00512   QButtonGroup* aBtnGrp = new QButtonGroup(this);
00513   QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp);
00514   aPixGrpLayout->setMargin(MARGIN); aPixGrpLayout->setSpacing(SPACING);
00515 
00516   QRadioButton* aRBut = new QRadioButton(aPixGrp);
00517   aRBut->setIcon(iconCompute);
00518   aRBut->setChecked(true);
00519   aPixGrpLayout->addWidget(aRBut);
00520   aBtnGrp->addButton(aRBut, 0);
00521 
00522   // Mesh name
00523 
00524   QGroupBox* nameBox = new QGroupBox(tr("SMESH_MESHINFO_NAME"), aFrame );
00525   QHBoxLayout* nameBoxLayout = new QHBoxLayout(nameBox);
00526   nameBoxLayout->setMargin(MARGIN); nameBoxLayout->setSpacing(SPACING);
00527   myMeshName = new QLabel(nameBox);
00528   nameBoxLayout->addWidget(myMeshName);
00529 
00530   // Mesh Info
00531 
00532   myBriefInfo = new SMESHGUI_MeshInfosBox(false, aFrame);
00533   myFullInfo  = new SMESHGUI_MeshInfosBox(true,  aFrame);
00534 
00535   // Computation errors
00536 
00537   myCompErrorGroup = new QGroupBox(tr("ERRORS"), aFrame);
00538   myTable      = new QTableWidget( 1, NB_COLUMNS, myCompErrorGroup);
00539   myShowBtn    = new QPushButton(tr("SHOW_SHAPE"), myCompErrorGroup);
00540   myPublishBtn = new QPushButton(tr("PUBLISH_SHAPE"), myCompErrorGroup);
00541   myBadMeshBtn = new QPushButton(tr("SHOW_BAD_MESH"), myCompErrorGroup);
00542 
00543   //myTable->setReadOnly( true ); // VSR: check
00544   myTable->setEditTriggers( QAbstractItemView::NoEditTriggers );
00545   myTable->hideColumn( COL_PUBLISHED );
00546   myTable->hideColumn( COL_SHAPEID );
00547   myTable->hideColumn( COL_BAD_MESH );
00548   myTable->horizontalHeader()->setResizeMode( COL_ERROR, QHeaderView::Interactive );
00549 
00550   QStringList headers;
00551   headers << tr( "COL_ALGO_HEADER" );
00552   headers << tr( "COL_SHAPE_HEADER" );
00553   headers << tr( "COL_ERROR_HEADER" );
00554   headers << tr( "COL_SHAPEID_HEADER" );
00555   headers << tr( "COL_PUBLISHED_HEADER" );
00556 
00557   myTable->setHorizontalHeaderLabels( headers );
00558 
00559   // layouting
00560   QGridLayout* grpLayout = new QGridLayout(myCompErrorGroup);
00561   grpLayout->setSpacing(SPACING);
00562   grpLayout->setMargin(MARGIN);
00563   grpLayout->addWidget( myTable,      0, 0, 4, 1 );
00564   grpLayout->addWidget( myShowBtn,    0, 1 );
00565   grpLayout->addWidget( myPublishBtn, 1, 1 );
00566   grpLayout->addWidget( myBadMeshBtn, 2, 1 );
00567   grpLayout->setRowStretch( 3, 1 );
00568 
00569   // Hypothesis definition errors
00570 
00571   myHypErrorGroup = new QGroupBox(tr("SMESH_WRN_MISSING_PARAMETERS"), aFrame);
00572   QHBoxLayout* myHypErrorGroupLayout = new QHBoxLayout(myHypErrorGroup);
00573   myHypErrorGroupLayout->setMargin(MARGIN);
00574   myHypErrorGroupLayout->setSpacing(SPACING);
00575   myHypErrorLabel = new QLabel(myHypErrorGroup);
00576   myHypErrorGroupLayout->addWidget(myHypErrorLabel);
00577 
00578   // Memory Lack Label
00579 
00580   myMemoryLackGroup = new QGroupBox(tr("ERRORS"), aFrame);
00581   QVBoxLayout* myMemoryLackGroupLayout = new QVBoxLayout(myMemoryLackGroup);
00582   myMemoryLackGroupLayout->setMargin(MARGIN);
00583   myMemoryLackGroupLayout->setSpacing(SPACING);
00584   QLabel* memLackLabel = new QLabel(tr("MEMORY_LACK"), myMemoryLackGroup);
00585   QFont bold = memLackLabel->font(); bold.setBold(true);
00586   memLackLabel->setFont( bold );
00587   memLackLabel->setMinimumWidth(300);
00588   myMemoryLackGroupLayout->addWidget(memLackLabel);
00589 
00590   // add all widgets to aFrame
00591   QVBoxLayout* aLay = new QVBoxLayout(aFrame);
00592   aLay->setMargin( 0 );
00593   aLay->setSpacing( 0 );
00594   aLay->addWidget( aPixGrp );
00595   aLay->addWidget( nameBox );
00596   aLay->addWidget( myBriefInfo );
00597   aLay->addWidget( myFullInfo );
00598   aLay->addWidget( myHypErrorGroup );
00599   aLay->addWidget( myCompErrorGroup );
00600   aLay->addWidget( myMemoryLackGroup );
00601   aLay->setStretchFactor( myCompErrorGroup, 1 );
00602 
00603   ((QPushButton*) button( OK ))->setDefault( true );
00604 
00605   return aFrame;
00606 }
00607 
00608 //================================================================================
00612 //================================================================================
00613 
00614 SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp()
00615   : SMESHGUI_Operation(), myCompDlg( 0 )
00616 {
00617   myTShapeDisplayer = new SMESH::TShapeDisplayer();
00618   myBadMeshDisplayer = 0;
00619 
00620   //myHelpFileName = "/files/about_meshes.htm"; // V3
00621   myHelpFileName = "about_meshes_page.html"; // V4
00622 }
00623 
00624 SMESH::SMESH_Mesh_ptr SMESHGUI_BaseComputeOp::getMesh()
00625 {
00626   LightApp_SelectionMgr* Sel = selectionMgr();
00627   SALOME_ListIO selected; Sel->selectedObjects( selected );
00628   Handle(SALOME_InteractiveObject) anIO = selected.First();
00629   SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(anIO);
00630   return myMesh->_is_nil() ? aMesh._retn() : SMESH::SMESH_Mesh::_duplicate( myMesh );
00631 }
00632 
00633 //================================================================================
00638 //================================================================================
00639 
00640 void SMESHGUI_BaseComputeOp::startOperation()
00641 {
00642   // create compute dialog if not created before
00643   computeDlg();
00644 
00645   myMesh      = SMESH::SMESH_Mesh::_nil();
00646   myMainShape = GEOM::GEOM_Object::_nil();
00647 
00648   // check selection
00649   LightApp_SelectionMgr *Sel = selectionMgr();
00650   SALOME_ListIO selected; Sel->selectedObjects( selected );
00651 
00652   int nbSel = selected.Extent();
00653   if (nbSel != 1) {
00654     SUIT_MessageBox::warning(desktop(),
00655                              tr("SMESH_WRN_WARNING"),
00656                              tr("SMESH_WRN_NO_AVAILABLE_DATA"));
00657     onCancel();
00658     return;
00659   }
00660 
00661   myIObject = selected.First();
00662   myMesh = SMESH::GetMeshByIO(myIObject);
00663   if (myMesh->_is_nil()) {
00664     SUIT_MessageBox::warning(desktop(),
00665                              tr("SMESH_WRN_WARNING"),
00666                              tr("SMESH_WRN_NO_AVAILABLE_DATA"));
00667     onCancel();
00668     return;
00669   }
00670   myMainShape = myMesh->GetShapeToMesh();
00671 
00672   SMESHGUI_Operation::startOperation();
00673 }
00674 
00675 //================================================================================
00676 //================================================================================
00677 
00678 SMESHGUI_ComputeDlg_QThread::SMESHGUI_ComputeDlg_QThread(SMESH::SMESH_Gen_var gen,
00679                                                          SMESH::SMESH_Mesh_var mesh,
00680                                                          GEOM::GEOM_Object_var mainShape)
00681 {
00682   myResult = false;
00683   myGen = gen;
00684   myMesh = mesh;
00685   myMainShape = mainShape;
00686 }
00687 
00688 void SMESHGUI_ComputeDlg_QThread::run()
00689 {
00690   myResult = myGen->Compute(myMesh, myMainShape);
00691 }
00692 
00693 bool SMESHGUI_ComputeDlg_QThread::result()
00694 {
00695   return myResult;
00696 }
00697 
00698 void SMESHGUI_ComputeDlg_QThread::cancel()
00699 {
00700   myGen->CancelCompute(myMesh, myMainShape);
00701 }
00702 
00703 //================================================================================
00704 //================================================================================
00705 
00706 SMESHGUI_ComputeDlg_QThreadQDialog::SMESHGUI_ComputeDlg_QThreadQDialog(QWidget *parent,
00707                                                                        SMESH::SMESH_Gen_var gen,
00708                                                                        SMESH::SMESH_Mesh_var mesh,
00709                                                                        GEOM::GEOM_Object_var mainShape)
00710   : QDialog(parent),
00711     qthread(gen, mesh, mainShape)
00712 {
00713   // --
00714   setWindowTitle(tr("Compute"));
00715   cancelButton = new QPushButton(tr("Cancel"));
00716   cancelButton->setDefault(true);
00717   connect(cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));
00718   QHBoxLayout *layout = new QHBoxLayout;
00719   layout->addWidget(cancelButton);
00720   setLayout(layout);
00721   resize(200, 50);
00722   // --
00723   startTimer(30); // 30 millisecs
00724   qthread.start();
00725 }
00726 
00727 bool SMESHGUI_ComputeDlg_QThreadQDialog::result()
00728 {
00729   return qthread.result();
00730 }
00731 
00732 void SMESHGUI_ComputeDlg_QThreadQDialog::onCancel()
00733 {
00734   qthread.cancel();
00735 }  
00736 
00737 void SMESHGUI_ComputeDlg_QThreadQDialog::timerEvent(QTimerEvent *event)
00738 {
00739   if(qthread.isFinished())
00740     {
00741       close();
00742     }
00743   event->accept();
00744 }
00745 
00746 void SMESHGUI_ComputeDlg_QThreadQDialog::closeEvent(QCloseEvent *event)
00747 {
00748   if(qthread.isRunning())
00749     {
00750       event->ignore();
00751       return;
00752     }
00753   event->accept();
00754 }
00755 
00756 //================================================================================
00760 //================================================================================
00761 
00762 void SMESHGUI_BaseComputeOp::computeMesh()
00763 {
00764   // COMPUTE MESH
00765 
00766   SMESH::MemoryReserve aMemoryReserve;
00767 
00768   SMESH::compute_error_array_var aCompErrors;
00769   QString                        aHypErrors;
00770 
00771   bool computeFailed = true, memoryLack = false;
00772 
00773   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
00774   if ( !aMeshSObj ) // IPAL 21340
00775     return;
00776   bool hasShape = myMesh->HasShapeToMesh();
00777   bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
00778   if ( shapeOK )
00779   {
00780     myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
00781     SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
00782     SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
00783     if ( errors->length() > 0 ) {
00784       aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
00785     }
00786     if ( myMesh->HasModificationsToDiscard() && // issue 0020693
00787          SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
00788                                     tr( "FULL_RECOMPUTE_QUESTION" ),
00789                                     tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 1, 0 ) == 0 )
00790       myMesh->Clear();
00791     SUIT_OverrideCursor aWaitCursor;
00792     try {
00793 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00794       OCC_CATCH_SIGNALS;
00795 #endif
00796       //SMESH::UpdateNulData(myIObject, true);
00797       bool res;
00798 #ifdef WITH_SMESH_CANCEL_COMPUTE
00799       SMESHGUI_ComputeDlg_QThreadQDialog qthreaddialog(desktop(), gen, myMesh, myMainShape);
00800       qthreaddialog.exec();
00801       res = qthreaddialog.result();
00802 #else
00803       res = gen->Compute(myMesh, myMainShape);
00804 #endif
00805       if (res)
00806         computeFailed = false;
00807     }
00808     catch(const SALOME::SALOME_Exception & S_ex){
00809       memoryLack = true;
00810     }
00811     try {
00812 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00813       OCC_CATCH_SIGNALS;
00814 #endif
00815       aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
00816       // check if there are memory problems
00817       for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
00818         memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB );
00819     }
00820     catch(const SALOME::SALOME_Exception & S_ex){
00821       memoryLack = true;
00822     }
00823 
00824     if ( !memoryLack && !SMDS_Mesh::CheckMemory(true) ) { // has memory to show dialog boxes?
00825       memoryLack = true;
00826     }
00827 
00828     // NPAL16631: if ( !memoryLack )
00829     {
00830       SMESH::ModifiedMesh(aMeshSObj, !computeFailed, myMesh->NbNodes() == 0);
00831       update( UF_ObjBrowser | UF_Model );
00832 
00833       // SHOW MESH
00834       // NPAL16631: if ( getSMESHGUI()->automaticUpdate() )
00835       SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
00836       long newSize = myMesh->NbElements();
00837       bool limitExceeded;
00838       if ( !memoryLack )
00839       {
00840         if ( getSMESHGUI()->automaticUpdate( newSize, &limitExceeded ) )
00841         {
00842           try {
00843 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00844             OCC_CATCH_SIGNALS;
00845 #endif
00846             SMESH::Update(myIObject, true);
00847           }
00848           catch (...) {
00849 #ifdef _DEBUG_
00850             MESSAGE ( "Exception thrown during mesh visualization" );
00851 #endif
00852             if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
00853               SMESH::OnVisuException();
00854             }
00855             else {
00856               memoryLack = true;
00857             }
00858           }
00859         }
00860         else if ( limitExceeded )
00861         {
00862           long limitSize = resMgr->integerValue( "SMESH", "update_limit", 500000 );
00863           SUIT_MessageBox::warning( desktop(),
00864                                     tr( "SMESH_WRN_WARNING" ),
00865                                     tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).arg( newSize ).arg( limitSize ) );
00866         }
00867       }
00868       LightApp_SelectionMgr *Sel = selectionMgr();
00869       if ( Sel )
00870       {
00871         SALOME_ListIO selected;
00872         selected.Append( myIObject );
00873         Sel->setSelectedObjects( selected );
00874       }
00875     }
00876   }
00877 
00878   if ( memoryLack )
00879     aMemoryReserve.release();
00880 
00881   myCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
00882 
00883   // SHOW ERRORS
00884   
00885   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
00886   bool noHypoError = ( aHypErrors.isEmpty() );
00887 
00888   SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
00889   int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
00890 
00891   bool isShowResultDlg = true;
00892   switch( aNotifyMode ) {
00893   case 0: // show the mesh computation result dialog NEVER
00894     isShowResultDlg = false;
00895     commit();
00896     break;
00897   case 1: // show the mesh computation result dialog if there are some errors
00898     if ( memoryLack || !noCompError || !noHypoError )
00899       isShowResultDlg = true;
00900     else
00901     {
00902       isShowResultDlg = false;
00903       commit();
00904     }
00905     break;
00906   default: // show the result dialog after each mesh computation
00907     isShowResultDlg = true;
00908   }
00909 
00910   // SHOW RESULTS
00911   if ( isShowResultDlg )
00912     showComputeResult( memoryLack, noCompError,aCompErrors, noHypoError, aHypErrors );
00913 }
00914 
00915 void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
00916                                                 const bool theNoCompError,
00917                                                 SMESH::compute_error_array_var& theCompErrors,
00918                                                 const bool theNoHypoError,
00919                                                 const QString& theHypErrors )
00920 {
00921   bool hasShape = myMesh->HasShapeToMesh();
00922   SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
00923   aCompDlg->myMemoryLackGroup->hide();
00924 
00925   if ( theMemoryLack )
00926   {
00927     aCompDlg->myMemoryLackGroup->show();
00928     aCompDlg->myFullInfo->hide();
00929     aCompDlg->myBriefInfo->hide();
00930     aCompDlg->myHypErrorGroup->hide();
00931     aCompDlg->myCompErrorGroup->hide();
00932   }
00933   else if ( theNoCompError && theNoHypoError )
00934   {
00935     SMESH::long_array_var aRes = myMesh->GetMeshInfo();
00936     aCompDlg->myFullInfo->SetMeshInfo( aRes );
00937     aCompDlg->myFullInfo->show();
00938     aCompDlg->myBriefInfo->hide();
00939     aCompDlg->myHypErrorGroup->hide();
00940     aCompDlg->myCompErrorGroup->hide();
00941   }
00942   else
00943   {
00944     QTableWidget* tbl = aCompDlg->myTable;
00945     SMESH::long_array_var aRes = myMesh->GetMeshInfo();
00946     aCompDlg->myBriefInfo->SetMeshInfo( aRes );
00947     aCompDlg->myBriefInfo->show();
00948     aCompDlg->myFullInfo->hide();
00949 
00950     if ( theNoHypoError ) {
00951       aCompDlg->myHypErrorGroup->hide();
00952     }
00953     else {
00954       aCompDlg->myHypErrorGroup->show();
00955       aCompDlg->myHypErrorLabel->setText( theHypErrors );
00956     }
00957 
00958     if ( theNoCompError ) {
00959       aCompDlg->myCompErrorGroup->hide();
00960     }
00961     else {
00962       aCompDlg->myCompErrorGroup->show();
00963 
00964       if ( !hasShape ) {
00965         aCompDlg->myPublishBtn->hide();
00966         aCompDlg->myShowBtn->hide();
00967       }
00968       else {
00969         aCompDlg->myPublishBtn->show();
00970         aCompDlg->myShowBtn->show();
00971       }
00972 
00973       // fill table of errors
00974       tbl->setRowCount( theCompErrors->length() );
00975       if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
00976       else             tbl->showColumn( COL_SHAPE );
00977       tbl->setColumnWidth( COL_ERROR, 200 );
00978 
00979       bool hasBadMesh = false;
00980       for ( int row = 0; row < theCompErrors->length(); ++row )
00981       {
00982         SMESH::ComputeError & err = theCompErrors[ row ];
00983 
00984         QString text = err.algoName.in();
00985         if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
00986         else tbl->item( row, COL_ALGO )->setText( text );
00987 
00988         text = SMESH::errorText( err.code, err.comment.in() );
00989         if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
00990         else tbl->item( row, COL_ERROR )->setText( text );
00991 
00992         text = QString("%1").arg( err.subShapeID );
00993         if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
00994         else tbl->item( row, COL_SHAPEID )->setText( text );
00995 
00996         text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
00997         if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
00998         else tbl->item( row, COL_SHAPE )->setText( text );
00999 
01000         text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
01001         if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
01002         else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
01003 
01004         text = err.hasBadMesh ? "hasBadMesh" : "";
01005         if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
01006         else tbl->item( row, COL_BAD_MESH )->setText( text );
01007         if ( err.hasBadMesh ) hasBadMesh = true;
01008 
01009         //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
01010         tbl->resizeRowToContents( row );
01011       }
01012       tbl->resizeColumnToContents( COL_ALGO );
01013       tbl->resizeColumnToContents( COL_SHAPE );
01014 
01015       if ( hasBadMesh )
01016         aCompDlg->myBadMeshBtn->show();
01017       else
01018         aCompDlg->myBadMeshBtn->hide();
01019 
01020       tbl->setCurrentCell(0,0);
01021       currentCellChanged(); // to update buttons
01022     }
01023   }
01024   // show dialog and wait, becase Compute can be invoked from Preview operation
01025   //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
01026   aCompDlg->show();
01027 }
01028 
01029 //================================================================================
01033 //================================================================================
01034 
01035 void SMESHGUI_BaseComputeOp::stopOperation()
01036 {
01037   SMESHGUI_Operation::stopOperation();
01038   if ( myTShapeDisplayer )
01039     myTShapeDisplayer->SetVisibility( false );
01040   if ( myBadMeshDisplayer ) {
01041     myBadMeshDisplayer->SetVisibility( false );
01042     // delete it in order not to have problems at its destruction when the viewer
01043     // where it worked is dead due to e.g. study closing
01044     delete myBadMeshDisplayer;
01045     myBadMeshDisplayer = 0;
01046   }
01047   myIObject.Nullify();
01048 }
01049 
01050 //================================================================================
01054 //================================================================================
01055 
01056 void SMESHGUI_BaseComputeOp::onPublishShape()
01057 {
01058   GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
01059   SALOMEDS::Study_var study = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
01060 
01061   QList<int> rows;
01062   SMESH::getSelectedRows( table(), rows );
01063   int row;
01064   foreach ( row, rows )
01065   {
01066     int curSub = table()->item(row, COL_SHAPEID)->text().toInt();
01067     GEOM::GEOM_Object_var shape = SMESH::getSubShape( curSub, myMainShape );
01068     if ( !shape->_is_nil() && ! SMESH::getSubShapeSO( curSub, myMainShape ))
01069     {
01070       if ( !SMESH::getSubShapeSO( 1, myMainShape )) // the main shape not published
01071       {
01072         QString name = GEOMBase::GetDefaultName( SMESH::shapeTypeName( myMainShape, "MAIN_SHAPE" ));
01073         SALOMEDS::SObject_var so =
01074           geomGen->AddInStudy( study, myMainShape, name.toLatin1().data(), GEOM::GEOM_Object::_nil());
01075         // look for myMainShape in the table
01076         for ( int r = 0, nr = table()->rowCount(); r < nr; ++r ) {
01077           if ( table()->item( r, COL_SHAPEID )->text() == "1" ) {
01078             if ( so->_is_nil() ) {
01079               table()->item( r, COL_SHAPE )->setText( so->GetName() );
01080               table()->item( r, COL_PUBLISHED )->setText( so->GetID() );
01081             }
01082             break;
01083           }
01084         }
01085         if ( curSub == 1 ) continue;
01086       }
01087       QString name = GEOMBase::GetDefaultName( SMESH::shapeTypeName( shape, "ERROR_SHAPE" ));
01088       SALOMEDS::SObject_var so = geomGen->AddInStudy( study, shape, name.toLatin1().data(), myMainShape);
01089       if ( !so->_is_nil() ) {
01090         table()->item( row, COL_SHAPE )->setText( so->GetName() );
01091         table()->item( row, COL_PUBLISHED )->setText( so->GetID() );
01092       }
01093     }
01094   }
01095   getSMESHGUI()->getApp()->updateObjectBrowser();
01096   currentCellChanged(); // to update buttons
01097 }
01098 
01099 //================================================================================
01103 //================================================================================
01104 
01105 void SMESHGUI_BaseComputeOp::onShowBadMesh()
01106 {
01107   myTShapeDisplayer->SetVisibility( false );
01108   QList<int> rows;
01109   if ( SMESH::getSelectedRows( table(), rows ) == 1 ) {
01110     bool hasBadMesh = ( !table()->item(rows.front(), COL_BAD_MESH)->text().isEmpty() );
01111     if ( hasBadMesh ) {
01112       int curSub = table()->item(rows.front(), COL_SHAPEID)->text().toInt();
01113       SMESHGUI* gui = getSMESHGUI();
01114       SMESH::SMESH_Gen_var gen = gui->GetSMESHGen();
01115       SVTK_ViewWindow*    view = SMESH::GetViewWindow( gui );
01116       if ( myBadMeshDisplayer ) delete myBadMeshDisplayer;
01117       myBadMeshDisplayer = new SMESHGUI_MeshEditPreview( view );
01118       SMESH::MeshPreviewStruct_var aMeshData = gen->GetBadInputElements(myMesh,curSub);
01119       vtkFloatingPointType aPointSize = SMESH::GetFloat("SMESH:node_size",3);
01120       vtkFloatingPointType aLineWidth = SMESH::GetFloat("SMESH:element_width",1);
01121       // delete property !!!!!!!!!!
01122       vtkProperty* prop = vtkProperty::New();
01123       prop->SetLineWidth( aLineWidth * 3 );
01124       prop->SetPointSize( aPointSize * 3 );
01125       prop->SetColor( 250, 0, 250 );
01126       myBadMeshDisplayer->GetActor()->SetProperty( prop );
01127       myBadMeshDisplayer->SetData( aMeshData._retn() );
01128     }
01129   }
01130 }
01131 
01132 //================================================================================
01136 //================================================================================
01137 
01138 void SMESHGUI_BaseComputeOp::currentCellChanged()
01139 {
01140   myTShapeDisplayer->SetVisibility( false );
01141   if ( myBadMeshDisplayer )
01142     myBadMeshDisplayer->SetVisibility( false );
01143 
01144   bool publishEnable = 0, showEnable = 0, showOnly = 1, hasBadMesh = 0;
01145   QList<int> rows;
01146   int nbSelected = SMESH::getSelectedRows( table(), rows );
01147   int row;
01148   foreach ( row, rows )
01149   {
01150     bool hasData     = ( !table()->item( row, COL_SHAPE )->text().isEmpty() );
01151     bool isPublished = ( !table()->item( row, COL_PUBLISHED )->text().isEmpty() );
01152     if ( hasData && !isPublished )
01153       publishEnable = true;
01154 
01155     int curSub = table()->item( row, COL_SHAPEID )->text().toInt();
01156     bool prsReady = myTShapeDisplayer->HasReadyActorsFor( curSub, myMainShape );
01157     if ( prsReady ) {
01158       myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
01159       showOnly = false;
01160     }
01161     else {
01162       showEnable = true;
01163     }
01164 
01165     if ( !table()->item(row, COL_BAD_MESH)->text().isEmpty() )
01166       hasBadMesh = true;
01167   }
01168   myCompDlg->myPublishBtn->setEnabled( publishEnable );
01169   myCompDlg->myShowBtn   ->setEnabled( showEnable );
01170   myCompDlg->myBadMeshBtn->setEnabled( hasBadMesh && ( nbSelected == 1 ));
01171 }
01172 
01173 //================================================================================
01177 //================================================================================
01178 
01179 void SMESHGUI_BaseComputeOp::onPreviewShape()
01180 {
01181   if ( myTShapeDisplayer )
01182   {
01183     SUIT_OverrideCursor aWaitCursor;
01184     QList<int> rows;
01185     SMESH::getSelectedRows( table(), rows );
01186 
01187     bool showOnly = true;
01188     int row;
01189     foreach ( row, rows )
01190     {
01191       int curSub = table()->item( row, COL_SHAPEID )->text().toInt();
01192       if ( curSub > 0 ) {
01193         myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
01194         showOnly = false;
01195       }
01196     }
01197     currentCellChanged(); // to update buttons
01198   }
01199 }
01200 
01201 //================================================================================
01205 //================================================================================
01206 
01207 SMESHGUI_BaseComputeOp::~SMESHGUI_BaseComputeOp()
01208 {
01209   delete myCompDlg;
01210   myCompDlg = 0;
01211   delete myTShapeDisplayer;
01212   if ( myBadMeshDisplayer )
01213     delete myBadMeshDisplayer;
01214 }
01215 
01216 //================================================================================
01221 //================================================================================
01222 
01223 SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::computeDlg() const
01224 {
01225   if ( !myCompDlg )
01226   {
01227     SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
01228     me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), false );
01229     // connect signals and slots
01230     connect(myCompDlg->myShowBtn,    SIGNAL (clicked()), SLOT(onPreviewShape()));
01231     connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
01232     connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh()));
01233 
01234     QTableWidget* aTable = me->table();
01235     connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged()));
01236     connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged()));
01237   }
01238   return myCompDlg;
01239 }
01240 
01241 //================================================================================
01245 //================================================================================
01246 
01247 bool SMESHGUI_BaseComputeOp::onApply()
01248 {
01249   return true;
01250 }
01251 
01252 //================================================================================
01256 //================================================================================
01257 
01258 QTableWidget* SMESHGUI_BaseComputeOp::table()
01259 {
01260   return myCompDlg->myTable;
01261 }
01262 
01263 
01264 //================================================================================
01268 //================================================================================
01269 
01270 SMESHGUI_ComputeOp::SMESHGUI_ComputeOp()
01271  : SMESHGUI_BaseComputeOp()
01272 {
01273 }
01274 
01275 
01276 //================================================================================
01280 //================================================================================
01281 
01282 SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp()
01283 {
01284 }
01285 
01286 //================================================================================
01290 //================================================================================
01291 
01292 void SMESHGUI_ComputeOp::startOperation()
01293 {
01294   SMESHGUI_BaseComputeOp::startOperation();
01295   if (myMesh->_is_nil())
01296     return;
01297   computeMesh();
01298 }
01299 
01300 //================================================================================
01304 //================================================================================
01305 
01306 bool SMESHGUI_BaseComputeOp::isValid(  SUIT_Operation* theOp  ) const
01307 {
01308   SMESHGUI_BaseComputeOp* baseOp = dynamic_cast<SMESHGUI_BaseComputeOp*>( theOp );
01309   bool ret = true;
01310   if ( !myMesh->_is_nil() && baseOp ) {
01311     SMESH::SMESH_Mesh_var aMesh = baseOp->getMesh();
01312     if ( !aMesh->_is_nil() && aMesh->GetId() == myMesh->GetId() ) ret = false;
01313   }
01314   return ret;
01315 }
01316 
01317 //================================================================================
01322 //================================================================================
01323 
01324 LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
01325 {
01326   return computeDlg();
01327 }
01328 
01329 //================================================================================
01333 //================================================================================
01334 
01335 SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp()
01336  : SMESHGUI_BaseComputeOp(),
01337  myDlg( 0 ),
01338  myOrderMgr( 0 ),
01339  myActiveDlg( 0 ),
01340  myPreviewDisplayer( 0 )
01341 {
01342   myHelpFileName = "constructing_meshes_page.html#preview_mesh_anchor";
01343 }
01344 
01345 //================================================================================
01349 //================================================================================
01350 
01351 SMESHGUI_PrecomputeOp::~SMESHGUI_PrecomputeOp()
01352 {
01353   delete myDlg;
01354   myDlg = 0;
01355   delete myOrderMgr;
01356   myOrderMgr = 0;
01357   myActiveDlg = 0;
01358   if ( myPreviewDisplayer )
01359     delete myPreviewDisplayer;
01360   myPreviewDisplayer = 0;
01361 }
01362 
01363 //================================================================================
01368 //================================================================================
01369 
01370 LightApp_Dialog* SMESHGUI_PrecomputeOp::dlg() const
01371 {
01372   return myActiveDlg;
01373 }
01374 
01375 //================================================================================
01379 //================================================================================
01380 
01381 void SMESHGUI_PrecomputeOp::startOperation()
01382 {
01383   if ( !myDlg )
01384   {
01385     myDlg = new SMESHGUI_PrecomputeDlg( desktop() );
01386     
01387     // connect signals
01388     connect( myDlg, SIGNAL( preview() ), this, SLOT( onPreview() ) );
01389     connect( myDlg, SIGNAL( dlgOk() ), this, SLOT( onCompute() ) );
01390     connect( myDlg, SIGNAL( dlgApply() ), this, SLOT( onCompute() ) );
01391   }
01392   myActiveDlg = myDlg;
01393 
01394   // connect signal to compute dialog. which will be shown after Compute mesh operation
01395   SMESHGUI_ComputeDlg* cmpDlg = computeDlg();
01396   if ( cmpDlg )
01397   {
01398     // disconnect signals
01399     disconnect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
01400     disconnect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
01401     disconnect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
01402     disconnect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
01403     disconnect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
01404 
01405     // connect signals
01406     if( cmpDlg->testButtonFlags( QtxDialog::OK ) )
01407       connect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
01408     if( cmpDlg->testButtonFlags( QtxDialog::Apply ) )
01409       connect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
01410     if( cmpDlg->testButtonFlags( QtxDialog::Help ) )
01411       connect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
01412     if( cmpDlg->testButtonFlags( QtxDialog::Cancel ) )
01413       connect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
01414     if( cmpDlg->testButtonFlags( QtxDialog::Close ) )
01415       connect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
01416   }
01417 
01418   SMESHGUI_BaseComputeOp::startOperation();
01419   if (myMesh->_is_nil())
01420     return;
01421 
01422   if (myDlg->getPreviewMode() == -1)
01423   {
01424     // nothing to preview
01425     SUIT_MessageBox::warning(desktop(),
01426                              tr("SMESH_WRN_WARNING"),
01427                              tr("SMESH_WRN_NOTHING_PREVIEW"));
01428     onCancel();
01429     return;
01430   }
01431 
01432   // disconnect slot from preview dialog to have Apply from results of compute operation only 
01433   disconnect( myDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
01434   disconnect( myDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
01435 
01436   myDlg->show();
01437 }
01438 
01439 //================================================================================
01443 //================================================================================
01444 
01445 void SMESHGUI_PrecomputeOp::stopOperation()
01446 {
01447   if ( myPreviewDisplayer )
01448   {
01449     myPreviewDisplayer->SetVisibility( false );
01450     delete myPreviewDisplayer;
01451     myPreviewDisplayer = 0;
01452   }
01453   myMapShapeId.clear();
01454   SMESHGUI_BaseComputeOp::stopOperation();
01455 }
01456 
01457 //================================================================================
01461 //================================================================================
01462 
01463 void SMESHGUI_PrecomputeOp::resumeOperation()
01464 {
01465   if ( myActiveDlg == myDlg )
01466     initDialog();
01467   SMESHGUI_BaseComputeOp::resumeOperation();
01468 }
01469 
01470 //================================================================================
01474 //================================================================================
01475 
01476 void SMESHGUI_PrecomputeOp::initDialog()
01477 {
01478   QList<int> modes;
01479 
01480   QMap<int, int> modeMap;
01481   _PTR(SObject)  pMesh = studyDS()->FindObjectID( myIObject->getEntry() );
01482   getAssignedAlgos( pMesh, modeMap );
01483   if ( modeMap.contains( SMESH::DIM_3D ) )
01484   {
01485     if ( modeMap.contains( SMESH::DIM_2D ) )
01486       modes.append( SMESH::DIM_2D );
01487     if ( modeMap.contains( SMESH::DIM_1D ) )
01488       modes.append( SMESH::DIM_1D );
01489   }
01490   else if ( modeMap.contains( SMESH::DIM_2D ) )
01491   {
01492     if ( modeMap.contains( SMESH::DIM_1D ) )
01493       modes.append( SMESH::DIM_1D );
01494   }
01495 
01496   myOrderMgr = new SMESHGUI_MeshOrderMgr( myDlg->getMeshOrderBox() );
01497   myOrderMgr->SetMesh( myMesh );
01498   bool isOrder = myOrderMgr->GetMeshOrder(myPrevOrder);
01499   myDlg->getMeshOrderBox()->setShown(isOrder);
01500   if ( !isOrder ) {
01501     delete myOrderMgr;
01502     myOrderMgr = 0;
01503   }
01504 
01505   myDlg->setPreviewModes( modes );
01506 }
01507 
01508 //================================================================================
01512 //================================================================================
01513 
01514 void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
01515                                              QMap<int,int>& theModeMap)
01516 {
01517   _PTR(SObject)          aHypRoot;
01518   _PTR(GenericAttribute) anAttr;
01519   int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
01520   if ( theMesh && theMesh->FindSubObject( aPart, aHypRoot ) )
01521   {
01522     _PTR(ChildIterator) anIter =
01523       SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
01524     for ( ; anIter->More(); anIter->Next() )
01525     {
01526       _PTR(SObject) anObj = anIter->Value();
01527       _PTR(SObject) aRefObj;
01528       if ( anObj->ReferencedObject( aRefObj ) )
01529         anObj = aRefObj;
01530       else
01531         continue;
01532       
01533       if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
01534       {
01535         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
01536         if ( CORBA::is_nil( aVar ) )
01537           continue;
01538         
01539         for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
01540         {
01541           SMESH::SMESH_Algo_var algo;
01542           switch(dim) {
01543           case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break;
01544           case SMESH::DIM_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break;
01545           case SMESH::DIM_3D: algo = SMESH::SMESH_3D_Algo::_narrow( aVar ); break;
01546           default: break;
01547           }
01548           if ( !algo->_is_nil() )
01549             theModeMap[ dim ] = 0;
01550         }
01551       }
01552     }
01553   }
01554 }
01555 
01556 //================================================================================
01560 //================================================================================
01561 
01562 void SMESHGUI_PrecomputeOp::onCompute()
01563 {
01564   myDlg->hide();
01565   if (myOrderMgr && myOrderMgr->IsOrderChanged())
01566     myOrderMgr->SetMeshOrder();
01567   myMapShapeId.clear();
01568   myActiveDlg = computeDlg();
01569   computeMesh();
01570 }
01571 
01572 //================================================================================
01576 //================================================================================
01577 
01578 void SMESHGUI_PrecomputeOp::onCancel()
01579 {
01580   QObject* curDlg = sender();
01581   if ( curDlg == computeDlg() && myActiveDlg == myDlg )
01582   {
01583     // return from error messages
01584     myDlg->show();
01585     return;
01586   }
01587 
01588   bool isRestoreOrder = false;
01589   if ( myActiveDlg == myDlg  && !myMesh->_is_nil() && myMapShapeId.count() )
01590   {
01591     // ask to remove already computed mesh elements
01592     if ( SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
01593                                     tr( "CLEAR_SUBMESH_QUESTION" ),
01594                                     tr( "SMESH_BUT_DELETE" ), tr( "SMESH_BUT_NO" ), 0, 1 ) == 0 )
01595     {
01596       // remove all submeshes for collected shapes
01597       QMap<int,int>::const_iterator it = myMapShapeId.constBegin();
01598       for ( ; it != myMapShapeId.constEnd(); ++it )
01599         myMesh->ClearSubMesh( *it );
01600       isRestoreOrder = true;
01601     }
01602   }
01603 
01604   // return previous mesh order
01605   if (myOrderMgr && myOrderMgr->IsOrderChanged()) {
01606     if (!isRestoreOrder)
01607       isRestoreOrder = 
01608         (SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
01609                                     tr( "SMESH_REJECT_MESH_ORDER" ),
01610                                     tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ) == 0);
01611     if (isRestoreOrder)
01612       myOrderMgr->SetMeshOrder(myPrevOrder);
01613   }
01614 
01615   delete myOrderMgr;
01616   myOrderMgr = 0;
01617 
01618   myMapShapeId.clear();
01619   SMESHGUI_BaseComputeOp::onCancel();
01620 }
01621 
01622 //================================================================================
01626 //================================================================================
01627 
01628 void SMESHGUI_PrecomputeOp::onPreview()
01629 {
01630   if ( !myDlg || myMesh->_is_nil() || myMainShape->_is_nil() )
01631     return;
01632 
01633   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
01634   if ( !aMeshSObj )
01635     return;
01636 
01637   // set modified submesh priority if any
01638   if (myOrderMgr && myOrderMgr->IsOrderChanged())
01639     myOrderMgr->SetMeshOrder();
01640 
01641   // Compute preview of mesh, 
01642   // i.e. compute mesh till indicated dimension
01643   int dim = myDlg->getPreviewMode();
01644   
01645   SMESH::MemoryReserve aMemoryReserve;
01646   
01647   SMESH::compute_error_array_var aCompErrors;
01648   QString                        aHypErrors;
01649 
01650   bool computeFailed = true, memoryLack = false;
01651 
01652   SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
01653     aCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
01654 
01655   SMESHGUI* gui = getSMESHGUI();
01656   SMESH::SMESH_Gen_var gen = gui->GetSMESHGen();
01657   SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
01658   if ( errors->length() > 0 ) {
01659     aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
01660   }
01661 
01662   SUIT_OverrideCursor aWaitCursor;
01663 
01664   SVTK_ViewWindow*    view = SMESH::GetViewWindow( gui );
01665   if ( myPreviewDisplayer ) delete myPreviewDisplayer;
01666   myPreviewDisplayer = new SMESHGUI_MeshEditPreview( view );
01667   
01668   SMESH::long_array_var aShapesId = new SMESH::long_array();
01669   try {
01670 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
01671     OCC_CATCH_SIGNALS;
01672 #endif
01673       
01674     SMESH::MeshPreviewStruct_var previewData =
01675       gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId);
01676 
01677     SMESH::MeshPreviewStruct* previewRes = previewData._retn();
01678     if ( previewRes && previewRes->nodesXYZ.length() > 0 )
01679     {
01680       computeFailed = false;
01681       myPreviewDisplayer->SetData( previewRes );
01682       // append shape indeces with computed mesh entities
01683       for ( int i = 0, n = aShapesId->length(); i < n; i++ )
01684         myMapShapeId[ aShapesId[ i ] ] = 0;
01685     }
01686     else
01687       myPreviewDisplayer->SetVisibility(false);
01688   }
01689   catch(const SALOME::SALOME_Exception & S_ex){
01690     memoryLack = true;
01691     myPreviewDisplayer->SetVisibility(false);
01692   }
01693 
01694   try {
01695 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
01696     OCC_CATCH_SIGNALS;
01697 #endif
01698     aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
01699     // check if there are memory problems
01700     for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
01701       memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB );
01702   }
01703   catch(const SALOME::SALOME_Exception & S_ex){
01704     memoryLack = true;
01705   }
01706 
01707   if ( memoryLack )
01708     aMemoryReserve.release();
01709 
01710   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
01711   bool noHypoError = ( aHypErrors.isEmpty() );
01712 
01713   SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( gui );
01714   int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
01715 
01716   bool isShowError = true;
01717   switch( aNotifyMode ) {
01718   case 0: // show the mesh computation result dialog NEVER
01719     isShowError = false;
01720     break;
01721   case 1: // show the mesh computation result dialog if there are some errors
01722   default: // show the result dialog after each mesh computation
01723     if ( !computeFailed && !memoryLack && noCompError && noHypoError )
01724       isShowError = false;
01725     break;
01726   }
01727 
01728   aWaitCursor.suspend();
01729   // SHOW ERRORS
01730   if ( isShowError )
01731   {
01732     myDlg->hide();
01733     aCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
01734     showComputeResult( memoryLack, noCompError, aCompErrors, noHypoError, aHypErrors );
01735   }
01736 }
01737 
01738 
01739 //================================================================================
01743 //================================================================================
01744 
01745 SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent )
01746  : SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help ),
01747    myOrderBox(0)
01748 {
01749   setWindowTitle( tr( "CAPTION" ) );
01750 
01751   setButtonText( OK, tr( "COMPUTE" ) );
01752   QFrame* main = mainFrame();
01753 
01754   QVBoxLayout* layout = new QVBoxLayout( main );
01755 
01756   myOrderBox = new SMESHGUI_MeshOrderBox( main );
01757   layout->addWidget(myOrderBox);
01758 
01759   QFrame* frame = new QFrame( main );
01760   layout->setMargin(0); layout->setSpacing(0);
01761   layout->addWidget( frame );
01762 
01763   QHBoxLayout* frameLay = new QHBoxLayout( frame );
01764   frameLay->setMargin(0); frameLay->setSpacing(SPACING);
01765   
01766   myPreviewMode = new QtxComboBox( frame );
01767   frameLay->addWidget( myPreviewMode );
01768 
01769   myPreviewBtn = new QPushButton( tr( "PREVIEW" ), frame );
01770   frameLay->addWidget( myPreviewBtn );
01771 
01772   connect( myPreviewBtn, SIGNAL( clicked( bool ) ), this, SIGNAL( preview() ) );
01773 }
01774 
01775 //================================================================================
01779 //================================================================================
01780 
01781 SMESHGUI_PrecomputeDlg::~SMESHGUI_PrecomputeDlg()
01782 {
01783 }
01784 
01785 //================================================================================
01789 //================================================================================
01790 
01791 void SMESHGUI_PrecomputeDlg::setPreviewModes( const QList<int>& theModes )
01792 {
01793   myPreviewMode->clear();
01794   QList<int>::const_iterator it = theModes.constBegin();
01795   for ( int i = 0; it != theModes.constEnd(); ++it, i++ )
01796   {
01797     QString mode = QString( "PREVIEW_%1" ).arg( *it );
01798     myPreviewMode->addItem( tr( mode.toLatin1().data() ) );
01799     myPreviewMode->setId( i, *it );
01800   }
01801   myPreviewBtn->setEnabled( !theModes.isEmpty() );
01802 }
01803 
01804 //================================================================================
01808 //================================================================================
01809 
01810 int SMESHGUI_PrecomputeDlg::getPreviewMode() const
01811 {
01812   return myPreviewMode->currentId();
01813 }
01814 
01815 //================================================================================
01819 //================================================================================
01820 
01821 SMESHGUI_MeshOrderBox* SMESHGUI_PrecomputeDlg::getMeshOrderBox() const
01822 {
01823   return myOrderBox;
01824 }
01825 
01826 
01827 //================================================================================
01831 //================================================================================
01832 
01833 SMESHGUI_EvaluateOp::SMESHGUI_EvaluateOp()
01834  : SMESHGUI_BaseComputeOp()
01835 {
01836 }
01837 
01838 
01839 //================================================================================
01843 //================================================================================
01844 
01845 SMESHGUI_EvaluateOp::~SMESHGUI_EvaluateOp()
01846 {
01847 }
01848 
01849 //================================================================================
01853 //================================================================================
01854 
01855 void SMESHGUI_EvaluateOp::startOperation()
01856 {
01857   SMESHGUI_BaseComputeOp::evaluateDlg();
01858   SMESHGUI_BaseComputeOp::startOperation();
01859   if (myMesh->_is_nil())
01860     return;
01861   evaluateMesh();
01862 }
01863 
01864 //================================================================================
01869 //================================================================================
01870 
01871 LightApp_Dialog* SMESHGUI_EvaluateOp::dlg() const
01872 {
01873   return evaluateDlg();
01874 }
01875 
01876 //================================================================================
01880 //================================================================================
01881 
01882 void SMESHGUI_BaseComputeOp::evaluateMesh()
01883 {
01884   // EVALUATE MESH
01885 
01886   SMESH::MemoryReserve aMemoryReserve;
01887 
01888   SMESH::compute_error_array_var aCompErrors;
01889   QString                        aHypErrors;
01890 
01891   bool evaluateFailed = true, memoryLack = false;
01892   SMESH::long_array_var aRes;
01893 
01894   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
01895   if ( !aMeshSObj ) //  IPAL21340
01896     return;
01897 
01898   bool hasShape = myMesh->HasShapeToMesh();
01899   bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
01900   if ( shapeOK )
01901   {
01902     myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
01903     SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
01904     SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
01905     if ( errors->length() > 0 ) {
01906       aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
01907     }
01908     SUIT_OverrideCursor aWaitCursor;
01909     try {
01910 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
01911       OCC_CATCH_SIGNALS;
01912 #endif
01913       aRes = gen->Evaluate(myMesh, myMainShape);
01914     }
01915     catch(const SALOME::SALOME_Exception & S_ex){
01916       memoryLack = true;
01917     }
01918 
01919     try {
01920 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
01921       OCC_CATCH_SIGNALS;
01922 #endif
01923       aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
01924     }
01925     catch(const SALOME::SALOME_Exception & S_ex){
01926       memoryLack = true;
01927     }
01928   }
01929 
01930   if ( memoryLack )
01931     aMemoryReserve.release();
01932 
01933   evaluateFailed =  ( aCompErrors->length() > 0 );
01934   myCompDlg->setWindowTitle(tr( evaluateFailed ? "SMESH_WRN_EVALUATE_FAILED" : "SMESH_EVALUATE_SUCCEED"));
01935 
01936   // SHOW ERRORS
01937   
01938   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
01939   bool noHypoError = ( aHypErrors.isEmpty() );
01940 
01941   //SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
01942   //int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
01943 
01944   bool isShowResultDlg = true;
01945   //if( noHypoError )
01946   //switch( aNotifyMode ) {
01947   //case 0: // show the mesh computation result dialog NEVER
01948   //isShowResultDlg = false;
01949   //commit();
01950   //break;
01951   //case 1: // show the mesh computation result dialog if there are some errors
01952   //if ( memoryLack || !noHypoError )
01953   //  isShowResultDlg = true;
01954   //else
01955   //{
01956   //  isShowResultDlg = false;
01957   //  commit();
01958   //}
01959   //break;
01960   //default: // show the result dialog after each mesh computation
01961   //isShowResultDlg = true;
01962   //}
01963 
01964   // SHOW RESULTS
01965   if ( isShowResultDlg )
01966     showEvaluateResult( aRes, memoryLack, noCompError, aCompErrors,
01967                         noHypoError, aHypErrors);
01968 }
01969 
01970 
01971 void SMESHGUI_BaseComputeOp::showEvaluateResult(const SMESH::long_array& theRes,
01972                                                 const bool theMemoryLack,
01973                                                 const bool theNoCompError,
01974                                                 SMESH::compute_error_array_var& theCompErrors,
01975                                                 const bool theNoHypoError,
01976                                                 const QString& theHypErrors)
01977 {
01978   bool hasShape = myMesh->HasShapeToMesh();
01979   SMESHGUI_ComputeDlg* aCompDlg = evaluateDlg();
01980   aCompDlg->myMemoryLackGroup->hide();
01981 
01982   if ( theMemoryLack )
01983   {
01984     aCompDlg->myMemoryLackGroup->show();
01985     aCompDlg->myFullInfo->hide();
01986     aCompDlg->myBriefInfo->hide();
01987     aCompDlg->myHypErrorGroup->hide();
01988     aCompDlg->myCompErrorGroup->hide();
01989   }
01990   else if ( theNoCompError && theNoHypoError )
01991   {
01992     aCompDlg->myFullInfo->SetMeshInfo( theRes );
01993     aCompDlg->myFullInfo->show();
01994     aCompDlg->myBriefInfo->hide();
01995     aCompDlg->myHypErrorGroup->hide();
01996     aCompDlg->myCompErrorGroup->hide();
01997   }
01998   else
01999   {
02000     QTableWidget* tbl = aCompDlg->myTable;
02001     aCompDlg->myBriefInfo->SetMeshInfo( theRes );
02002     aCompDlg->myBriefInfo->show();
02003     aCompDlg->myFullInfo->hide();
02004 
02005     if ( theNoHypoError ) {
02006       aCompDlg->myHypErrorGroup->hide();
02007     }
02008     else {
02009       aCompDlg->myHypErrorGroup->show();
02010       aCompDlg->myHypErrorLabel->setText( theHypErrors );
02011     }
02012 
02013     if ( theNoCompError ) {
02014       aCompDlg->myCompErrorGroup->hide();
02015     }
02016     else {
02017       aCompDlg->myCompErrorGroup->show();
02018 
02019       aCompDlg->myPublishBtn->hide();
02020       aCompDlg->myShowBtn->hide();
02021 
02022       // fill table of errors
02023       tbl->setRowCount( theCompErrors->length() );
02024       if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
02025       else             tbl->showColumn( COL_SHAPE );
02026       tbl->setColumnWidth( COL_ERROR, 200 );
02027 
02028       bool hasBadMesh = false;
02029       for ( int row = 0; row < theCompErrors->length(); ++row )
02030       {
02031         SMESH::ComputeError & err = theCompErrors[ row ];
02032 
02033         QString text = err.algoName.in();
02034         if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
02035         else tbl->item( row, COL_ALGO )->setText( text );
02036 
02037         text = SMESH::errorText( err.code, err.comment.in() );
02038         if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
02039         else tbl->item( row, COL_ERROR )->setText( text );
02040 
02041         text = QString("%1").arg( err.subShapeID );
02042         if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
02043         else tbl->item( row, COL_SHAPEID )->setText( text );
02044 
02045         text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
02046         if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
02047         else tbl->item( row, COL_SHAPE )->setText( text );
02048 
02049         text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
02050         if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
02051         else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
02052 
02053         text = err.hasBadMesh ? "hasBadMesh" : "";
02054         if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
02055         else tbl->item( row, COL_BAD_MESH )->setText( text );
02056         if ( err.hasBadMesh ) hasBadMesh = true;
02057 
02058         //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
02059         tbl->resizeRowToContents( row );
02060       }
02061       tbl->resizeColumnToContents( COL_ALGO );
02062       tbl->resizeColumnToContents( COL_SHAPE );
02063 
02064       if ( hasBadMesh )
02065         aCompDlg->myBadMeshBtn->show();
02066       else
02067         aCompDlg->myBadMeshBtn->hide();
02068 
02069       tbl->setCurrentCell(0,0);
02070       currentCellChanged(); // to update buttons
02071     }
02072   }
02073   // show dialog and wait, becase Compute can be invoked from Preview operation
02074   //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
02075   aCompDlg->show();
02076 }
02077 
02078 
02079 //================================================================================
02084 //================================================================================
02085 
02086 SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::evaluateDlg() const
02087 {
02088   if ( !myCompDlg )
02089   {
02090     SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
02091     me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), true );
02092     // connect signals and slots
02093     connect(myCompDlg->myShowBtn,    SIGNAL (clicked()), SLOT(onPreviewShape()));
02094     connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
02095     connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh()));
02096     QTableWidget* aTable = me->table();
02097     connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged()));
02098     connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged()));
02099   }
02100   return myCompDlg;
02101 }
02102 
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS