Back to index

salome-smesh  6.5.0
SMESHGUI_ComputeDlg.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  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     case SMESH::COMPERR_WARNING:
00353       return comment ? QString(comment) : QObject::tr("COMPERR_UNKNOWN");
00354     default:
00355       text = QString("#%1").arg( -errCode );
00356     }
00357     if ( text.length() > 0 ) text += ". ";
00358     return text + comment;
00359   }
00360   // -----------------------------------------------------------------------
00364   _PTR(SObject) getSubShapeSO( int subShapeID, GEOM::GEOM_Object_var aMainShape)
00365   {
00366     _PTR(SObject) so = SMESH::FindSObject(aMainShape);
00367     if ( subShapeID == 1 || !so )
00368       return so;
00369     _PTR(ChildIterator) it;
00370     if (_PTR(Study) study = SMESH::GetActiveStudyDocument())
00371       it =  study->NewChildIterator(so);
00372     _PTR(SObject) subSO;
00373     if ( it ) {
00374       for ( it->InitEx(true); !subSO && it->More(); it->Next() ) {
00375         GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>( it->Value() );
00376         if ( !geom->_is_nil() ) {
00377           GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
00378           if ( list->length() == 1 && list[0] == subShapeID )
00379             subSO = it->Value();
00380         }
00381       }
00382     }
00383     return subSO;
00384   }
00385   // -----------------------------------------------------------------------
00389   GEOM::GEOM_Object_ptr getSubShape( int subShapeID, GEOM::GEOM_Object_var aMainShape)
00390   {
00391     GEOM::GEOM_Object_var aSubShape;
00392     if ( subShapeID == 1 )
00393       aSubShape = aMainShape;
00394     else if ( _PTR(SObject) so = getSubShapeSO( subShapeID, aMainShape ))
00395       aSubShape = SMESH::SObjectToInterface<GEOM::GEOM_Object>( so );
00396     else
00397       aSubShape = SMESH::GetSubShape( aMainShape, subShapeID );
00398     return aSubShape._retn();
00399   }
00400   // -----------------------------------------------------------------------
00404 #define CASE2NAME(enum) case GEOM::enum: name = QObject::tr( "GEOM_" #enum ); break;
00405   QString shapeTypeName(GEOM::GEOM_Object_var aShape, const char* dflt = "" )
00406   {
00407     QString name = dflt;
00408     if ( !aShape->_is_nil() ) {
00409       switch ( aShape->GetShapeType() ) {
00410       CASE2NAME( VERTEX    );
00411       CASE2NAME( EDGE      );
00412       CASE2NAME( WIRE      );
00413       CASE2NAME( FACE      );
00414       CASE2NAME( SHELL     );
00415       CASE2NAME( SOLID     );
00416       CASE2NAME( COMPSOLID );
00417       CASE2NAME( COMPOUND  );
00418       default:;
00419       }
00420     }
00421     return name;
00422   }
00423   // -----------------------------------------------------------------------
00427   QString shapeText(int subShapeID, GEOM::GEOM_Object_var aMainShape )
00428   {
00429     QString text;
00430     if ( _PTR(SObject) aSO = getSubShapeSO( subShapeID, aMainShape ))
00431       text = aSO->GetName().c_str();
00432     else {
00433       text = QString("#%1").arg( subShapeID );
00434       QString typeName = shapeTypeName( getSubShape( subShapeID, aMainShape ));
00435       if ( typeName.length() )
00436         text += QString(" (%1)").arg(typeName);
00437     }
00438     return text;
00439   }
00440   // -----------------------------------------------------------------------
00444   int getSelectedRows(QTableWidget* table, QList<int>& rows)
00445   {
00446     rows.clear();
00447     QList<QTableWidgetSelectionRange> selRanges = table->selectedRanges();
00448     QTableWidgetSelectionRange range;
00449     foreach( range, selRanges )
00450     {
00451       for ( int row = range.topRow(); row <= range.bottomRow(); ++row )
00452         rows.append( row );
00453     }
00454     if ( rows.isEmpty() && table->currentRow() > -1 )
00455       rows.append( table->currentRow() );
00456 
00457     return rows.count();
00458   }
00459 
00460 } // namespace SMESH
00461 
00462 
00463 // =========================================================================================
00467 //=======================================================================
00468 
00469 SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent, bool ForEval )
00470  : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ )
00471 {
00472   QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
00473   aDlgLay->setMargin( 0 );
00474   aDlgLay->setSpacing( SPACING );
00475 
00476   QFrame* aMainFrame = createMainFrame(mainFrame(),ForEval);
00477 
00478   aDlgLay->addWidget(aMainFrame);
00479 
00480   aDlgLay->setStretchFactor(aMainFrame, 1);
00481 }
00482 
00483 // =========================================================================================
00487 //=======================================================================
00488 
00489 SMESHGUI_ComputeDlg::~SMESHGUI_ComputeDlg()
00490 {
00491 }
00492 
00493 //=======================================================================
00494 // function : createMainFrame()
00495 // purpose  : Create frame containing dialog's fields
00496 //=======================================================================
00497 
00498 QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent, bool ForEval)
00499 {
00500   QFrame* aFrame = new QFrame(theParent);
00501 
00502   SUIT_ResourceMgr* rm = resourceMgr();
00503   QPixmap iconCompute (rm->loadPixmap("SMESH", tr("ICON_COMPUTE")));
00504 
00505   // constructor
00506 
00507   QGroupBox* aPixGrp;
00508   if(ForEval) {
00509     aPixGrp = new QGroupBox(tr("EVAL_DLG"), aFrame);
00510   }
00511   else {
00512     aPixGrp = new QGroupBox(tr("CONSTRUCTOR"), aFrame);
00513   }
00514   QButtonGroup* aBtnGrp = new QButtonGroup(this);
00515   QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp);
00516   aPixGrpLayout->setMargin(MARGIN); aPixGrpLayout->setSpacing(SPACING);
00517 
00518   QRadioButton* aRBut = new QRadioButton(aPixGrp);
00519   aRBut->setIcon(iconCompute);
00520   aRBut->setChecked(true);
00521   aPixGrpLayout->addWidget(aRBut);
00522   aBtnGrp->addButton(aRBut, 0);
00523 
00524   // Mesh name
00525 
00526   QGroupBox* nameBox = new QGroupBox(tr("SMESH_MESHINFO_NAME"), aFrame );
00527   QHBoxLayout* nameBoxLayout = new QHBoxLayout(nameBox);
00528   nameBoxLayout->setMargin(MARGIN); nameBoxLayout->setSpacing(SPACING);
00529   myMeshName = new QLabel(nameBox);
00530   nameBoxLayout->addWidget(myMeshName);
00531 
00532   // Mesh Info
00533 
00534   myBriefInfo = new SMESHGUI_MeshInfosBox(false, aFrame);
00535   myFullInfo  = new SMESHGUI_MeshInfosBox(true,  aFrame);
00536 
00537   // Computation errors
00538 
00539   myCompErrorGroup = new QGroupBox(tr("ERRORS"), aFrame);
00540   myWarningLabel = new QLabel(QString("<b>%1</b>").arg(tr("COMPUTE_WARNING")), myCompErrorGroup);
00541   myTable        = new QTableWidget( 1, NB_COLUMNS, myCompErrorGroup);
00542   myShowBtn      = new QPushButton(tr("SHOW_SHAPE"), myCompErrorGroup);
00543   myPublishBtn   = new QPushButton(tr("PUBLISH_SHAPE"), myCompErrorGroup);
00544   myBadMeshBtn   = new QPushButton(tr("SHOW_BAD_MESH"), myCompErrorGroup);
00545 
00546   //myTable->setReadOnly( true ); // VSR: check
00547   myTable->setEditTriggers( QAbstractItemView::NoEditTriggers );
00548   myTable->hideColumn( COL_PUBLISHED );
00549   myTable->hideColumn( COL_SHAPEID );
00550   myTable->hideColumn( COL_BAD_MESH );
00551   myTable->horizontalHeader()->setResizeMode( COL_ERROR, QHeaderView::Interactive );
00552 
00553   QStringList headers;
00554   headers << tr( "COL_ALGO_HEADER" );
00555   headers << tr( "COL_SHAPE_HEADER" );
00556   headers << tr( "COL_ERROR_HEADER" );
00557   headers << tr( "COL_SHAPEID_HEADER" );
00558   headers << tr( "COL_PUBLISHED_HEADER" );
00559 
00560   myTable->setHorizontalHeaderLabels( headers );
00561 
00562   // layouting
00563   QGridLayout* grpLayout = new QGridLayout(myCompErrorGroup);
00564   grpLayout->setSpacing(SPACING);
00565   grpLayout->setMargin(MARGIN);
00566   grpLayout->addWidget( myWarningLabel, 0, 0 );
00567   grpLayout->addWidget( myTable,        1, 0, 4, 1 );
00568   grpLayout->addWidget( myShowBtn,      1, 1 );
00569   grpLayout->addWidget( myPublishBtn,   2, 1 );
00570   grpLayout->addWidget( myBadMeshBtn,   3, 1 );
00571   grpLayout->setRowStretch( 4, 1 );
00572 
00573   // Hypothesis definition errors
00574 
00575   myHypErrorGroup = new QGroupBox(tr("SMESH_WRN_MISSING_PARAMETERS"), aFrame);
00576   QHBoxLayout* myHypErrorGroupLayout = new QHBoxLayout(myHypErrorGroup);
00577   myHypErrorGroupLayout->setMargin(MARGIN);
00578   myHypErrorGroupLayout->setSpacing(SPACING);
00579   myHypErrorLabel = new QLabel(myHypErrorGroup);
00580   myHypErrorGroupLayout->addWidget(myHypErrorLabel);
00581 
00582   // Memory Lack Label
00583 
00584   myMemoryLackGroup = new QGroupBox(tr("ERRORS"), aFrame);
00585   QVBoxLayout* myMemoryLackGroupLayout = new QVBoxLayout(myMemoryLackGroup);
00586   myMemoryLackGroupLayout->setMargin(MARGIN);
00587   myMemoryLackGroupLayout->setSpacing(SPACING);
00588   QLabel* memLackLabel = new QLabel(tr("MEMORY_LACK"), myMemoryLackGroup);
00589   QFont bold = memLackLabel->font(); bold.setBold(true);
00590   memLackLabel->setFont( bold );
00591   memLackLabel->setMinimumWidth(300);
00592   myMemoryLackGroupLayout->addWidget(memLackLabel);
00593 
00594   // add all widgets to aFrame
00595   QVBoxLayout* aLay = new QVBoxLayout(aFrame);
00596   aLay->setMargin( 0 );
00597   aLay->setSpacing( 0 );
00598   aLay->addWidget( aPixGrp );
00599   aLay->addWidget( nameBox );
00600   aLay->addWidget( myBriefInfo );
00601   aLay->addWidget( myFullInfo );
00602   aLay->addWidget( myHypErrorGroup );
00603   aLay->addWidget( myCompErrorGroup );
00604   aLay->addWidget( myMemoryLackGroup );
00605   aLay->setStretchFactor( myCompErrorGroup, 1 );
00606 
00607   ((QPushButton*) button( OK ))->setDefault( true );
00608 
00609   return aFrame;
00610 }
00611 
00612 //================================================================================
00616 //================================================================================
00617 
00618 SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp()
00619   : SMESHGUI_Operation(), myCompDlg( 0 )
00620 {
00621   myTShapeDisplayer = new SMESH::TShapeDisplayer();
00622   myBadMeshDisplayer = 0;
00623 
00624   //myHelpFileName = "/files/about_meshes.htm"; // V3
00625   myHelpFileName = "about_meshes_page.html"; // V4
00626 }
00627 
00628 SMESH::SMESH_Mesh_ptr SMESHGUI_BaseComputeOp::getMesh()
00629 {
00630   LightApp_SelectionMgr* Sel = selectionMgr();
00631   SALOME_ListIO selected; Sel->selectedObjects( selected );
00632   Handle(SALOME_InteractiveObject) anIO = selected.First();
00633   SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(anIO);
00634   return myMesh->_is_nil() ? aMesh._retn() : SMESH::SMESH_Mesh::_duplicate( myMesh );
00635 }
00636 
00637 //================================================================================
00642 //================================================================================
00643 
00644 void SMESHGUI_BaseComputeOp::startOperation()
00645 {
00646   // create compute dialog if not created before
00647   computeDlg();
00648 
00649   myMesh      = SMESH::SMESH_Mesh::_nil();
00650   myMainShape = GEOM::GEOM_Object::_nil();
00651 
00652   // check selection
00653   LightApp_SelectionMgr *Sel = selectionMgr();
00654   SALOME_ListIO selected; Sel->selectedObjects( selected );
00655 
00656   int nbSel = selected.Extent();
00657   if (nbSel != 1) {
00658     SUIT_MessageBox::warning(desktop(),
00659                              tr("SMESH_WRN_WARNING"),
00660                              tr("SMESH_WRN_NO_AVAILABLE_DATA"));
00661     onCancel();
00662     return;
00663   }
00664 
00665   myIObject = selected.First();
00666   myMesh = SMESH::GetMeshByIO(myIObject);
00667   if (myMesh->_is_nil()) {
00668     SUIT_MessageBox::warning(desktop(),
00669                              tr("SMESH_WRN_WARNING"),
00670                              tr("SMESH_WRN_NO_AVAILABLE_DATA"));
00671     onCancel();
00672     return;
00673   }
00674   myMainShape = myMesh->GetShapeToMesh();
00675 
00676   SMESHGUI_Operation::startOperation();
00677 }
00678 
00679 //================================================================================
00680 //================================================================================
00681 
00682 SMESHGUI_ComputeDlg_QThread::SMESHGUI_ComputeDlg_QThread(SMESH::SMESH_Gen_var gen,
00683                                                          SMESH::SMESH_Mesh_var mesh,
00684                                                          GEOM::GEOM_Object_var mainShape)
00685 {
00686   myResult = false;
00687   myGen = gen;
00688   myMesh = mesh;
00689   myMainShape = mainShape;
00690 }
00691 
00692 void SMESHGUI_ComputeDlg_QThread::run()
00693 {
00694   myResult = myGen->Compute(myMesh, myMainShape);
00695 }
00696 
00697 bool SMESHGUI_ComputeDlg_QThread::result()
00698 {
00699   return myResult;
00700 }
00701 
00702 void SMESHGUI_ComputeDlg_QThread::cancel()
00703 {
00704   myGen->CancelCompute(myMesh, myMainShape);
00705 }
00706 
00707 //================================================================================
00708 //================================================================================
00709 
00710 SMESHGUI_ComputeDlg_QThreadQDialog::SMESHGUI_ComputeDlg_QThreadQDialog(QWidget *parent,
00711                                                                        SMESH::SMESH_Gen_var gen,
00712                                                                        SMESH::SMESH_Mesh_var mesh,
00713                                                                        GEOM::GEOM_Object_var mainShape)
00714   : QDialog(parent),
00715     qthread(gen, mesh, mainShape)
00716 {
00717   // --
00718   setWindowTitle(tr("Compute"));
00719   cancelButton = new QPushButton(tr("Cancel"));
00720   cancelButton->setDefault(true);
00721   connect(cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));
00722   QHBoxLayout *layout = new QHBoxLayout;
00723   layout->addWidget(cancelButton);
00724   setLayout(layout);
00725   resize(200, 50);
00726   // --
00727   startTimer(30); // 30 millisecs
00728   qthread.start();
00729 }
00730 
00731 bool SMESHGUI_ComputeDlg_QThreadQDialog::result()
00732 {
00733   return qthread.result();
00734 }
00735 
00736 void SMESHGUI_ComputeDlg_QThreadQDialog::onCancel()
00737 {
00738   qthread.cancel();
00739 }  
00740 
00741 void SMESHGUI_ComputeDlg_QThreadQDialog::timerEvent(QTimerEvent *event)
00742 {
00743   if(qthread.isFinished())
00744     {
00745       close();
00746     }
00747   event->accept();
00748 }
00749 
00750 void SMESHGUI_ComputeDlg_QThreadQDialog::closeEvent(QCloseEvent *event)
00751 {
00752   if(qthread.isRunning())
00753     {
00754       event->ignore();
00755       return;
00756     }
00757   event->accept();
00758 }
00759 
00760 //================================================================================
00764 //================================================================================
00765 
00766 void SMESHGUI_BaseComputeOp::computeMesh()
00767 {
00768   // COMPUTE MESH
00769 
00770   SMESH::MemoryReserve aMemoryReserve;
00771 
00772   SMESH::compute_error_array_var aCompErrors;
00773   QString                        aHypErrors;
00774 
00775   bool computeFailed = true, memoryLack = false;
00776 
00777   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
00778   if ( !aMeshSObj ) // IPAL 21340
00779     return;
00780   bool hasShape = myMesh->HasShapeToMesh();
00781   bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
00782   if ( shapeOK )
00783   {
00784     myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
00785     SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
00786     SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
00787     if ( errors->length() > 0 ) {
00788       aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
00789     }
00790     if ( myMesh->HasModificationsToDiscard() && // issue 0020693
00791          SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
00792                                     tr( "FULL_RECOMPUTE_QUESTION" ),
00793                                     tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 1, 0 ) == 0 )
00794       myMesh->Clear();
00795     SUIT_OverrideCursor aWaitCursor;
00796     try {
00797 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00798       OCC_CATCH_SIGNALS;
00799 #endif
00800       //SMESH::UpdateNulData(myIObject, true);
00801       bool res;
00802 #ifdef WITH_SMESH_CANCEL_COMPUTE
00803       SMESHGUI_ComputeDlg_QThreadQDialog qthreaddialog(desktop(), gen, myMesh, myMainShape);
00804       qthreaddialog.exec();
00805       res = qthreaddialog.result();
00806 #else
00807       res = gen->Compute(myMesh, myMainShape);
00808 #endif
00809       if (res)
00810         computeFailed = false;
00811     }
00812     catch(const SALOME::SALOME_Exception & S_ex){
00813       memoryLack = true;
00814     }
00815     try {
00816 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00817       OCC_CATCH_SIGNALS;
00818 #endif
00819       aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
00820       // check if there are memory problems
00821       for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
00822         memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB );
00823     }
00824     catch(const SALOME::SALOME_Exception & S_ex){
00825       memoryLack = true;
00826     }
00827 
00828     if ( !memoryLack && !SMDS_Mesh::CheckMemory(true) ) { // has memory to show dialog boxes?
00829       memoryLack = true;
00830     }
00831 
00832     // NPAL16631: if ( !memoryLack )
00833     {
00834       SMESH::ModifiedMesh(aMeshSObj, !computeFailed, myMesh->NbNodes() == 0);
00835       update( UF_ObjBrowser | UF_Model );
00836 
00837       // SHOW MESH
00838       // NPAL16631: if ( getSMESHGUI()->automaticUpdate() )
00839       SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
00840       long newSize = myMesh->NbElements();
00841       bool limitExceeded;
00842       if ( !memoryLack )
00843       {
00844         if ( getSMESHGUI()->automaticUpdate( newSize, &limitExceeded ) )
00845         {
00846           try {
00847 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00848             OCC_CATCH_SIGNALS;
00849 #endif
00850             SMESH::Update(myIObject, true);
00851           }
00852           catch (...) {
00853 #ifdef _DEBUG_
00854             MESSAGE ( "Exception thrown during mesh visualization" );
00855 #endif
00856             if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
00857               SMESH::OnVisuException();
00858             }
00859             else {
00860               memoryLack = true;
00861             }
00862           }
00863         }
00864         else if ( limitExceeded )
00865         {
00866           long limitSize = resMgr->integerValue( "SMESH", "update_limit", 500000 );
00867           SUIT_MessageBox::warning( desktop(),
00868                                     tr( "SMESH_WRN_WARNING" ),
00869                                     tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).arg( newSize ).arg( limitSize ) );
00870         }
00871       }
00872       LightApp_SelectionMgr *Sel = selectionMgr();
00873       if ( Sel )
00874       {
00875         SALOME_ListIO selected;
00876         selected.Append( myIObject );
00877         Sel->setSelectedObjects( selected );
00878       }
00879     }
00880   }
00881 
00882   if ( memoryLack )
00883     aMemoryReserve.release();
00884 
00885   myCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
00886 
00887   // SHOW ERRORS
00888   
00889   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
00890   bool noHypoError = ( aHypErrors.isEmpty() );
00891 
00892   SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
00893   int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
00894 
00895   bool isShowResultDlg = true;
00896   switch( aNotifyMode ) {
00897   case 0: // show the mesh computation result dialog NEVER
00898     isShowResultDlg = false;
00899     commit();
00900     break;
00901   case 1: // show the mesh computation result dialog if there are some errors
00902     if ( memoryLack || !noCompError || !noHypoError )
00903       isShowResultDlg = true;
00904     else
00905     {
00906       isShowResultDlg = false;
00907       commit();
00908     }
00909     break;
00910   default: // show the result dialog after each mesh computation
00911     isShowResultDlg = true;
00912   }
00913 
00914   // SHOW RESULTS
00915   if ( isShowResultDlg )
00916     showComputeResult( memoryLack, noCompError,aCompErrors, noHypoError, aHypErrors );
00917 }
00918 
00919 void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
00920                                                 const bool theNoCompError,
00921                                                 SMESH::compute_error_array_var& theCompErrors,
00922                                                 const bool theNoHypoError,
00923                                                 const QString& theHypErrors )
00924 {
00925   bool hasShape = myMesh->HasShapeToMesh();
00926   SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
00927   aCompDlg->myMemoryLackGroup->hide();
00928 
00929   if ( theMemoryLack )
00930   {
00931     aCompDlg->myMemoryLackGroup->show();
00932     aCompDlg->myFullInfo->hide();
00933     aCompDlg->myBriefInfo->hide();
00934     aCompDlg->myHypErrorGroup->hide();
00935     aCompDlg->myCompErrorGroup->hide();
00936   }
00937   else if ( theNoCompError && theNoHypoError )
00938   {
00939     SMESH::long_array_var aRes = myMesh->GetMeshInfo();
00940     aCompDlg->myFullInfo->SetMeshInfo( aRes );
00941     aCompDlg->myFullInfo->show();
00942     aCompDlg->myBriefInfo->hide();
00943     aCompDlg->myHypErrorGroup->hide();
00944     aCompDlg->myCompErrorGroup->hide();
00945   }
00946   else
00947   {
00948     bool onlyWarnings = !theNoCompError; // == valid mesh computed but there are errors reported
00949     for ( int i = 0; i < theCompErrors->length() && onlyWarnings; ++i )
00950       onlyWarnings = ( theCompErrors[ i ].code == SMESH::COMPERR_WARNING );
00951 
00952     // full or brief mesh info
00953     SMESH::long_array_var aRes = myMesh->GetMeshInfo();
00954     if ( onlyWarnings ) {
00955       aCompDlg->myFullInfo->SetMeshInfo( aRes );
00956       aCompDlg->myFullInfo->show();
00957       aCompDlg->myBriefInfo->hide();
00958     } else {
00959       aCompDlg->myBriefInfo->SetMeshInfo( aRes );
00960       aCompDlg->myBriefInfo->show();
00961       aCompDlg->myFullInfo->hide();
00962     }
00963 
00964     // pbs of hypo dfinitions
00965     if ( theNoHypoError ) {
00966       aCompDlg->myHypErrorGroup->hide();
00967     } else {
00968       aCompDlg->myHypErrorGroup->show();
00969       aCompDlg->myHypErrorLabel->setText( theHypErrors );
00970     }
00971 
00972     // table of errors
00973     if ( theNoCompError )
00974     {
00975       aCompDlg->myCompErrorGroup->hide();
00976     }
00977     else
00978     {
00979       aCompDlg->myCompErrorGroup->show();
00980 
00981       if ( onlyWarnings )
00982         aCompDlg->myWarningLabel->show();
00983       else
00984         aCompDlg->myWarningLabel->hide();
00985 
00986       if ( !hasShape ) {
00987         aCompDlg->myPublishBtn->hide();
00988         aCompDlg->myShowBtn->hide();
00989       }
00990       else {
00991         aCompDlg->myPublishBtn->show();
00992         aCompDlg->myShowBtn->show();
00993       }
00994 
00995       // fill table of errors
00996       QTableWidget* tbl = aCompDlg->myTable;
00997       tbl->setRowCount( theCompErrors->length() );
00998       if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
00999       else             tbl->showColumn( COL_SHAPE );
01000       tbl->setColumnWidth( COL_ERROR, 200 );
01001 
01002       bool hasBadMesh = false;
01003       for ( int row = 0; row < theCompErrors->length(); ++row )
01004       {
01005         SMESH::ComputeError & err = theCompErrors[ row ];
01006 
01007         QString text = err.algoName.in();
01008         if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
01009         else tbl->item( row, COL_ALGO )->setText( text );
01010 
01011         text = SMESH::errorText( err.code, err.comment.in() );
01012         if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
01013         else tbl->item( row, COL_ERROR )->setText( text );
01014 
01015         text = QString("%1").arg( err.subShapeID );
01016         if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
01017         else tbl->item( row, COL_SHAPEID )->setText( text );
01018 
01019         text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
01020         if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
01021         else tbl->item( row, COL_SHAPE )->setText( text );
01022 
01023         text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
01024         if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
01025         else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
01026 
01027         text = err.hasBadMesh ? "hasBadMesh" : "";
01028         if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
01029         else tbl->item( row, COL_BAD_MESH )->setText( text );
01030         if ( err.hasBadMesh ) hasBadMesh = true;
01031 
01032         //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
01033         tbl->resizeRowToContents( row );
01034       }
01035       tbl->resizeColumnToContents( COL_ALGO );
01036       tbl->resizeColumnToContents( COL_SHAPE );
01037 
01038       if ( hasBadMesh )
01039         aCompDlg->myBadMeshBtn->show();
01040       else
01041         aCompDlg->myBadMeshBtn->hide();
01042 
01043       tbl->setCurrentCell(0,0);
01044       currentCellChanged(); // to update buttons
01045     }
01046   }
01047   // show dialog and wait, becase Compute can be invoked from Preview operation
01048   //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
01049   aCompDlg->show();
01050 }
01051 
01052 //================================================================================
01056 //================================================================================
01057 
01058 void SMESHGUI_BaseComputeOp::stopOperation()
01059 {
01060   SMESHGUI_Operation::stopOperation();
01061   if ( myTShapeDisplayer )
01062     myTShapeDisplayer->SetVisibility( false );
01063   if ( myBadMeshDisplayer ) {
01064     myBadMeshDisplayer->SetVisibility( false );
01065     // delete it in order not to have problems at its destruction when the viewer
01066     // where it worked is dead due to e.g. study closing
01067     delete myBadMeshDisplayer;
01068     myBadMeshDisplayer = 0;
01069   }
01070   myIObject.Nullify();
01071 }
01072 
01073 //================================================================================
01077 //================================================================================
01078 
01079 void SMESHGUI_BaseComputeOp::onPublishShape()
01080 {
01081   GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
01082   SALOMEDS::Study_var study = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
01083 
01084   QList<int> rows;
01085   SMESH::getSelectedRows( table(), rows );
01086   int row;
01087   foreach ( row, rows )
01088   {
01089     int curSub = table()->item(row, COL_SHAPEID)->text().toInt();
01090     GEOM::GEOM_Object_var shape = SMESH::getSubShape( curSub, myMainShape );
01091     if ( !shape->_is_nil() && ! SMESH::getSubShapeSO( curSub, myMainShape ))
01092     {
01093       if ( !SMESH::getSubShapeSO( 1, myMainShape )) // the main shape not published
01094       {
01095         QString name = GEOMBase::GetDefaultName( SMESH::shapeTypeName( myMainShape, "MAIN_SHAPE" ));
01096         SALOMEDS::SObject_var so =
01097           geomGen->AddInStudy( study, myMainShape, name.toLatin1().data(), GEOM::GEOM_Object::_nil());
01098         // look for myMainShape in the table
01099         for ( int r = 0, nr = table()->rowCount(); r < nr; ++r ) {
01100           if ( table()->item( r, COL_SHAPEID )->text() == "1" ) {
01101             if ( so->_is_nil() ) {
01102               table()->item( r, COL_SHAPE )->setText( so->GetName() );
01103               table()->item( r, COL_PUBLISHED )->setText( so->GetID() );
01104             }
01105             break;
01106           }
01107         }
01108         if ( curSub == 1 ) continue;
01109       }
01110       QString name = GEOMBase::GetDefaultName( SMESH::shapeTypeName( shape, "ERROR_SHAPE" ));
01111       SALOMEDS::SObject_var so = geomGen->AddInStudy( study, shape, name.toLatin1().data(), myMainShape);
01112       if ( !so->_is_nil() ) {
01113         table()->item( row, COL_SHAPE )->setText( so->GetName() );
01114         table()->item( row, COL_PUBLISHED )->setText( so->GetID() );
01115       }
01116     }
01117   }
01118   getSMESHGUI()->getApp()->updateObjectBrowser();
01119   currentCellChanged(); // to update buttons
01120 }
01121 
01122 //================================================================================
01126 //================================================================================
01127 
01128 void SMESHGUI_BaseComputeOp::onShowBadMesh()
01129 {
01130   myTShapeDisplayer->SetVisibility( false );
01131   QList<int> rows;
01132   if ( SMESH::getSelectedRows( table(), rows ) == 1 ) {
01133     bool hasBadMesh = ( !table()->item(rows.front(), COL_BAD_MESH)->text().isEmpty() );
01134     if ( hasBadMesh ) {
01135       int curSub = table()->item(rows.front(), COL_SHAPEID)->text().toInt();
01136       SMESHGUI* gui = getSMESHGUI();
01137       SMESH::SMESH_Gen_var gen = gui->GetSMESHGen();
01138       SVTK_ViewWindow*    view = SMESH::GetViewWindow( gui );
01139       if ( myBadMeshDisplayer ) delete myBadMeshDisplayer;
01140       myBadMeshDisplayer = new SMESHGUI_MeshEditPreview( view );
01141       SMESH::MeshPreviewStruct_var aMeshData = gen->GetBadInputElements(myMesh,curSub);
01142       vtkFloatingPointType aPointSize = SMESH::GetFloat("SMESH:node_size",3);
01143       vtkFloatingPointType aLineWidth = SMESH::GetFloat("SMESH:element_width",1);
01144       // delete property !!!!!!!!!!
01145       vtkProperty* prop = vtkProperty::New();
01146       prop->SetLineWidth( aLineWidth * 3 );
01147       prop->SetPointSize( aPointSize * 3 );
01148       prop->SetColor( 250, 0, 250 );
01149       myBadMeshDisplayer->GetActor()->SetProperty( prop );
01150       myBadMeshDisplayer->SetData( aMeshData._retn() );
01151     }
01152   }
01153 }
01154 
01155 //================================================================================
01159 //================================================================================
01160 
01161 void SMESHGUI_BaseComputeOp::currentCellChanged()
01162 {
01163   myTShapeDisplayer->SetVisibility( false );
01164   if ( myBadMeshDisplayer )
01165     myBadMeshDisplayer->SetVisibility( false );
01166 
01167   bool publishEnable = 0, showEnable = 0, showOnly = 1, hasBadMesh = 0;
01168   QList<int> rows;
01169   int nbSelected = SMESH::getSelectedRows( table(), rows );
01170   int row;
01171   foreach ( row, rows )
01172   {
01173     bool hasData     = ( !table()->item( row, COL_SHAPE )->text().isEmpty() );
01174     bool isPublished = ( !table()->item( row, COL_PUBLISHED )->text().isEmpty() );
01175     if ( hasData && !isPublished )
01176       publishEnable = true;
01177 
01178     int curSub = table()->item( row, COL_SHAPEID )->text().toInt();
01179     bool prsReady = myTShapeDisplayer->HasReadyActorsFor( curSub, myMainShape );
01180     if ( prsReady ) {
01181       myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
01182       showOnly = false;
01183     }
01184     else {
01185       showEnable = true;
01186     }
01187 
01188     if ( !table()->item(row, COL_BAD_MESH)->text().isEmpty() )
01189       hasBadMesh = true;
01190   }
01191   myCompDlg->myPublishBtn->setEnabled( publishEnable );
01192   myCompDlg->myShowBtn   ->setEnabled( showEnable );
01193   myCompDlg->myBadMeshBtn->setEnabled( hasBadMesh && ( nbSelected == 1 ));
01194 }
01195 
01196 //================================================================================
01200 //================================================================================
01201 
01202 void SMESHGUI_BaseComputeOp::onPreviewShape()
01203 {
01204   if ( myTShapeDisplayer )
01205   {
01206     SUIT_OverrideCursor aWaitCursor;
01207     QList<int> rows;
01208     SMESH::getSelectedRows( table(), rows );
01209 
01210     bool showOnly = true;
01211     int row;
01212     foreach ( row, rows )
01213     {
01214       int curSub = table()->item( row, COL_SHAPEID )->text().toInt();
01215       if ( curSub > 0 ) {
01216         myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
01217         showOnly = false;
01218       }
01219     }
01220     currentCellChanged(); // to update buttons
01221   }
01222 }
01223 
01224 //================================================================================
01228 //================================================================================
01229 
01230 SMESHGUI_BaseComputeOp::~SMESHGUI_BaseComputeOp()
01231 {
01232   delete myCompDlg;
01233   myCompDlg = 0;
01234   delete myTShapeDisplayer;
01235   if ( myBadMeshDisplayer )
01236     delete myBadMeshDisplayer;
01237 }
01238 
01239 //================================================================================
01244 //================================================================================
01245 
01246 SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::computeDlg() const
01247 {
01248   if ( !myCompDlg )
01249   {
01250     SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
01251     me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), false );
01252     // connect signals and slots
01253     connect(myCompDlg->myShowBtn,    SIGNAL (clicked()), SLOT(onPreviewShape()));
01254     connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
01255     connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh()));
01256 
01257     QTableWidget* aTable = me->table();
01258     connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged()));
01259     connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged()));
01260   }
01261   return myCompDlg;
01262 }
01263 
01264 //================================================================================
01268 //================================================================================
01269 
01270 bool SMESHGUI_BaseComputeOp::onApply()
01271 {
01272   return true;
01273 }
01274 
01275 //================================================================================
01279 //================================================================================
01280 
01281 QTableWidget* SMESHGUI_BaseComputeOp::table()
01282 {
01283   return myCompDlg->myTable;
01284 }
01285 
01286 
01287 //================================================================================
01291 //================================================================================
01292 
01293 SMESHGUI_ComputeOp::SMESHGUI_ComputeOp()
01294  : SMESHGUI_BaseComputeOp()
01295 {
01296 }
01297 
01298 
01299 //================================================================================
01303 //================================================================================
01304 
01305 SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp()
01306 {
01307 }
01308 
01309 //================================================================================
01313 //================================================================================
01314 
01315 void SMESHGUI_ComputeOp::startOperation()
01316 {
01317   SMESHGUI_BaseComputeOp::startOperation();
01318   if (myMesh->_is_nil())
01319     return;
01320   computeMesh();
01321 }
01322 
01323 //================================================================================
01327 //================================================================================
01328 
01329 bool SMESHGUI_BaseComputeOp::isValid(  SUIT_Operation* theOp  ) const
01330 {
01331   SMESHGUI_BaseComputeOp* baseOp = dynamic_cast<SMESHGUI_BaseComputeOp*>( theOp );
01332   bool ret = true;
01333   if ( !myMesh->_is_nil() && baseOp ) {
01334     SMESH::SMESH_Mesh_var aMesh = baseOp->getMesh();
01335     if ( !aMesh->_is_nil() && aMesh->GetId() == myMesh->GetId() ) ret = false;
01336   }
01337   return ret;
01338 }
01339 
01340 //================================================================================
01345 //================================================================================
01346 
01347 LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
01348 {
01349   return computeDlg();
01350 }
01351 
01352 //================================================================================
01356 //================================================================================
01357 
01358 SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp()
01359  : SMESHGUI_BaseComputeOp(),
01360  myDlg( 0 ),
01361  myOrderMgr( 0 ),
01362  myActiveDlg( 0 ),
01363  myPreviewDisplayer( 0 )
01364 {
01365   myHelpFileName = "constructing_meshes_page.html#preview_mesh_anchor";
01366 }
01367 
01368 //================================================================================
01372 //================================================================================
01373 
01374 SMESHGUI_PrecomputeOp::~SMESHGUI_PrecomputeOp()
01375 {
01376   delete myDlg;
01377   myDlg = 0;
01378   delete myOrderMgr;
01379   myOrderMgr = 0;
01380   myActiveDlg = 0;
01381   if ( myPreviewDisplayer )
01382     delete myPreviewDisplayer;
01383   myPreviewDisplayer = 0;
01384 }
01385 
01386 //================================================================================
01391 //================================================================================
01392 
01393 LightApp_Dialog* SMESHGUI_PrecomputeOp::dlg() const
01394 {
01395   return myActiveDlg;
01396 }
01397 
01398 //================================================================================
01402 //================================================================================
01403 
01404 void SMESHGUI_PrecomputeOp::startOperation()
01405 {
01406   if ( !myDlg )
01407   {
01408     myDlg = new SMESHGUI_PrecomputeDlg( desktop() );
01409     
01410     // connect signals
01411     connect( myDlg, SIGNAL( preview() ), this, SLOT( onPreview() ) );
01412     connect( myDlg, SIGNAL( dlgOk() ), this, SLOT( onCompute() ) );
01413     connect( myDlg, SIGNAL( dlgApply() ), this, SLOT( onCompute() ) );
01414   }
01415   myActiveDlg = myDlg;
01416 
01417   // connect signal to compute dialog. which will be shown after Compute mesh operation
01418   SMESHGUI_ComputeDlg* cmpDlg = computeDlg();
01419   if ( cmpDlg )
01420   {
01421     // disconnect signals
01422     disconnect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
01423     disconnect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
01424     disconnect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
01425     disconnect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
01426     disconnect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
01427 
01428     // connect signals
01429     if( cmpDlg->testButtonFlags( QtxDialog::OK ) )
01430       connect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
01431     if( cmpDlg->testButtonFlags( QtxDialog::Apply ) )
01432       connect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
01433     if( cmpDlg->testButtonFlags( QtxDialog::Help ) )
01434       connect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
01435     if( cmpDlg->testButtonFlags( QtxDialog::Cancel ) )
01436       connect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
01437     if( cmpDlg->testButtonFlags( QtxDialog::Close ) )
01438       connect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
01439   }
01440 
01441   SMESHGUI_BaseComputeOp::startOperation();
01442   if (myMesh->_is_nil())
01443     return;
01444 
01445   if (myDlg->getPreviewMode() == -1)
01446   {
01447     // nothing to preview
01448     SUIT_MessageBox::warning(desktop(),
01449                              tr("SMESH_WRN_WARNING"),
01450                              tr("SMESH_WRN_NOTHING_PREVIEW"));
01451     onCancel();
01452     return;
01453   }
01454 
01455   // disconnect slot from preview dialog to have Apply from results of compute operation only 
01456   disconnect( myDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
01457   disconnect( myDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
01458 
01459   myDlg->show();
01460 }
01461 
01462 //================================================================================
01466 //================================================================================
01467 
01468 void SMESHGUI_PrecomputeOp::stopOperation()
01469 {
01470   if ( myPreviewDisplayer )
01471   {
01472     myPreviewDisplayer->SetVisibility( false );
01473     delete myPreviewDisplayer;
01474     myPreviewDisplayer = 0;
01475   }
01476   myMapShapeId.clear();
01477   SMESHGUI_BaseComputeOp::stopOperation();
01478 }
01479 
01480 //================================================================================
01484 //================================================================================
01485 
01486 void SMESHGUI_PrecomputeOp::resumeOperation()
01487 {
01488   if ( myActiveDlg == myDlg )
01489     initDialog();
01490   SMESHGUI_BaseComputeOp::resumeOperation();
01491 }
01492 
01493 //================================================================================
01497 //================================================================================
01498 
01499 void SMESHGUI_PrecomputeOp::initDialog()
01500 {
01501   QList<int> modes;
01502 
01503   QMap<int, int> modeMap;
01504   _PTR(SObject)  pMesh = studyDS()->FindObjectID( myIObject->getEntry() );
01505   getAssignedAlgos( pMesh, modeMap );
01506   if ( modeMap.contains( SMESH::DIM_3D ) )
01507   {
01508     if ( modeMap.contains( SMESH::DIM_2D ) )
01509       modes.append( SMESH::DIM_2D );
01510     if ( modeMap.contains( SMESH::DIM_1D ) )
01511       modes.append( SMESH::DIM_1D );
01512   }
01513   else if ( modeMap.contains( SMESH::DIM_2D ) )
01514   {
01515     if ( modeMap.contains( SMESH::DIM_1D ) )
01516       modes.append( SMESH::DIM_1D );
01517   }
01518 
01519   myOrderMgr = new SMESHGUI_MeshOrderMgr( myDlg->getMeshOrderBox() );
01520   myOrderMgr->SetMesh( myMesh );
01521   bool isOrder = myOrderMgr->GetMeshOrder(myPrevOrder);
01522   myDlg->getMeshOrderBox()->setShown(isOrder);
01523   if ( !isOrder ) {
01524     delete myOrderMgr;
01525     myOrderMgr = 0;
01526   }
01527 
01528   myDlg->setPreviewModes( modes );
01529 }
01530 
01531 //================================================================================
01535 //================================================================================
01536 
01537 void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
01538                                              QMap<int,int>& theModeMap)
01539 {
01540   _PTR(SObject)          aHypRoot;
01541   _PTR(GenericAttribute) anAttr;
01542   int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
01543   if ( theMesh && theMesh->FindSubObject( aPart, aHypRoot ) )
01544   {
01545     _PTR(ChildIterator) anIter =
01546       SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
01547     for ( ; anIter->More(); anIter->Next() )
01548     {
01549       _PTR(SObject) anObj = anIter->Value();
01550       _PTR(SObject) aRefObj;
01551       if ( anObj->ReferencedObject( aRefObj ) )
01552         anObj = aRefObj;
01553       else
01554         continue;
01555       
01556       if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
01557       {
01558         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
01559         if ( CORBA::is_nil( aVar ) )
01560           continue;
01561         
01562         for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
01563         {
01564           SMESH::SMESH_Algo_var algo;
01565           switch(dim) {
01566           case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break;
01567           case SMESH::DIM_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break;
01568           case SMESH::DIM_3D: algo = SMESH::SMESH_3D_Algo::_narrow( aVar ); break;
01569           default: break;
01570           }
01571           if ( !algo->_is_nil() )
01572             theModeMap[ dim ] = 0;
01573         }
01574       }
01575     }
01576   }
01577 }
01578 
01579 //================================================================================
01583 //================================================================================
01584 
01585 void SMESHGUI_PrecomputeOp::onCompute()
01586 {
01587   myDlg->hide();
01588   if (myOrderMgr && myOrderMgr->IsOrderChanged())
01589     myOrderMgr->SetMeshOrder();
01590   myMapShapeId.clear();
01591   myActiveDlg = computeDlg();
01592   computeMesh();
01593 }
01594 
01595 //================================================================================
01599 //================================================================================
01600 
01601 void SMESHGUI_PrecomputeOp::onCancel()
01602 {
01603   QObject* curDlg = sender();
01604   if ( curDlg == computeDlg() && myActiveDlg == myDlg )
01605   {
01606     // return from error messages
01607     myDlg->show();
01608     return;
01609   }
01610 
01611   bool isRestoreOrder = false;
01612   if ( myActiveDlg == myDlg  && !myMesh->_is_nil() && myMapShapeId.count() )
01613   {
01614     // ask to remove already computed mesh elements
01615     if ( SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
01616                                     tr( "CLEAR_SUBMESH_QUESTION" ),
01617                                     tr( "SMESH_BUT_DELETE" ), tr( "SMESH_BUT_NO" ), 0, 1 ) == 0 )
01618     {
01619       // remove all submeshes for collected shapes
01620       QMap<int,int>::const_iterator it = myMapShapeId.constBegin();
01621       for ( ; it != myMapShapeId.constEnd(); ++it )
01622         myMesh->ClearSubMesh( *it );
01623       isRestoreOrder = true;
01624     }
01625   }
01626 
01627   // return previous mesh order
01628   if (myOrderMgr && myOrderMgr->IsOrderChanged()) {
01629     if (!isRestoreOrder)
01630       isRestoreOrder = 
01631         (SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
01632                                     tr( "SMESH_REJECT_MESH_ORDER" ),
01633                                     tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ) == 0);
01634     if (isRestoreOrder)
01635       myOrderMgr->SetMeshOrder(myPrevOrder);
01636   }
01637 
01638   delete myOrderMgr;
01639   myOrderMgr = 0;
01640 
01641   myMapShapeId.clear();
01642   SMESHGUI_BaseComputeOp::onCancel();
01643 }
01644 
01645 //================================================================================
01649 //================================================================================
01650 
01651 void SMESHGUI_PrecomputeOp::onPreview()
01652 {
01653   if ( !myDlg || myMesh->_is_nil() || myMainShape->_is_nil() )
01654     return;
01655 
01656   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
01657   if ( !aMeshSObj )
01658     return;
01659 
01660   // set modified submesh priority if any
01661   if (myOrderMgr && myOrderMgr->IsOrderChanged())
01662     myOrderMgr->SetMeshOrder();
01663 
01664   // Compute preview of mesh, 
01665   // i.e. compute mesh till indicated dimension
01666   int dim = myDlg->getPreviewMode();
01667   
01668   SMESH::MemoryReserve aMemoryReserve;
01669   
01670   SMESH::compute_error_array_var aCompErrors;
01671   QString                        aHypErrors;
01672 
01673   bool computeFailed = true, memoryLack = false;
01674 
01675   SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
01676     aCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
01677 
01678   SMESHGUI* gui = getSMESHGUI();
01679   SMESH::SMESH_Gen_var gen = gui->GetSMESHGen();
01680   SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
01681   if ( errors->length() > 0 ) {
01682     aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
01683   }
01684 
01685   SUIT_OverrideCursor aWaitCursor;
01686 
01687   SVTK_ViewWindow*    view = SMESH::GetViewWindow( gui );
01688   if ( myPreviewDisplayer ) delete myPreviewDisplayer;
01689   myPreviewDisplayer = new SMESHGUI_MeshEditPreview( view );
01690   
01691   SMESH::long_array_var aShapesId = new SMESH::long_array();
01692   try {
01693 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
01694     OCC_CATCH_SIGNALS;
01695 #endif
01696       
01697     SMESH::MeshPreviewStruct_var previewData =
01698       gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId);
01699 
01700     SMESH::MeshPreviewStruct* previewRes = previewData._retn();
01701     if ( previewRes && previewRes->nodesXYZ.length() > 0 )
01702     {
01703       computeFailed = false;
01704       myPreviewDisplayer->SetData( previewRes );
01705       // append shape indeces with computed mesh entities
01706       for ( int i = 0, n = aShapesId->length(); i < n; i++ )
01707         myMapShapeId[ aShapesId[ i ] ] = 0;
01708     }
01709     else
01710       myPreviewDisplayer->SetVisibility(false);
01711   }
01712   catch(const SALOME::SALOME_Exception & S_ex){
01713     memoryLack = true;
01714     myPreviewDisplayer->SetVisibility(false);
01715   }
01716 
01717   try {
01718 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
01719     OCC_CATCH_SIGNALS;
01720 #endif
01721     aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
01722     // check if there are memory problems
01723     for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
01724       memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB );
01725   }
01726   catch(const SALOME::SALOME_Exception & S_ex){
01727     memoryLack = true;
01728   }
01729 
01730   if ( memoryLack )
01731     aMemoryReserve.release();
01732 
01733   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
01734   bool noHypoError = ( aHypErrors.isEmpty() );
01735 
01736   SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( gui );
01737   int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
01738 
01739   bool isShowError = true;
01740   switch( aNotifyMode ) {
01741   case 0: // show the mesh computation result dialog NEVER
01742     isShowError = false;
01743     break;
01744   case 1: // show the mesh computation result dialog if there are some errors
01745   default: // show the result dialog after each mesh computation
01746     if ( !computeFailed && !memoryLack && noCompError && noHypoError )
01747       isShowError = false;
01748     break;
01749   }
01750 
01751   aWaitCursor.suspend();
01752   // SHOW ERRORS
01753   if ( isShowError )
01754   {
01755     myDlg->hide();
01756     aCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
01757     showComputeResult( memoryLack, noCompError, aCompErrors, noHypoError, aHypErrors );
01758   }
01759 }
01760 
01761 
01762 //================================================================================
01766 //================================================================================
01767 
01768 SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent )
01769  : SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help ),
01770    myOrderBox(0)
01771 {
01772   setWindowTitle( tr( "CAPTION" ) );
01773 
01774   setButtonText( OK, tr( "COMPUTE" ) );
01775   QFrame* main = mainFrame();
01776 
01777   QVBoxLayout* layout = new QVBoxLayout( main );
01778 
01779   myOrderBox = new SMESHGUI_MeshOrderBox( main );
01780   layout->addWidget(myOrderBox);
01781 
01782   QFrame* frame = new QFrame( main );
01783   layout->setMargin(0); layout->setSpacing(0);
01784   layout->addWidget( frame );
01785 
01786   QHBoxLayout* frameLay = new QHBoxLayout( frame );
01787   frameLay->setMargin(0); frameLay->setSpacing(SPACING);
01788   
01789   myPreviewMode = new QtxComboBox( frame );
01790   frameLay->addWidget( myPreviewMode );
01791 
01792   myPreviewBtn = new QPushButton( tr( "PREVIEW" ), frame );
01793   frameLay->addWidget( myPreviewBtn );
01794 
01795   connect( myPreviewBtn, SIGNAL( clicked( bool ) ), this, SIGNAL( preview() ) );
01796 }
01797 
01798 //================================================================================
01802 //================================================================================
01803 
01804 SMESHGUI_PrecomputeDlg::~SMESHGUI_PrecomputeDlg()
01805 {
01806 }
01807 
01808 //================================================================================
01812 //================================================================================
01813 
01814 void SMESHGUI_PrecomputeDlg::setPreviewModes( const QList<int>& theModes )
01815 {
01816   myPreviewMode->clear();
01817   QList<int>::const_iterator it = theModes.constBegin();
01818   for ( int i = 0; it != theModes.constEnd(); ++it, i++ )
01819   {
01820     QString mode = QString( "PREVIEW_%1" ).arg( *it );
01821     myPreviewMode->addItem( tr( mode.toLatin1().data() ) );
01822     myPreviewMode->setId( i, *it );
01823   }
01824   myPreviewBtn->setEnabled( !theModes.isEmpty() );
01825 }
01826 
01827 //================================================================================
01831 //================================================================================
01832 
01833 int SMESHGUI_PrecomputeDlg::getPreviewMode() const
01834 {
01835   return myPreviewMode->currentId();
01836 }
01837 
01838 //================================================================================
01842 //================================================================================
01843 
01844 SMESHGUI_MeshOrderBox* SMESHGUI_PrecomputeDlg::getMeshOrderBox() const
01845 {
01846   return myOrderBox;
01847 }
01848 
01849 
01850 //================================================================================
01854 //================================================================================
01855 
01856 SMESHGUI_EvaluateOp::SMESHGUI_EvaluateOp()
01857  : SMESHGUI_BaseComputeOp()
01858 {
01859 }
01860 
01861 
01862 //================================================================================
01866 //================================================================================
01867 
01868 SMESHGUI_EvaluateOp::~SMESHGUI_EvaluateOp()
01869 {
01870 }
01871 
01872 //================================================================================
01876 //================================================================================
01877 
01878 void SMESHGUI_EvaluateOp::startOperation()
01879 {
01880   SMESHGUI_BaseComputeOp::evaluateDlg();
01881   SMESHGUI_BaseComputeOp::startOperation();
01882   if (myMesh->_is_nil())
01883     return;
01884   evaluateMesh();
01885 }
01886 
01887 //================================================================================
01892 //================================================================================
01893 
01894 LightApp_Dialog* SMESHGUI_EvaluateOp::dlg() const
01895 {
01896   return evaluateDlg();
01897 }
01898 
01899 //================================================================================
01903 //================================================================================
01904 
01905 void SMESHGUI_BaseComputeOp::evaluateMesh()
01906 {
01907   // EVALUATE MESH
01908 
01909   SMESH::MemoryReserve aMemoryReserve;
01910 
01911   SMESH::compute_error_array_var aCompErrors;
01912   QString                        aHypErrors;
01913 
01914   bool evaluateFailed = true, memoryLack = false;
01915   SMESH::long_array_var aRes;
01916 
01917   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
01918   if ( !aMeshSObj ) //  IPAL21340
01919     return;
01920 
01921   bool hasShape = myMesh->HasShapeToMesh();
01922   bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
01923   if ( shapeOK )
01924   {
01925     myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
01926     SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
01927     SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
01928     if ( errors->length() > 0 ) {
01929       aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
01930     }
01931     SUIT_OverrideCursor aWaitCursor;
01932     try {
01933 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
01934       OCC_CATCH_SIGNALS;
01935 #endif
01936       aRes = gen->Evaluate(myMesh, myMainShape);
01937     }
01938     catch(const SALOME::SALOME_Exception & S_ex){
01939       memoryLack = true;
01940     }
01941 
01942     try {
01943 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
01944       OCC_CATCH_SIGNALS;
01945 #endif
01946       aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
01947     }
01948     catch(const SALOME::SALOME_Exception & S_ex){
01949       memoryLack = true;
01950     }
01951   }
01952 
01953   if ( memoryLack )
01954     aMemoryReserve.release();
01955 
01956   evaluateFailed =  ( aCompErrors->length() > 0 );
01957   myCompDlg->setWindowTitle(tr( evaluateFailed ? "SMESH_WRN_EVALUATE_FAILED" : "SMESH_EVALUATE_SUCCEED"));
01958 
01959   // SHOW ERRORS
01960   
01961   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
01962   bool noHypoError = ( aHypErrors.isEmpty() );
01963 
01964   //SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
01965   //int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
01966 
01967   bool isShowResultDlg = true;
01968   //if( noHypoError )
01969   //switch( aNotifyMode ) {
01970   //case 0: // show the mesh computation result dialog NEVER
01971   //isShowResultDlg = false;
01972   //commit();
01973   //break;
01974   //case 1: // show the mesh computation result dialog if there are some errors
01975   //if ( memoryLack || !noHypoError )
01976   //  isShowResultDlg = true;
01977   //else
01978   //{
01979   //  isShowResultDlg = false;
01980   //  commit();
01981   //}
01982   //break;
01983   //default: // show the result dialog after each mesh computation
01984   //isShowResultDlg = true;
01985   //}
01986 
01987   // SHOW RESULTS
01988   if ( isShowResultDlg )
01989     showEvaluateResult( aRes, memoryLack, noCompError, aCompErrors,
01990                         noHypoError, aHypErrors);
01991 }
01992 
01993 
01994 void SMESHGUI_BaseComputeOp::showEvaluateResult(const SMESH::long_array& theRes,
01995                                                 const bool theMemoryLack,
01996                                                 const bool theNoCompError,
01997                                                 SMESH::compute_error_array_var& theCompErrors,
01998                                                 const bool theNoHypoError,
01999                                                 const QString& theHypErrors)
02000 {
02001   bool hasShape = myMesh->HasShapeToMesh();
02002   SMESHGUI_ComputeDlg* aCompDlg = evaluateDlg();
02003   aCompDlg->myMemoryLackGroup->hide();
02004 
02005   if ( theMemoryLack )
02006   {
02007     aCompDlg->myMemoryLackGroup->show();
02008     aCompDlg->myFullInfo->hide();
02009     aCompDlg->myBriefInfo->hide();
02010     aCompDlg->myHypErrorGroup->hide();
02011     aCompDlg->myCompErrorGroup->hide();
02012   }
02013   else if ( theNoCompError && theNoHypoError )
02014   {
02015     aCompDlg->myFullInfo->SetMeshInfo( theRes );
02016     aCompDlg->myFullInfo->show();
02017     aCompDlg->myBriefInfo->hide();
02018     aCompDlg->myHypErrorGroup->hide();
02019     aCompDlg->myCompErrorGroup->hide();
02020   }
02021   else
02022   {
02023     QTableWidget* tbl = aCompDlg->myTable;
02024     aCompDlg->myBriefInfo->SetMeshInfo( theRes );
02025     aCompDlg->myBriefInfo->show();
02026     aCompDlg->myFullInfo->hide();
02027 
02028     if ( theNoHypoError ) {
02029       aCompDlg->myHypErrorGroup->hide();
02030     }
02031     else {
02032       aCompDlg->myHypErrorGroup->show();
02033       aCompDlg->myHypErrorLabel->setText( theHypErrors );
02034     }
02035 
02036     if ( theNoCompError ) {
02037       aCompDlg->myCompErrorGroup->hide();
02038     }
02039     else {
02040       aCompDlg->myCompErrorGroup->show();
02041 
02042       aCompDlg->myPublishBtn->hide();
02043       aCompDlg->myShowBtn->hide();
02044 
02045       // fill table of errors
02046       tbl->setRowCount( theCompErrors->length() );
02047       if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
02048       else             tbl->showColumn( COL_SHAPE );
02049       tbl->setColumnWidth( COL_ERROR, 200 );
02050 
02051       bool hasBadMesh = false;
02052       for ( int row = 0; row < theCompErrors->length(); ++row )
02053       {
02054         SMESH::ComputeError & err = theCompErrors[ row ];
02055 
02056         QString text = err.algoName.in();
02057         if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
02058         else tbl->item( row, COL_ALGO )->setText( text );
02059 
02060         text = SMESH::errorText( err.code, err.comment.in() );
02061         if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
02062         else tbl->item( row, COL_ERROR )->setText( text );
02063 
02064         text = QString("%1").arg( err.subShapeID );
02065         if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
02066         else tbl->item( row, COL_SHAPEID )->setText( text );
02067 
02068         text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
02069         if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
02070         else tbl->item( row, COL_SHAPE )->setText( text );
02071 
02072         text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
02073         if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
02074         else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
02075 
02076         text = err.hasBadMesh ? "hasBadMesh" : "";
02077         if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
02078         else tbl->item( row, COL_BAD_MESH )->setText( text );
02079         if ( err.hasBadMesh ) hasBadMesh = true;
02080 
02081         //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
02082         tbl->resizeRowToContents( row );
02083       }
02084       tbl->resizeColumnToContents( COL_ALGO );
02085       tbl->resizeColumnToContents( COL_SHAPE );
02086 
02087       if ( hasBadMesh )
02088         aCompDlg->myBadMeshBtn->show();
02089       else
02090         aCompDlg->myBadMeshBtn->hide();
02091 
02092       tbl->setCurrentCell(0,0);
02093       currentCellChanged(); // to update buttons
02094     }
02095   }
02096   // show dialog and wait, becase Compute can be invoked from Preview operation
02097   //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
02098   aCompDlg->show();
02099 }
02100 
02101 
02102 //================================================================================
02107 //================================================================================
02108 
02109 SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::evaluateDlg() const
02110 {
02111   if ( !myCompDlg )
02112   {
02113     SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
02114     me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), true );
02115     // connect signals and slots
02116     connect(myCompDlg->myShowBtn,    SIGNAL (clicked()), SLOT(onPreviewShape()));
02117     connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
02118     connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh()));
02119     QTableWidget* aTable = me->table();
02120     connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged()));
02121     connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged()));
02122   }
02123   return myCompDlg;
02124 }
02125