]> SALOME platform Git repositories - modules/smesh.git/blob - src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
Salome HOME
Rollback previous wrong integration, restore improvement 0018239 implementation
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_ComputeDlg.cxx
1 // Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 //
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
8 //
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 // File   : SMESHGUI_ComputeDlg.cxx
21 // Author : Edward AGAPOV, Open CASCADE S.A.S.
22 //
23
24 // SMESH includes
25 #include "SMESHGUI_ComputeDlg.h"
26
27 #include "SMESHGUI.h"
28 #include "SMESHGUI_GEOMGenUtils.h"
29 #include "SMESHGUI_MeshUtils.h"
30 #include "SMESHGUI_VTKUtils.h"
31 #include "SMESHGUI_HypothesesUtils.h"
32 #include "SMESHGUI_MeshEditPreview.h"
33 #include "SMESH_ActorUtils.h"
34
35 #include <SMDS_SetIterator.hxx>
36 #include <SMDS_Mesh.hxx>
37
38 // SALOME GEOM includes
39 #include <GEOMBase.h>
40 #include <GEOM_Actor.h>
41
42 // SALOME GUI includes
43 #include <LightApp_SelectionMgr.h>
44 #include <LightApp_UpdateFlags.h>
45 #include <SALOME_ListIO.hxx>
46 #include <SVTK_ViewWindow.h>
47 #include <SVTK_ViewModel.h>
48 #include <SalomeApp_Application.h>
49 #include <SUIT_ResourceMgr.h>
50 #include <SUIT_OverrideCursor.h>
51 #include <SUIT_MessageBox.h>
52 #include <SUIT_Desktop.h>
53 #include <QtxComboBox.h>
54
55 // SALOME KERNEL includes
56 #include <SALOMEDS_SObject.hxx>
57 #include <SALOMEDSClient_SObject.hxx>
58
59 // OCCT includes
60 #include <BRep_Tool.hxx>
61 #include <TopExp.hxx>
62 #include <TopExp_Explorer.hxx>
63 #include <TopTools_IndexedMapOfShape.hxx>
64 #include <TopoDS.hxx>
65
66 #include <TopLoc_Location.hxx>
67 #include <Poly_Triangulation.hxx>
68 #include <Bnd_Box.hxx>
69 #include <BRepBndLib.hxx>
70 #include <BRepMesh_IncrementalMesh.hxx>
71
72 #include <Standard_ErrorHandler.hxx>
73
74 // Qt includes
75 #include <QFrame>
76 #include <QPushButton>
77 #include <QLabel>
78 #include <QRadioButton>
79 #include <QTableWidget>
80 #include <QHeaderView>
81 #include <QGridLayout>
82 #include <QHBoxLayout>
83 #include <QVBoxLayout>
84 #include <QButtonGroup>
85
86 // VTK includes
87 #include <vtkProperty.h>
88
89 // STL includes
90 #include <vector>
91 #include <set>
92
93 #define SPACING 6
94 #define MARGIN  11
95
96 #define COLONIZE(str)   (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" )
97
98 static void addSeparator( QWidget* parent )
99 {
100   QGridLayout* l = qobject_cast<QGridLayout*>( parent->layout() );
101   int row  = l->rowCount();
102   int cols = l->columnCount();
103   for ( int i = 0; i < cols; i++ ) {
104     QFrame* hline = new QFrame( parent );
105     hline->setFrameStyle( QFrame::HLine | QFrame::Sunken );
106     l->addWidget( hline, row, i );
107   }
108 }
109
110 enum TCol {
111   COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, COL_BAD_MESH, NB_COLUMNS
112 };
113
114 //using namespace SMESH;
115
116 namespace SMESH
117 {
118   //=============================================================================
119   /*!
120    * \brief Allocate some memory at construction and release it at destruction.
121    * Is used to be able to continue working after mesh generation or visualization
122    * break due to lack of memory
123    */
124   //=============================================================================
125
126   struct MemoryReserve
127   {
128     char* myBuf;
129     MemoryReserve(): myBuf( new char[1024*1024*1] ){} // 1M
130     void release() { delete [] myBuf; myBuf = 0; }
131     ~MemoryReserve() { release(); }
132   };
133
134   // =========================================================================================
135   /*!
136    * \brief Class showing shapes without publishing
137    */
138   // =========================================================================================
139
140   class TShapeDisplayer
141   {
142   public:
143     // -----------------------------------------------------------------------
144     TShapeDisplayer(): myViewWindow(0)
145     {
146       myProperty = vtkProperty::New();
147       myProperty->SetRepresentationToWireframe();
148       myProperty->SetColor( 250, 0, 250 );
149       myProperty->SetAmbientColor( 250, 0, 250 );
150       myProperty->SetDiffuseColor( 250, 0, 250 );
151       //myProperty->SetSpecularColor( 250, 0, 250 );
152       myProperty->SetLineWidth( 5 );
153     }
154     // -----------------------------------------------------------------------
155     ~TShapeDisplayer()
156     {
157       DeleteActors();
158       myProperty->Delete();
159     }
160     // -----------------------------------------------------------------------
161     void DeleteActors()
162     {
163       if ( hasViewWindow() ) {
164         TActorIterator actorIt = actorIterator();
165         while ( actorIt.more() )
166           if (VTKViewer_Actor* anActor = actorIt.next()) {
167             myViewWindow->RemoveActor( anActor );
168             //anActor->Delete();
169           }
170       }
171       myIndexToShape.Clear();
172       myActors.clear();
173       myShownActors.clear();
174       myBuiltSubs.clear();
175     }
176     // -----------------------------------------------------------------------
177     void SetVisibility (bool theVisibility)
178     {
179       TActorIterator actorIt = shownIterator();
180       while ( actorIt.more() )
181         if (VTKViewer_Actor* anActor = actorIt.next())
182           anActor->SetVisibility(theVisibility);
183       SMESH::RepaintCurrentView();
184     }
185     // -----------------------------------------------------------------------
186     bool HasReadyActorsFor (int subShapeID, GEOM::GEOM_Object_var aMainShape )
187     {
188       std::string mainEntry;
189       if ( !aMainShape->_is_nil() )
190         mainEntry = aMainShape->GetStudyEntry();
191       return ( myMainEntry == mainEntry &&
192                myBuiltSubs.find( subShapeID ) != myBuiltSubs.end() );
193     }
194     // -----------------------------------------------------------------------
195     void Show( int subShapeID, GEOM::GEOM_Object_var aMainShape, bool only = false)
196     {
197       SVTK_ViewWindow* aViewWindow  = SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() );
198       std::string mainEntry;
199       if ( !aMainShape->_is_nil() )
200         mainEntry = aMainShape->GetStudyEntry();
201       if ( myMainEntry != mainEntry || aViewWindow != myViewWindow ) { // remove actors
202         DeleteActors();
203         TopoDS_Shape aShape;
204         if ( !aMainShape->_is_nil() && GEOMBase::GetShape(aMainShape, aShape)) {
205           checkTriangulation( aShape );
206           TopExp::MapShapes(aShape, myIndexToShape);
207           myActors.resize( myIndexToShape.Extent(), 0 );
208           myShownActors.reserve( myIndexToShape.Extent() );
209         }
210         myMainEntry  = mainEntry;
211         myViewWindow = aViewWindow;
212       }
213       if ( only ) { // hide shown actors
214         TActorIterator actorIt = shownIterator();
215         while ( actorIt.more() )
216           if (VTKViewer_Actor* anActor = actorIt.next())
217             anActor->SetVisibility(false);
218         myShownActors.clear();
219       }
220       // find actors to show
221       TopoDS_Shape aShape = myIndexToShape( subShapeID );
222       if ( !aShape.IsNull() ) {
223         TopAbs_ShapeEnum type( aShape.ShapeType() >= TopAbs_WIRE ? TopAbs_EDGE : TopAbs_FACE );
224         for ( TopExp_Explorer exp( aShape, type ); exp.More(); exp.Next() ) {
225           //checkTriangulation( exp.Current() );
226           if ( GEOM_Actor* anActor = getActor( exp.Current() ))
227             myShownActors.push_back( anActor );
228         }
229         if ( type == TopAbs_FACE ) {
230           for ( TopExp_Explorer exp( aShape, TopAbs_EDGE ); exp.More(); exp.Next() ) {
231             const TopoDS_Edge & edge = TopoDS::Edge( exp.Current() );
232             if ( !BRep_Tool::Degenerated( edge ))
233               if ( GEOM_Actor* anActor = getActor( exp.Current() ))
234                 myShownActors.push_back( anActor );
235           }
236         }
237       }
238       myBuiltSubs.insert( subShapeID );
239       SetVisibility(true);
240     }
241     // -----------------------------------------------------------------------
242
243   private:
244
245     typedef std::vector<GEOM_Actor*> TActorVec;
246     TActorVec                  myActors;
247     TActorVec                  myShownActors;
248     TopTools_IndexedMapOfShape myIndexToShape;
249     std::string                myMainEntry;
250     SVTK_ViewWindow*           myViewWindow;
251     vtkProperty*               myProperty;
252     std::set<int>              myBuiltSubs;
253
254     // -----------------------------------------------------------------------
255     typedef SMDS_SetIterator< GEOM_Actor*, TActorVec::const_iterator> TActorIterator;
256     TActorIterator actorIterator() {
257       return TActorIterator( myActors.begin(), myActors.end() );
258     }
259     TActorIterator shownIterator() {
260       return TActorIterator( myShownActors.begin(), myShownActors.end() );
261     }
262     // -----------------------------------------------------------------------
263     GEOM_Actor* getActor(const TopoDS_Shape& shape)
264     {
265       int index = myIndexToShape.FindIndex( shape ) - 1;
266       if ( index < 0 || index >= myActors.size() )
267         return 0;
268       GEOM_Actor* & actor = myActors[ index ];
269       if ( !actor ) {
270         actor = GEOM_Actor::New();
271         if ( actor ) {
272           actor->SetShape(shape,0,0);
273           actor->SetProperty(myProperty);
274           actor->SetShadingProperty(myProperty);
275           actor->SetWireframeProperty(myProperty);
276           actor->SetPreviewProperty(myProperty);
277           actor->PickableOff();
278           //         if ( shape.ShapeType() == TopAbs_EDGE )
279           //           actor->SubShapeOn();
280           myViewWindow->AddActor( actor );
281         }
282       }
283       return actor;
284     }
285     // -----------------------------------------------------------------------
286     void checkTriangulation(const TopoDS_Shape& shape)
287     {
288       TopLoc_Location aLoc;
289       Standard_Boolean alreadymesh = Standard_True;
290       TopExp_Explorer ex(shape, TopAbs_FACE);
291       if ( ex.More() )
292         for ( ; ex.More(); ex.Next()) {
293           const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
294           Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
295           if(aPoly.IsNull()) { alreadymesh = Standard_False; break; }
296         }
297       else
298         for (ex.Init(shape, TopAbs_EDGE); ex.More(); ex.Next()) {
299           const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
300           Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D(edge, aLoc);
301           if(aPoly.IsNull()) { alreadymesh = Standard_False; break; }
302         }
303       if (alreadymesh) return;
304       // Compute default deflection
305       Bnd_Box B;
306       BRepBndLib::Add(shape, B);
307       Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
308       B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
309       double deflection = Max( aXmax-aXmin, Max ( aYmax-aYmin, aZmax-aZmin)) * 0.01 *4;
310       BRepMesh_IncrementalMesh MESH(shape,deflection);
311     }
312     // -----------------------------------------------------------------------
313     bool hasViewWindow() const
314     {
315       if ( !myViewWindow ) return false;
316
317       if ( SalomeApp_Application* anApp = SMESHGUI::GetSMESHGUI()->getApp() )
318         return FindVtkViewWindow( anApp->getViewManager(SVTK_Viewer::Type(), false ),
319                                   myViewWindow );
320       return false;
321     }
322   };
323
324   // =========================================================================================
325   /*!
326    * \brief Return text describing an error
327    */
328 #define CASE2TEXT(enum) case SMESH::enum: text = QObject::tr( #enum ); break;
329   QString errorText(int errCode, const char* comment)
330   {
331     QString text;
332     switch ( errCode ) {
333       CASE2TEXT( COMPERR_OK            );
334       CASE2TEXT( COMPERR_BAD_INPUT_MESH);
335       CASE2TEXT( COMPERR_STD_EXCEPTION );
336       CASE2TEXT( COMPERR_OCC_EXCEPTION );
337     case SMESH::COMPERR_SLM_EXCEPTION: break; // avoid double "Salome exception"
338       CASE2TEXT( COMPERR_EXCEPTION     );
339       CASE2TEXT( COMPERR_MEMORY_PB     );
340       CASE2TEXT( COMPERR_BAD_SHAPE     );
341     case SMESH::COMPERR_ALGO_FAILED:
342       if ( strlen(comment) == 0 )
343         text = QObject::tr("COMPERR_ALGO_FAILED");
344       break;
345     default:
346       text = QString("#%1").arg( -errCode );
347     }
348     if ( text.length() > 0 ) text += ". ";
349     return text + comment;
350   }
351   // -----------------------------------------------------------------------
352   /*!
353    * \brief Return SO of a subshape
354    */
355   _PTR(SObject) getSubShapeSO( int subShapeID, GEOM::GEOM_Object_var aMainShape)
356   {
357     _PTR(SObject) so = SMESH::FindSObject(aMainShape);
358     if ( subShapeID == 1 || !so )
359       return so;
360     _PTR(ChildIterator) it;
361     if (_PTR(Study) study = SMESH::GetActiveStudyDocument())
362       it =  study->NewChildIterator(so);
363     _PTR(SObject) subSO;
364     if ( it ) {
365       for ( it->InitEx(true); !subSO && it->More(); it->Next() ) {
366         GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>( it->Value() );
367         if ( !geom->_is_nil() ) {
368           GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
369           if ( list->length() == 1 && list[0] == subShapeID )
370             subSO = it->Value();
371         }
372       }
373     }
374     return subSO;
375   }
376   // -----------------------------------------------------------------------
377   /*!
378    * \brief Return subshape by ID
379    */
380   GEOM::GEOM_Object_ptr getSubShape( int subShapeID, GEOM::GEOM_Object_var aMainShape)
381   {
382     GEOM::GEOM_Object_var aSubShape;
383     if ( subShapeID == 1 )
384       aSubShape = aMainShape;
385     else if ( _PTR(SObject) so = getSubShapeSO( subShapeID, aMainShape ))
386       aSubShape = SMESH::SObjectToInterface<GEOM::GEOM_Object>( so );
387     else
388       aSubShape = SMESH::GetSubShape( aMainShape, subShapeID );
389     return aSubShape._retn();
390   }
391   // -----------------------------------------------------------------------
392   /*!
393    * \brief Return shape type name
394    */
395 #define CASE2NAME(enum) case GEOM::enum: name = QObject::tr( "GEOM_" #enum ); break;
396   QString shapeTypeName(GEOM::GEOM_Object_var aShape, const char* dflt = "" )
397   {
398     QString name = dflt;
399     if ( !aShape->_is_nil() ) {
400       switch ( aShape->GetShapeType() ) {
401       CASE2NAME( VERTEX    );
402       CASE2NAME( EDGE      );
403       CASE2NAME( WIRE      );
404       CASE2NAME( FACE      );
405       CASE2NAME( SHELL     );
406       CASE2NAME( SOLID     );
407       CASE2NAME( COMPSOLID );
408       CASE2NAME( COMPOUND  );
409       default:;
410       }
411     }
412     return name;
413   }
414   // -----------------------------------------------------------------------
415   /*!
416    * \brief Return text describing a subshape
417    */
418   QString shapeText(int subShapeID, GEOM::GEOM_Object_var aMainShape )
419   {
420     QString text;
421     if ( _PTR(SObject) aSO = getSubShapeSO( subShapeID, aMainShape ))
422       text = aSO->GetName().c_str();
423     else {
424       text = QString("#%1").arg( subShapeID );
425       QString typeName = shapeTypeName( getSubShape( subShapeID, aMainShape ));
426       if ( typeName.length() )
427         text += QString(" (%1)").arg(typeName);
428     }
429     return text;
430   }
431   // -----------------------------------------------------------------------
432   /*!
433    * \brief Return a list of selected rows
434    */
435   int getSelectedRows(QTableWidget* table, QList<int>& rows)
436   {
437     rows.clear();
438     QList<QTableWidgetSelectionRange> selRanges = table->selectedRanges();
439     QTableWidgetSelectionRange range;
440     foreach( range, selRanges )
441     {
442       for ( int row = range.topRow(); row <= range.bottomRow(); ++row )
443         rows.append( row );
444     }
445     if ( rows.isEmpty() && table->currentRow() > -1 )
446       rows.append( table->currentRow() );
447
448     return rows.count();
449   }
450
451 } // namespace SMESH
452
453
454 // =========================================================================================
455 /*!
456  * \brief Box showing mesh info
457  */
458 // =========================================================================================
459
460 SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent)
461   : QGroupBox( tr("SMESH_MESHINFO_TITLE"), theParent ), myFull( full )
462 {
463   QGridLayout* l = new QGridLayout(this);
464   l->setMargin( MARGIN );
465   l->setSpacing( SPACING );
466
467   QFont italic = font(); italic.setItalic(true);
468   QFont bold   = font(); bold.setBold(true);
469
470   QLabel* lab;
471   int row = 0;
472
473   // title
474   lab = new QLabel( this );
475   lab->setMinimumWidth(100); lab->setFont( italic );
476   l->addWidget( lab, row, 0 );
477   // --
478   lab = new QLabel(tr("SMESH_MESHINFO_ORDER0"), this );
479   lab->setMinimumWidth(100); lab->setFont( italic );
480   l->addWidget( lab, row, 1 );
481   // --
482   lab = new QLabel(tr("SMESH_MESHINFO_ORDER1"), this );
483   lab->setMinimumWidth(100); lab->setFont( italic );
484   l->addWidget( lab, row, 2 );
485   // --
486   lab = new QLabel(tr("SMESH_MESHINFO_ORDER2"), this );
487   lab->setMinimumWidth(100); lab->setFont( italic );
488   l->addWidget( lab, row, 3 );
489
490   if ( myFull )
491   {
492     // nodes
493     row = l->rowCount();         // retrieve current row count
494     // --
495     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this );
496     lab->setFont( bold );
497     l->addWidget( lab,           row, 0 );
498     // --
499     myNbNode = new QLabel( this );
500     l->addWidget( myNbNode,      row, 1 );
501
502     addSeparator(this);          // add separator
503
504     // edges
505     row = l->rowCount();         // retrieve current row count
506     // --
507     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this );
508     lab->setFont( bold );
509     l->addWidget( lab,           row, 0 );
510     // --
511     myNbEdge = new QLabel( this );
512     l->addWidget( myNbEdge,      row, 1 );
513     // --
514     myNbLinEdge = new QLabel( this );
515     l->addWidget( myNbLinEdge,   row, 2 );
516     // --
517     myNbQuadEdge = new QLabel( this );
518     l->addWidget( myNbQuadEdge,  row, 3 );
519
520     addSeparator(this);          // add separator
521
522     // faces
523     row = l->rowCount();         // retrieve current row count
524     // --
525     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this);
526     lab->setFont( bold );
527     l->addWidget( lab,           row, 0 );
528     // --
529     myNbFace     = new QLabel( this );
530     l->addWidget( myNbFace,      row, 1 );
531     // --
532     myNbLinFace  = new QLabel( this );
533     l->addWidget( myNbLinFace,   row, 2 );
534     // --
535     myNbQuadFace = new QLabel( this );
536     l->addWidget( myNbQuadFace,  row, 3 );
537     // --
538     row++;                       // increment row count
539     // ... triangles
540     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TRIANGLES")), this );
541     l->addWidget( lab,           row, 0 );
542     // --
543     myNbTrai     = new QLabel( this );
544     l->addWidget( myNbTrai,      row, 1 );
545     // --
546     myNbLinTrai  = new QLabel( this );
547     l->addWidget( myNbLinTrai,   row, 2 );
548     // --
549     myNbQuadTrai = new QLabel( this );
550     l->addWidget( myNbQuadTrai,  row, 3 );
551     // --
552     row++;                       // increment row count
553     // ... quadrangles
554     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_QUADRANGLES")), this );
555     l->addWidget( lab,           row, 0 );
556     // --
557     myNbQuad     = new QLabel( this );
558     l->addWidget( myNbQuad,      row, 1 );
559     // --
560     myNbLinQuad  = new QLabel( this );
561     l->addWidget( myNbLinQuad,   row, 2 );
562     // --
563     myNbQuadQuad = new QLabel( this );
564     l->addWidget( myNbQuadQuad,  row, 3 );
565     // --
566     row++;                       // increment row count
567     // ... poligones
568     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYGONES")), this );
569     l->addWidget( lab,           row, 0 );
570     myNbPolyg    = new QLabel( this );
571     l->addWidget( myNbPolyg,     row, 1 );
572
573     addSeparator(this);          // add separator
574
575     // volumes
576     row = l->rowCount();         // retrieve current row count
577     // --
578     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this);
579     lab->setFont( bold );
580     l->addWidget( lab,           row, 0 );
581     // --
582     myNbVolum     = new QLabel( this );
583     l->addWidget( myNbVolum,     row, 1 );
584     // --
585     myNbLinVolum  = new QLabel( this );
586     l->addWidget( myNbLinVolum,  row, 2 );
587     // --
588     myNbQuadVolum = new QLabel( this );
589     l->addWidget( myNbQuadVolum, row, 3 );
590     // --
591     row++;                       // increment row count
592     // ... tetras
593     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TETRAS")), this );
594     l->addWidget( lab,           row, 0 );
595     // --
596     myNbTetra     = new QLabel( this );
597     l->addWidget( myNbTetra,     row, 1 );
598     // --
599     myNbLinTetra  = new QLabel( this );
600     l->addWidget( myNbLinTetra,  row, 2 );
601     // --
602     myNbQuadTetra = new QLabel( this );
603     l->addWidget( myNbQuadTetra, row, 3 );
604     // --
605     row++;                       // increment row count
606     // ... hexas
607     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAS")), this );
608     l->addWidget( lab,           row, 0 );
609     // --
610     myNbHexa      = new QLabel( this );
611     l->addWidget( myNbHexa,      row, 1 );
612     // --
613     myNbLinHexa   = new QLabel( this );
614     l->addWidget( myNbLinHexa,   row, 2 );
615     // --
616     myNbQuadHexa  = new QLabel( this );
617     l->addWidget( myNbQuadHexa,  row, 3 );
618     // --
619     row++;                       // increment row count
620     // ... pyras
621     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PYRAS")), this );
622     l->addWidget( lab,           row, 0 );
623     // --
624     myNbPyra      = new QLabel( this );
625     l->addWidget( myNbPyra,      row, 1 );
626     // --
627     myNbLinPyra   = new QLabel( this );
628     l->addWidget( myNbLinPyra,   row, 2 );
629     // --
630     myNbQuadPyra  = new QLabel( this );
631     l->addWidget( myNbQuadPyra,  row, 3 );
632     // --
633     row++;                       // increment row count
634     // ... prisms
635     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PRISMS")), this );
636     l->addWidget( lab,           row, 0 );
637     // --
638     myNbPrism     = new QLabel( this );
639     l->addWidget( myNbPrism,     row, 1 );
640     // --
641     myNbLinPrism  = new QLabel( this );
642     l->addWidget( myNbLinPrism,  row, 2 );
643     // --
644     myNbQuadPrism = new QLabel( this );
645     l->addWidget( myNbQuadPrism, row, 3 );
646     // --
647     row++;                       // increment row count
648     // ... polyedres
649     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYEDRES")), this );
650     l->addWidget( lab,           row, 0 );
651     // --
652     myNbPolyh     = new QLabel( this );
653     l->addWidget( myNbPolyh,     row, 1 );
654   }
655   else
656   {
657     // nodes
658     row = l->rowCount();         // retrieve current row count
659     // --
660     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this );
661     l->addWidget( lab,           row, 0 );
662     // --
663     myNbNode      = new QLabel( this );
664     l->addWidget( myNbNode,      row, 1 );
665
666     // edges
667     row = l->rowCount();         // retrieve current row count
668     // --
669     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this );
670     l->addWidget( lab,           row, 0 );
671     // --
672     myNbEdge      = new QLabel( this );
673     l->addWidget( myNbEdge,      row, 1 );
674     // --
675     myNbLinEdge   = new QLabel( this );
676     l->addWidget( myNbLinEdge,   row, 2 );
677     // --
678     myNbQuadEdge  = new QLabel( this );
679     l->addWidget( myNbQuadEdge,  row, 3 );
680
681     // faces
682     row = l->rowCount();         // retrieve current row count
683     // --
684     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this);
685     l->addWidget( lab,           row, 0 );
686     // --
687     myNbFace      = new QLabel( this );
688     l->addWidget( myNbFace,      row, 1 );
689     // --
690     myNbLinFace   = new QLabel( this );
691     l->addWidget( myNbLinFace,   row, 2 );
692     // --
693     myNbQuadFace  = new QLabel( this );
694     l->addWidget( myNbQuadFace,  row, 3 );
695
696     // volumes
697     row = l->rowCount();         // retrieve current row count
698     // --
699     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this);
700     l->addWidget( lab,           row, 0 );
701     // --
702     myNbVolum     = new QLabel( this );
703     l->addWidget( myNbVolum,     row, 1 );
704     // --
705     myNbLinVolum  = new QLabel( this );
706     l->addWidget( myNbLinVolum,  row, 2 );
707     // --
708     myNbQuadVolum = new QLabel( this );
709     l->addWidget( myNbQuadVolum, row, 3 );
710   }
711 }
712
713 // =========================================================================================
714 /*!
715  * \brief Set mesh info
716  */
717 // =========================================================================================
718
719 void SMESHGUI_MeshInfosBox::SetInfoByMesh(SMESH::SMESH_Mesh_var mesh)
720 {
721   const SMESH::ElementOrder lin = SMESH::ORDER_LINEAR;
722   int nbTot, nbLin;
723
724   // nodes
725   myNbNode     ->setText( QString("%1").arg( mesh->NbNodes() ));
726
727   // edges
728   nbTot = mesh->NbEdges(), nbLin = mesh->NbEdgesOfOrder(lin);
729   myNbEdge     ->setText( QString("%1").arg( nbTot ));
730   myNbLinEdge  ->setText( QString("%1").arg( nbLin ));
731   myNbQuadEdge ->setText( QString("%1").arg( nbTot - nbLin ));
732
733   // faces
734   nbTot = mesh->NbFaces(), nbLin = mesh->NbFacesOfOrder(lin);
735   myNbFace     ->setText( QString("%1").arg( nbTot ));
736   myNbLinFace  ->setText( QString("%1").arg( nbLin ));
737   myNbQuadFace ->setText( QString("%1").arg( nbTot - nbLin ));
738
739   // volumes
740   nbTot = mesh->NbVolumes(), nbLin = mesh->NbVolumesOfOrder(lin);
741   myNbVolum    ->setText( QString("%1").arg( nbTot ));
742   myNbLinVolum ->setText( QString("%1").arg( nbLin ));
743   myNbQuadVolum->setText( QString("%1").arg( nbTot - nbLin ));
744
745   if ( myFull )
746   {
747     // triangles
748     nbTot = mesh->NbTriangles(), nbLin = mesh->NbTrianglesOfOrder(lin);
749     myNbTrai     ->setText( QString("%1").arg( nbTot ));
750     myNbLinTrai  ->setText( QString("%1").arg( nbLin ));
751     myNbQuadTrai ->setText( QString("%1").arg( nbTot - nbLin ));
752     // quadrangles
753     nbTot = mesh->NbQuadrangles(), nbLin = mesh->NbQuadranglesOfOrder(lin);
754     myNbQuad     ->setText( QString("%1").arg( nbTot ));
755     myNbLinQuad  ->setText( QString("%1").arg( nbLin ));
756     myNbQuadQuad ->setText( QString("%1").arg( nbTot - nbLin ));
757     // poligones
758     myNbPolyg    ->setText( QString("%1").arg( mesh->NbPolygons() ));
759
760     // tetras
761     nbTot = mesh->NbTetras(), nbLin = mesh->NbTetrasOfOrder(lin);
762     myNbTetra    ->setText( QString("%1").arg( nbTot ));
763     myNbLinTetra ->setText( QString("%1").arg( nbLin ));
764     myNbQuadTetra->setText( QString("%1").arg( nbTot - nbLin ));
765     // hexas
766     nbTot = mesh->NbHexas(), nbLin = mesh->NbHexasOfOrder(lin);
767     myNbHexa     ->setText( QString("%1").arg( nbTot ));
768     myNbLinHexa  ->setText( QString("%1").arg( nbLin ));
769     myNbQuadHexa ->setText( QString("%1").arg( nbTot - nbLin ));
770     // pyras
771     nbTot = mesh->NbPyramids(), nbLin = mesh->NbPyramidsOfOrder(lin);
772     myNbPyra     ->setText( QString("%1").arg( nbTot ));
773     myNbLinPyra  ->setText( QString("%1").arg( nbLin ));
774     myNbQuadPyra ->setText( QString("%1").arg( nbTot - nbLin ));
775     // prisms
776     nbTot = mesh->NbPrisms(), nbLin = mesh->NbPrismsOfOrder(lin);
777     myNbPrism    ->setText( QString("%1").arg( nbTot ));
778     myNbLinPrism ->setText( QString("%1").arg( nbLin ));
779     myNbQuadPrism->setText( QString("%1").arg( nbTot - nbLin ));
780     // polyedres
781     myNbPolyh    ->setText( QString("%1").arg( mesh->NbPolyhedrons() ));
782   }
783 }
784
785 // =========================================================================================
786 /*!
787  * \brief Dialog to compute a mesh and show computation errors
788  */
789 //=======================================================================
790
791 SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent )
792  : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ )
793 {
794   QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
795   aDlgLay->setMargin( 0 );
796   aDlgLay->setSpacing( SPACING );
797
798   QFrame* aMainFrame = createMainFrame  (mainFrame());
799
800   aDlgLay->addWidget(aMainFrame);
801
802   aDlgLay->setStretchFactor(aMainFrame, 1);
803 }
804
805 // =========================================================================================
806 /*!
807  * \brief Destructor
808  */
809 //=======================================================================
810
811 SMESHGUI_ComputeDlg::~SMESHGUI_ComputeDlg()
812 {
813 }
814
815 //=======================================================================
816 // function : createMainFrame()
817 // purpose  : Create frame containing dialog's fields
818 //=======================================================================
819
820 QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
821 {
822   QFrame* aFrame = new QFrame(theParent);
823
824   SUIT_ResourceMgr* rm = resourceMgr();
825   QPixmap iconCompute (rm->loadPixmap("SMESH", tr("ICON_COMPUTE")));
826
827   // constructor
828
829   QGroupBox* aPixGrp = new QGroupBox(tr("CONSTRUCTOR"), aFrame);
830   QButtonGroup* aBtnGrp = new QButtonGroup(this);
831   QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp);
832   aPixGrpLayout->setMargin(MARGIN); aPixGrpLayout->setSpacing(SPACING);
833
834   QRadioButton* aRBut = new QRadioButton(aPixGrp);
835   aRBut->setIcon(iconCompute);
836   aRBut->setChecked(true);
837   aPixGrpLayout->addWidget(aRBut);
838   aBtnGrp->addButton(aRBut, 0);
839
840   // Mesh name
841
842   QGroupBox* nameBox = new QGroupBox(tr("SMESH_MESHINFO_NAME"), aFrame );
843   QHBoxLayout* nameBoxLayout = new QHBoxLayout(nameBox);
844   nameBoxLayout->setMargin(MARGIN); nameBoxLayout->setSpacing(SPACING);
845   myMeshName = new QLabel(nameBox);
846   nameBoxLayout->addWidget(myMeshName);
847
848   // Mesh Info
849
850   myBriefInfo = new SMESHGUI_MeshInfosBox(false, aFrame);
851   myFullInfo  = new SMESHGUI_MeshInfosBox(true,  aFrame);
852
853   // Computation errors
854
855   myCompErrorGroup = new QGroupBox(tr("ERRORS"), aFrame);
856   myTable      = new QTableWidget( 1, NB_COLUMNS, myCompErrorGroup);
857   myShowBtn    = new QPushButton(tr("SHOW_SHAPE"), myCompErrorGroup);
858   myPublishBtn = new QPushButton(tr("PUBLISH_SHAPE"), myCompErrorGroup);
859   myBadMeshBtn = new QPushButton(tr("SHOW_BAD_MESH"), myCompErrorGroup);
860
861   //myTable->setReadOnly( true ); // VSR: check
862   myTable->setEditTriggers( QAbstractItemView::NoEditTriggers );
863   myTable->hideColumn( COL_PUBLISHED );
864   myTable->hideColumn( COL_SHAPEID );
865   myTable->hideColumn( COL_BAD_MESH );
866   myTable->horizontalHeader()->setResizeMode( COL_ERROR, QHeaderView::Interactive );
867
868   QStringList headers;
869   headers << tr( "COL_ALGO_HEADER" );
870   headers << tr( "COL_SHAPE_HEADER" );
871   headers << tr( "COL_ERROR_HEADER" );
872   headers << tr( "COL_SHAPEID_HEADER" );
873   headers << tr( "COL_PUBLISHED_HEADER" );
874
875   myTable->setHorizontalHeaderLabels( headers );
876
877   // layouting
878   QGridLayout* grpLayout = new QGridLayout(myCompErrorGroup);
879   grpLayout->setSpacing(SPACING);
880   grpLayout->setMargin(MARGIN);
881   grpLayout->addWidget( myTable,      0, 0, 4, 1 );
882   grpLayout->addWidget( myShowBtn,    0, 1 );
883   grpLayout->addWidget( myPublishBtn, 1, 1 );
884   grpLayout->addWidget( myBadMeshBtn, 2, 1 );
885   grpLayout->setRowStretch( 3, 1 );
886
887   // Hypothesis definition errors
888
889   myHypErrorGroup = new QGroupBox(tr("SMESH_WRN_MISSING_PARAMETERS"), aFrame);
890   QHBoxLayout* myHypErrorGroupLayout = new QHBoxLayout(myHypErrorGroup);
891   myHypErrorGroupLayout->setMargin(MARGIN);
892   myHypErrorGroupLayout->setSpacing(SPACING);
893   myHypErrorLabel = new QLabel(myHypErrorGroup);
894   myHypErrorGroupLayout->addWidget(myHypErrorLabel);
895
896   // Memory Lack Label
897
898   myMemoryLackGroup = new QGroupBox(tr("ERRORS"), aFrame);
899   QVBoxLayout* myMemoryLackGroupLayout = new QVBoxLayout(myMemoryLackGroup);
900   myMemoryLackGroupLayout->setMargin(MARGIN);
901   myMemoryLackGroupLayout->setSpacing(SPACING);
902   QLabel* memLackLabel = new QLabel(tr("MEMORY_LACK"), myMemoryLackGroup);
903   QFont bold = memLackLabel->font(); bold.setBold(true);
904   memLackLabel->setFont( bold );
905   memLackLabel->setMinimumWidth(300);
906   myMemoryLackGroupLayout->addWidget(memLackLabel);
907
908   // add all widgets to aFrame
909   QVBoxLayout* aLay = new QVBoxLayout(aFrame);
910   aLay->setMargin( 0 );
911   aLay->setSpacing( 0 );
912   aLay->addWidget( aPixGrp );
913   aLay->addWidget( nameBox );
914   aLay->addWidget( myBriefInfo );
915   aLay->addWidget( myFullInfo );
916   aLay->addWidget( myHypErrorGroup );
917   aLay->addWidget( myCompErrorGroup );
918   aLay->addWidget( myMemoryLackGroup );
919   aLay->setStretchFactor( myCompErrorGroup, 1 );
920
921   ((QPushButton*) button( OK ))->setDefault( true );
922
923   return aFrame;
924 }
925
926 //================================================================================
927 /*!
928  * \brief Constructor
929 */
930 //================================================================================
931
932 SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp()
933   : SMESHGUI_Operation(),
934     myCompDlg( 0 )
935 {
936   myTShapeDisplayer = new SMESH::TShapeDisplayer();
937   myBadMeshDisplayer = 0;
938
939   //myHelpFileName = "/files/about_meshes.htm"; // V3
940   myHelpFileName = "about_meshes_page.html"; // V4
941 }
942
943 //================================================================================
944 /*!
945  * \brief Start operation
946  * \purpose Init dialog fields, connect signals and slots, show dialog
947  */
948 //================================================================================
949
950 void SMESHGUI_BaseComputeOp::startOperation()
951 {
952   if ( !myCompDlg )
953   {
954     myCompDlg = new SMESHGUI_ComputeDlg( desktop() );
955     // connect signals and slots
956     connect(myCompDlg->myShowBtn,    SIGNAL (clicked()), SLOT(onPreviewShape()));
957     connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
958     connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh()));
959
960     QTableWidget* aTable = table();
961     connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged()));
962     connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged()));
963   }
964
965   myMesh      = SMESH::SMESH_Mesh::_nil();
966   myMainShape = GEOM::GEOM_Object::_nil();
967
968   // check selection
969   LightApp_SelectionMgr *Sel = selectionMgr();
970   SALOME_ListIO selected; Sel->selectedObjects( selected );
971
972   int nbSel = selected.Extent();
973   if (nbSel != 1) {
974     SUIT_MessageBox::warning(desktop(),
975                              tr("SMESH_WRN_WARNING"),
976                              tr("SMESH_WRN_NO_AVAILABLE_DATA"));
977     onCancel();
978     return;
979   }
980
981   myIObject = selected.First();
982   myMesh = SMESH::GetMeshByIO(myIObject);
983   if (myMesh->_is_nil()) {
984     SUIT_MessageBox::warning(desktop(),
985                              tr("SMESH_WRN_WARNING"),
986                              tr("SMESH_WRN_NO_AVAILABLE_DATA"));
987     onCancel();
988
989   }
990   myMainShape = myMesh->GetShapeToMesh();
991
992   SMESHGUI_Operation::startOperation();
993 }
994
995 //================================================================================
996 /*!
997  * \brief computeMesh()
998 */
999 //================================================================================
1000
1001 void SMESHGUI_BaseComputeOp::computeMesh()
1002 {
1003   // COMPUTE MESH
1004
1005   SMESH::MemoryReserve aMemoryReserve;
1006
1007   SMESH::compute_error_array_var aCompErrors;
1008   QString                        aHypErrors;
1009
1010   bool computeFailed = true, memoryLack = false;
1011
1012   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
1013   bool hasShape = myMesh->HasShapeToMesh();
1014   bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
1015   if ( shapeOK && aMeshSObj )
1016   {
1017     myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
1018     SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
1019     SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
1020     if ( errors->length() > 0 ) {
1021       aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
1022     }
1023     SUIT_OverrideCursor aWaitCursor;
1024     try {
1025 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1026       OCC_CATCH_SIGNALS;
1027 #endif
1028       if (gen->Compute(myMesh, myMainShape))
1029         computeFailed = false;
1030     }
1031     catch(const SALOME::SALOME_Exception & S_ex){
1032       memoryLack = true;
1033     }
1034     try {
1035 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1036       OCC_CATCH_SIGNALS;
1037 #endif
1038       aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
1039       // check if there are memory problems
1040       for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
1041         memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB );
1042     }
1043     catch(const SALOME::SALOME_Exception & S_ex){
1044       memoryLack = true;
1045     }
1046
1047     // NPAL16631: if ( !memoryLack )
1048     {
1049       SMESH::ModifiedMesh(aMeshSObj, !computeFailed, myMesh->NbNodes() == 0);
1050       update( UF_ObjBrowser | UF_Model );
1051
1052       // SHOW MESH
1053       // NPAL16631: if ( getSMESHGUI()->automaticUpdate() )
1054       if ( !memoryLack && getSMESHGUI()->automaticUpdate() )
1055       {
1056         try {
1057 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1058           OCC_CATCH_SIGNALS;
1059 #endif
1060           SMESH::Update(myIObject, true);
1061         }
1062         catch (...) {
1063 #ifdef _DEBUG_
1064           MESSAGE ( "Exception thrown during mesh visualization" );
1065 #endif
1066           if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
1067             SMESH::OnVisuException();
1068           }
1069           else {
1070             memoryLack = true;
1071           }
1072         }
1073       }
1074       LightApp_SelectionMgr *Sel = selectionMgr();
1075       if ( Sel )
1076       {
1077         SALOME_ListIO selected;
1078         selected.Append( myIObject );
1079         Sel->setSelectedObjects( selected );
1080       }
1081     }
1082   }
1083
1084   if ( memoryLack )
1085     aMemoryReserve.release();
1086
1087   myCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
1088
1089   // SHOW ERRORS
1090   
1091   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
1092   bool noHypoError = ( aHypErrors.isEmpty() );
1093
1094   SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
1095   int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
1096
1097   bool isShowResultDlg = true;
1098   switch( aNotifyMode ) {
1099   case 0: // show the mesh computation result dialog NEVER
1100     isShowResultDlg = false;
1101     commit();
1102     break;
1103   case 1: // show the mesh computation result dialog if there are some errors
1104     if ( memoryLack || !noCompError || !noHypoError )
1105       isShowResultDlg = true;
1106     else
1107     {
1108       isShowResultDlg = false;
1109       commit();
1110     }
1111     break;
1112   default: // show the result dialog after each mesh computation
1113     isShowResultDlg = true;
1114   }
1115
1116   // SHOW RESULTS
1117   if ( isShowResultDlg )
1118     showComputeResult( memoryLack, noCompError,aCompErrors, noHypoError, aHypErrors );
1119 }
1120
1121 void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
1122                                                 const bool theNoCompError,
1123                                                 SMESH::compute_error_array_var& theCompErrors,
1124                                                 const bool     theNoHypoError,
1125                                                 const QString& theHypErrors )
1126 {
1127   bool hasShape = myMesh->HasShapeToMesh();
1128   SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
1129   aCompDlg->myMemoryLackGroup->hide();
1130
1131   if ( theMemoryLack )
1132   {
1133     aCompDlg->myMemoryLackGroup->show();
1134     aCompDlg->myFullInfo->hide();
1135     aCompDlg->myBriefInfo->hide();
1136     aCompDlg->myHypErrorGroup->hide();
1137     aCompDlg->myCompErrorGroup->hide();
1138   }
1139   else if ( theNoCompError && theNoHypoError )
1140   {
1141     aCompDlg->myFullInfo->SetInfoByMesh( myMesh );
1142     aCompDlg->myFullInfo->show();
1143     aCompDlg->myBriefInfo->hide();
1144     aCompDlg->myHypErrorGroup->hide();
1145     aCompDlg->myCompErrorGroup->hide();
1146   }
1147   else
1148   {
1149     QTableWidget* tbl = aCompDlg->myTable;
1150     aCompDlg->myBriefInfo->SetInfoByMesh( myMesh );
1151     aCompDlg->myBriefInfo->show();
1152     aCompDlg->myFullInfo->hide();
1153
1154     if ( theNoHypoError ) {
1155       aCompDlg->myHypErrorGroup->hide();
1156     }
1157     else {
1158       aCompDlg->myHypErrorGroup->show();
1159       aCompDlg->myHypErrorLabel->setText( theHypErrors );
1160     }
1161
1162     if ( theNoCompError ) {
1163       aCompDlg->myCompErrorGroup->hide();
1164     }
1165     else {
1166       aCompDlg->myCompErrorGroup->show();
1167
1168       if ( !hasShape ) {
1169         aCompDlg->myPublishBtn->hide();
1170         aCompDlg->myShowBtn->hide();
1171       }
1172       else {
1173         aCompDlg->myPublishBtn->show();
1174         aCompDlg->myShowBtn->show();
1175       }
1176
1177       // fill table of errors
1178       tbl->setRowCount( theCompErrors->length() );
1179       if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
1180       else             tbl->showColumn( COL_SHAPE );
1181       tbl->setColumnWidth( COL_ERROR, 200 );
1182
1183       bool hasBadMesh = false;
1184       for ( int row = 0; row < theCompErrors->length(); ++row )
1185       {
1186         SMESH::ComputeError & err = theCompErrors[ row ];
1187
1188         QString text = err.algoName.in();
1189         if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
1190         else tbl->item( row, COL_ALGO )->setText( text );
1191
1192         text = SMESH::errorText( err.code, err.comment.in() );
1193         if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
1194         else tbl->item( row, COL_ERROR )->setText( text );
1195
1196         text = QString("%1").arg( err.subShapeID );
1197         if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
1198         else tbl->item( row, COL_SHAPEID )->setText( text );
1199
1200         text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
1201         if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
1202         else tbl->item( row, COL_SHAPE )->setText( text );
1203
1204         text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
1205         if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
1206         else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
1207
1208         text = err.hasBadMesh ? "hasBadMesh" : "";
1209         if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
1210         else tbl->item( row, COL_BAD_MESH )->setText( text );
1211         if ( err.hasBadMesh ) hasBadMesh = true;
1212
1213         //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
1214         tbl->resizeRowToContents( row );
1215       }
1216       tbl->resizeColumnToContents( COL_ALGO );
1217       tbl->resizeColumnToContents( COL_SHAPE );
1218
1219       if ( hasBadMesh )
1220         aCompDlg->myBadMeshBtn->show();
1221       else
1222         aCompDlg->myBadMeshBtn->hide();
1223
1224       tbl->setCurrentCell(0,0);
1225       currentCellChanged(); // to update buttons
1226     }
1227   }
1228   aCompDlg->show();
1229 }
1230
1231 //================================================================================
1232 /*!
1233  * \brief Stops operation
1234  */
1235 //================================================================================
1236
1237 void SMESHGUI_BaseComputeOp::stopOperation()
1238 {
1239   SMESHGUI_Operation::stopOperation();
1240   if ( myTShapeDisplayer )
1241     myTShapeDisplayer->SetVisibility( false );
1242   if ( myBadMeshDisplayer ) {
1243     myBadMeshDisplayer->SetVisibility( false );
1244     // delete it in order not to have problems at its destruction when the viewer
1245     // where it worked is dead due to e.g. study closing
1246     delete myBadMeshDisplayer;
1247     myBadMeshDisplayer = 0;
1248   }
1249   myIObject.Nullify();
1250 }
1251
1252 //================================================================================
1253 /*!
1254  * \brief publish selected subshape
1255  */
1256 //================================================================================
1257
1258 void SMESHGUI_BaseComputeOp::onPublishShape()
1259 {
1260   GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
1261   SALOMEDS::Study_var study = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
1262
1263   QList<int> rows;
1264   SMESH::getSelectedRows( table(), rows );
1265   int row;
1266   foreach ( row, rows )
1267   {
1268     int curSub = table()->item(row, COL_SHAPEID)->text().toInt();
1269     GEOM::GEOM_Object_var shape = SMESH::getSubShape( curSub, myMainShape );
1270     if ( !shape->_is_nil() && ! SMESH::getSubShapeSO( curSub, myMainShape ))
1271     {
1272       if ( !SMESH::getSubShapeSO( 1, myMainShape )) // the main shape not published
1273       {
1274         QString name = GEOMBase::GetDefaultName( SMESH::shapeTypeName( myMainShape, "MAIN_SHAPE" ));
1275         SALOMEDS::SObject_var so =
1276           geomGen->AddInStudy( study, myMainShape, name.toLatin1().data(), GEOM::GEOM_Object::_nil());
1277         // look for myMainShape in the table
1278         for ( int r = 0, nr = table()->rowCount(); r < nr; ++r ) {
1279           if ( table()->item( r, COL_SHAPEID )->text() == "1" ) {
1280             if ( so->_is_nil() ) {
1281               table()->item( r, COL_SHAPE )->setText( so->GetName() );
1282               table()->item( r, COL_PUBLISHED )->setText( so->GetID() );
1283             }
1284             break;
1285           }
1286         }
1287         if ( curSub == 1 ) continue;
1288       }
1289       QString name = GEOMBase::GetDefaultName( SMESH::shapeTypeName( shape, "ERROR_SHAPE" ));
1290       SALOMEDS::SObject_var so = geomGen->AddInStudy( study, shape, name.toLatin1().data(), myMainShape);
1291       if ( !so->_is_nil() ) {
1292         table()->item( row, COL_SHAPE )->setText( so->GetName() );
1293         table()->item( row, COL_PUBLISHED )->setText( so->GetID() );
1294       }
1295     }
1296   }
1297   getSMESHGUI()->getApp()->updateObjectBrowser();
1298   currentCellChanged(); // to update buttons
1299 }
1300
1301 //================================================================================
1302 /*!
1303  * \brief show mesh elements preventing computation of a submesh of current row
1304  */
1305 //================================================================================
1306
1307 void SMESHGUI_BaseComputeOp::onShowBadMesh()
1308 {
1309   myTShapeDisplayer->SetVisibility( false );
1310   QList<int> rows;
1311   if ( SMESH::getSelectedRows( table(), rows ) == 1 ) {
1312     bool hasBadMesh = ( !table()->item(rows.front(), COL_BAD_MESH)->text().isEmpty() );
1313     if ( hasBadMesh ) {
1314       int curSub = table()->item(rows.front(), COL_SHAPEID)->text().toInt();
1315       SMESHGUI* gui = getSMESHGUI();
1316       SMESH::SMESH_Gen_var gen = gui->GetSMESHGen();
1317       SVTK_ViewWindow*    view = SMESH::GetViewWindow( gui );
1318       if ( myBadMeshDisplayer ) delete myBadMeshDisplayer;
1319       myBadMeshDisplayer = new SMESHGUI_MeshEditPreview( view );
1320       SMESH::MeshPreviewStruct_var aMeshData = gen->GetBadInputElements(myMesh,curSub);
1321       vtkFloatingPointType aPointSize = SMESH::GetFloat("SMESH:node_size",3);
1322       vtkFloatingPointType aLineWidth = SMESH::GetFloat("SMESH:element_width",1);
1323       // delete property !!!!!!!!!!
1324       vtkProperty* prop = vtkProperty::New();
1325       prop->SetLineWidth( aLineWidth * 3 );
1326       prop->SetPointSize( aPointSize * 3 );
1327       prop->SetColor( 250, 0, 250 );
1328       myBadMeshDisplayer->GetActor()->SetProperty( prop );
1329       myBadMeshDisplayer->SetData( aMeshData._retn() );
1330     }
1331   }
1332 }
1333
1334 //================================================================================
1335 /*!
1336  * \brief SLOT called when a selected cell in table() changed
1337  */
1338 //================================================================================
1339
1340 void SMESHGUI_BaseComputeOp::currentCellChanged()
1341 {
1342   myTShapeDisplayer->SetVisibility( false );
1343   if ( myBadMeshDisplayer )
1344     myBadMeshDisplayer->SetVisibility( false );
1345
1346   bool publishEnable = 0, showEnable = 0, showOnly = 1, hasBadMesh = 0;
1347   QList<int> rows;
1348   int nbSelected = SMESH::getSelectedRows( table(), rows );
1349   int row;
1350   foreach ( row, rows )
1351   {
1352     bool hasData     = ( !table()->item( row, COL_SHAPE )->text().isEmpty() );
1353     bool isPublished = ( !table()->item( row, COL_PUBLISHED )->text().isEmpty() );
1354     if ( hasData && !isPublished )
1355       publishEnable = true;
1356
1357     int curSub = table()->item( row, COL_SHAPEID )->text().toInt();
1358     bool prsReady = myTShapeDisplayer->HasReadyActorsFor( curSub, myMainShape );
1359     if ( prsReady ) {
1360       myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
1361       showOnly = false;
1362     }
1363     else {
1364       showEnable = true;
1365     }
1366
1367     if ( !table()->item(row, COL_BAD_MESH)->text().isEmpty() )
1368       hasBadMesh = true;
1369   }
1370   myCompDlg->myPublishBtn->setEnabled( publishEnable );
1371   myCompDlg->myShowBtn   ->setEnabled( showEnable );
1372   myCompDlg->myBadMeshBtn->setEnabled( hasBadMesh && ( nbSelected == 1 ));
1373 }
1374
1375 //================================================================================
1376 /*!
1377  * \brief update preview
1378  */
1379 //================================================================================
1380
1381 void SMESHGUI_BaseComputeOp::onPreviewShape()
1382 {
1383   if ( myTShapeDisplayer )
1384   {
1385     SUIT_OverrideCursor aWaitCursor;
1386     QList<int> rows;
1387     SMESH::getSelectedRows( table(), rows );
1388
1389     bool showOnly = true;
1390     int row;
1391     foreach ( row, rows )
1392     {
1393       int curSub = table()->item( row, COL_SHAPEID )->text().toInt();
1394       if ( curSub > 0 ) {
1395         myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
1396         showOnly = false;
1397       }
1398     }
1399     currentCellChanged(); // to update buttons
1400   }
1401 }
1402
1403 //================================================================================
1404 /*!
1405  * \brief Destructor
1406  */
1407 //================================================================================
1408
1409 SMESHGUI_BaseComputeOp::~SMESHGUI_BaseComputeOp()
1410 {
1411   delete myCompDlg;
1412   myCompDlg = 0;
1413   delete myTShapeDisplayer;
1414   if ( myBadMeshDisplayer )
1415     delete myBadMeshDisplayer;
1416 }
1417
1418 //================================================================================
1419 /*!
1420  * \brief Gets dialog of compute operation
1421  * \retval SMESHGUI_ComputeDlg* - pointer to dialog of this operation
1422  */
1423 //================================================================================
1424
1425 SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::computeDlg() const
1426 {
1427   return myCompDlg;
1428 }
1429
1430 //================================================================================
1431 /*!
1432  * \brief Return a table
1433  */
1434 //================================================================================
1435
1436 QTableWidget* SMESHGUI_BaseComputeOp::table()
1437 {
1438   return myCompDlg->myTable;
1439 }
1440
1441
1442 //================================================================================
1443 /*!
1444  * \brief Constructor
1445 */
1446 //================================================================================
1447
1448 SMESHGUI_ComputeOp::SMESHGUI_ComputeOp()
1449  : SMESHGUI_BaseComputeOp()
1450 {
1451 }
1452
1453
1454 //================================================================================
1455 /*!
1456  * \brief Desctructor
1457 */
1458 //================================================================================
1459
1460 SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp()
1461 {
1462 }
1463
1464 //================================================================================
1465 /*!
1466  * \brief perform it's intention action: compute mesh
1467  */
1468 //================================================================================
1469
1470 void SMESHGUI_ComputeOp::startOperation()
1471 {
1472   SMESHGUI_BaseComputeOp::startOperation();
1473   computeMesh();
1474 }
1475
1476 //================================================================================
1477 /*!
1478  * \brief perform it's intention action: compute mesh
1479  */
1480 //================================================================================
1481
1482 bool SMESHGUI_ComputeOp::onApply()
1483 {
1484   return true;
1485 }
1486
1487 //================================================================================
1488 /*!
1489  * \brief Gets dialog of this operation
1490  * \retval LightApp_Dialog* - pointer to dialog of this operation
1491  */
1492 //================================================================================
1493
1494 LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
1495 {
1496   return computeDlg();
1497 }
1498
1499 //================================================================================
1500 /*!
1501  * \brief Constructor
1502 */
1503 //================================================================================
1504
1505 SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp()
1506  : SMESHGUI_BaseComputeOp(),
1507  myDlg( 0 ),
1508  myActiveDlg( 0 ),
1509  myPreviewDisplayer( 0 )
1510 {
1511   myHelpFileName = "preview_meshes_page.html"; // V4
1512 }
1513
1514 //================================================================================
1515 /*!
1516  * \brief Destructor
1517  */
1518 //================================================================================
1519
1520 SMESHGUI_PrecomputeOp::~SMESHGUI_PrecomputeOp()
1521 {
1522   delete myDlg;
1523   myDlg = 0;
1524   myActiveDlg = 0;
1525   if ( myPreviewDisplayer )
1526     delete myPreviewDisplayer;
1527   myPreviewDisplayer = 0;
1528 }
1529
1530 //================================================================================
1531 /*!
1532  * \brief Gets current dialog of this operation
1533  * \retval LightApp_Dialog* - pointer to dialog of this operation
1534  */
1535 //================================================================================
1536
1537 LightApp_Dialog* SMESHGUI_PrecomputeOp::dlg() const
1538 {
1539   return myActiveDlg;
1540 }
1541
1542 //================================================================================
1543 /*!
1544  * \brief perform it's intention action: prepare data
1545  */
1546 //================================================================================
1547
1548 void SMESHGUI_PrecomputeOp::startOperation()
1549 {
1550   if ( !myDlg )
1551   {
1552     myDlg = new SMESHGUI_PrecomputeDlg( desktop() );
1553     
1554     // connect signals
1555     connect( myDlg, SIGNAL( preview() ), this, SLOT( onPreview() ) );
1556   }
1557   myActiveDlg = myDlg;
1558
1559   // connect signal to compute dialog. which will be shown after Compute mesh operation
1560   SMESHGUI_ComputeDlg* cmpDlg = computeDlg();
1561   if ( cmpDlg )
1562   {
1563     // disconnect signals
1564     disconnect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
1565     disconnect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
1566     disconnect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
1567     disconnect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
1568     disconnect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
1569
1570     // connect signals
1571     if( cmpDlg->testButtonFlags( QtxDialog::OK ) )
1572       connect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
1573     if( cmpDlg->testButtonFlags( QtxDialog::Apply ) )
1574       connect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
1575     if( cmpDlg->testButtonFlags( QtxDialog::Help ) )
1576       connect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
1577     if( cmpDlg->testButtonFlags( QtxDialog::Cancel ) )
1578       connect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
1579     if( cmpDlg->testButtonFlags( QtxDialog::Close ) )
1580       connect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
1581   }
1582
1583   SMESHGUI_BaseComputeOp::startOperation();
1584
1585   myDlg->show();
1586 }
1587
1588 //================================================================================
1589 /*!
1590  * \brief Stops operation
1591  */
1592 //================================================================================
1593
1594 void SMESHGUI_PrecomputeOp::stopOperation()
1595 {
1596   if ( myPreviewDisplayer )
1597   {
1598     myPreviewDisplayer->SetVisibility( false );
1599     delete myPreviewDisplayer;
1600     myPreviewDisplayer = 0;
1601   }
1602   myMapShapeId.clear();
1603   SMESHGUI_BaseComputeOp::stopOperation();
1604 }
1605
1606 //================================================================================
1607 /*!
1608  * \brief perform it's intention action: reinitialise dialog
1609  */
1610 //================================================================================
1611
1612 void SMESHGUI_PrecomputeOp::resumeOperation()
1613 {
1614   if ( myActiveDlg == myDlg )
1615     initDialog();
1616   SMESHGUI_BaseComputeOp::resumeOperation();
1617 }
1618
1619 void SMESHGUI_PrecomputeOp::initDialog()
1620 {
1621   QList<int> modes;
1622   QMap<int, int> modeMap;
1623   _PTR(SObject)          aHypRoot;
1624   _PTR(GenericAttribute) anAttr;
1625   int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
1626
1627   _PTR(SObject) pMesh = studyDS()->FindObjectID( myIObject->getEntry() );
1628   if ( pMesh && pMesh->FindSubObject( aPart, aHypRoot ) )
1629   {
1630     _PTR(ChildIterator) anIter =
1631       SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
1632     for ( ; anIter->More(); anIter->Next() )
1633     {
1634       _PTR(SObject) anObj = anIter->Value();
1635       _PTR(SObject) aRefObj;
1636       if ( anObj->ReferencedObject( aRefObj ) )
1637         anObj = aRefObj;
1638       else
1639         continue;
1640       
1641       if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
1642       {
1643         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
1644         if ( CORBA::is_nil( aVar ) )
1645           continue;
1646
1647         SMESH::SMESH_Algo_var algo = SMESH::SMESH_3D_Algo::_narrow( aVar );
1648         if ( !algo->_is_nil() )
1649         {
1650           modeMap[ SMESH::DIM_1D ] = 0;
1651           modeMap[ SMESH::DIM_2D ] = 0;
1652         }
1653         else
1654         {
1655           algo = SMESH::SMESH_2D_Algo::_narrow( aVar );
1656           if ( !algo->_is_nil() )
1657             modeMap[ SMESH::DIM_2D ] = 0;
1658         }
1659       }
1660     }
1661   }
1662   if ( modeMap.contains( SMESH::DIM_1D ) )
1663     modes.append( SMESH::DIM_1D );
1664   if ( modeMap.contains( SMESH::DIM_2D ) )
1665     modes.append( SMESH::DIM_2D );
1666
1667   myDlg->setPreviewModes( modes );
1668 }
1669
1670 //================================================================================
1671 /*!
1672  * \brief perform it's intention action: 
1673  */
1674 //================================================================================
1675
1676 bool SMESHGUI_PrecomputeOp::onApply()
1677 {
1678   QObject* obj = sender();
1679   if ( obj != myDlg && myActiveDlg == myDlg )
1680     return true; // just return from error messages
1681   if ( myActiveDlg == myDlg )
1682   {
1683     myDlg->hide();
1684     myMapShapeId.clear();
1685     myActiveDlg = computeDlg();
1686     computeMesh();
1687   }
1688
1689   return true;
1690 }
1691
1692 //================================================================================
1693 /*!
1694  * \brief perform it's intention action: compute mesh
1695  */
1696 //================================================================================
1697
1698 void SMESHGUI_PrecomputeOp::onCancel()
1699 {
1700   QObject* curDlg = sender();
1701   if ( curDlg == computeDlg() )
1702   {
1703     if ( myActiveDlg == myDlg ) // return from error messages
1704       myDlg->show();
1705
1706     return;
1707   }
1708
1709   if ( myActiveDlg == myDlg  && !myMesh->_is_nil() && myMapShapeId.count() )
1710   {
1711     // ask to remove already computed mesh elements
1712     if ( SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
1713                                     tr( "CLEAR_SUBMESH_QUESTION" ),
1714                                     tr( "SMESH_BUT_DELETE" ), tr( "SMESH_BUT_NO" ), 0, 1 ) == 0 )
1715     {
1716       // remove all submeshes for collected shapes
1717       QMap<int,int>::const_iterator it = myMapShapeId.constBegin();
1718       for ( ; it != myMapShapeId.constEnd(); ++it )
1719         myMesh->ClearSubMesh( *it );
1720     }
1721   }
1722   myMapShapeId.clear();
1723   SMESHGUI_BaseComputeOp::onCancel();
1724 }
1725
1726 //================================================================================
1727 /*!
1728  * \brief perform it's intention action: preview mesh
1729  */
1730 //================================================================================
1731
1732 void SMESHGUI_PrecomputeOp::onPreview()
1733 {
1734   if ( !myDlg || myMesh->_is_nil() || myMainShape->_is_nil() )
1735     return;
1736
1737   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
1738   if ( !aMeshSObj )
1739     return;
1740   // Compute preview of mesh, 
1741   // i.e. compute mesh till indicated dimension
1742   int dim = myDlg->getPreviewMode();
1743   
1744   SMESH::MemoryReserve aMemoryReserve;
1745   
1746   SMESH::compute_error_array_var aCompErrors;
1747   QString                        aHypErrors;
1748
1749   bool computeFailed = true, memoryLack = false;
1750
1751   SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
1752     aCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
1753
1754   SMESHGUI* gui = getSMESHGUI();
1755   SMESH::SMESH_Gen_var gen = gui->GetSMESHGen();
1756   SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
1757   if ( errors->length() > 0 ) {
1758     aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
1759   }
1760
1761   SUIT_OverrideCursor aWaitCursor;
1762
1763   SVTK_ViewWindow*    view = SMESH::GetViewWindow( gui );
1764   if ( myPreviewDisplayer ) delete myPreviewDisplayer;
1765   myPreviewDisplayer = new SMESHGUI_MeshEditPreview( view );
1766   
1767   SMESH::long_array_var aShapesId = new SMESH::long_array();
1768   try {
1769 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1770     OCC_CATCH_SIGNALS;
1771 #endif
1772       
1773     SMESH::MeshPreviewStruct_var previewData =
1774       gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId);
1775     if ( previewData.operator->() )
1776     {
1777       computeFailed = false;
1778       myPreviewDisplayer->SetData( previewData._retn() );
1779       // append shape indeces with computed mesh entities
1780       for ( int i = 0, n = aShapesId->length(); i < n; i++ )
1781         myMapShapeId[ aShapesId[ i ] ] = 0;
1782     }
1783     else
1784       myPreviewDisplayer->SetVisibility(false);
1785   }
1786   catch(const SALOME::SALOME_Exception & S_ex){
1787     memoryLack = true;
1788     myPreviewDisplayer->SetVisibility(false);
1789   }
1790
1791   try {
1792 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1793     OCC_CATCH_SIGNALS;
1794 #endif
1795     aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
1796     // check if there are memory problems
1797     for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
1798       memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB );
1799   }
1800   catch(const SALOME::SALOME_Exception & S_ex){
1801     memoryLack = true;
1802   }
1803
1804   if ( memoryLack )
1805     aMemoryReserve.release();
1806
1807   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
1808   bool noHypoError = ( aHypErrors.isEmpty() );
1809
1810   SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( gui );
1811   int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
1812
1813   bool isShowError = true;
1814   switch( aNotifyMode ) {
1815   case 0: // show the mesh computation result dialog NEVER
1816     isShowError = false;
1817     break;
1818   case 1: // show the mesh computation result dialog if there are some errors
1819   default: // show the result dialog after each mesh computation
1820     if ( !computeFailed && !memoryLack && noCompError && noHypoError )
1821       isShowError = false;
1822     break;
1823   }
1824
1825   // SHOW ERRORS
1826   if ( isShowError )
1827   {
1828     myDlg->hide();
1829     aCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
1830     showComputeResult( memoryLack, noCompError, aCompErrors, noHypoError, aHypErrors );
1831   }
1832 }
1833
1834
1835 //================================================================================
1836 /*!
1837  * \brief Constructor
1838 */
1839 //================================================================================
1840
1841 SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent )
1842  : SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help )
1843 {
1844   setWindowTitle( tr( "CAPTION" ) );
1845
1846   setButtonText( OK, tr( "COMPUTE" ) );
1847   QFrame* main = mainFrame();
1848
1849   QVBoxLayout* layout = new QVBoxLayout( main );
1850
1851   QFrame* frame = new QFrame( main );
1852   layout->setMargin(0); layout->setSpacing(0);
1853   layout->addWidget( frame );
1854
1855   QHBoxLayout* frameLay = new QHBoxLayout( frame );
1856   frameLay->setMargin(0); frameLay->setSpacing(SPACING);
1857   
1858   myPreviewMode = new QtxComboBox( frame );
1859   frameLay->addWidget( myPreviewMode );
1860
1861   myPreviewBtn = new QPushButton( tr( "PREVIEW" ), frame );
1862   frameLay->addWidget( myPreviewBtn );
1863
1864   connect( myPreviewBtn, SIGNAL( clicked( bool ) ), this, SIGNAL( preview() ) );
1865 }
1866
1867 //================================================================================
1868 /*!
1869  * \brief Destructor
1870 */
1871 //================================================================================
1872
1873 SMESHGUI_PrecomputeDlg::~SMESHGUI_PrecomputeDlg()
1874 {
1875 }
1876
1877 //================================================================================
1878 /*!
1879  * \brief Sets available preview modes
1880 */
1881 //================================================================================
1882
1883 void SMESHGUI_PrecomputeDlg::setPreviewModes( const QList<int>& theModes )
1884 {
1885   myPreviewMode->clear();
1886   QList<int>::const_iterator it = theModes.constBegin();
1887   for ( int i = 0; it != theModes.constEnd(); ++it, i++ )
1888   {
1889     QString mode = QString( "PREVIEW_%1" ).arg( *it );
1890     myPreviewMode->addItem( tr( mode.toLatin1().data() ) );
1891     myPreviewMode->setId( i, *it );
1892   }
1893   myPreviewBtn->setEnabled( !theModes.isEmpty() );
1894 }
1895
1896 //================================================================================
1897 /*!
1898  * \brief Returns current preview mesh mode
1899 */
1900 //================================================================================
1901
1902 int SMESHGUI_PrecomputeDlg::getPreviewMode() const
1903 {
1904   return myPreviewMode->currentId();
1905 }