]> SALOME platform Git repositories - modules/smesh.git/blob - src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
Salome HOME
fix problem with Preview result when server and client launched as independant processes
[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   // create compute dialog if not created before
953   computeDlg();
954
955   myMesh      = SMESH::SMESH_Mesh::_nil();
956   myMainShape = GEOM::GEOM_Object::_nil();
957
958   // check selection
959   LightApp_SelectionMgr *Sel = selectionMgr();
960   SALOME_ListIO selected; Sel->selectedObjects( selected );
961
962   int nbSel = selected.Extent();
963   if (nbSel != 1) {
964     SUIT_MessageBox::warning(desktop(),
965                              tr("SMESH_WRN_WARNING"),
966                              tr("SMESH_WRN_NO_AVAILABLE_DATA"));
967     onCancel();
968     return;
969   }
970
971   myIObject = selected.First();
972   myMesh = SMESH::GetMeshByIO(myIObject);
973   if (myMesh->_is_nil()) {
974     SUIT_MessageBox::warning(desktop(),
975                              tr("SMESH_WRN_WARNING"),
976                              tr("SMESH_WRN_NO_AVAILABLE_DATA"));
977     onCancel();
978
979   }
980   myMainShape = myMesh->GetShapeToMesh();
981
982   SMESHGUI_Operation::startOperation();
983 }
984
985 //================================================================================
986 /*!
987  * \brief computeMesh()
988 */
989 //================================================================================
990
991 void SMESHGUI_BaseComputeOp::computeMesh()
992 {
993   // COMPUTE MESH
994
995   SMESH::MemoryReserve aMemoryReserve;
996
997   SMESH::compute_error_array_var aCompErrors;
998   QString                        aHypErrors;
999
1000   bool computeFailed = true, memoryLack = false;
1001
1002   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
1003   bool hasShape = myMesh->HasShapeToMesh();
1004   bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
1005   if ( shapeOK && aMeshSObj )
1006   {
1007     myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
1008     SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
1009     SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
1010     if ( errors->length() > 0 ) {
1011       aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
1012     }
1013     SUIT_OverrideCursor aWaitCursor;
1014     try {
1015 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1016       OCC_CATCH_SIGNALS;
1017 #endif
1018       if (gen->Compute(myMesh, myMainShape))
1019         computeFailed = false;
1020     }
1021     catch(const SALOME::SALOME_Exception & S_ex){
1022       memoryLack = true;
1023     }
1024     try {
1025 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1026       OCC_CATCH_SIGNALS;
1027 #endif
1028       aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
1029       // check if there are memory problems
1030       for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
1031         memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB );
1032     }
1033     catch(const SALOME::SALOME_Exception & S_ex){
1034       memoryLack = true;
1035     }
1036
1037     // NPAL16631: if ( !memoryLack )
1038     {
1039       SMESH::ModifiedMesh(aMeshSObj, !computeFailed, myMesh->NbNodes() == 0);
1040       update( UF_ObjBrowser | UF_Model );
1041
1042       // SHOW MESH
1043       // NPAL16631: if ( getSMESHGUI()->automaticUpdate() )
1044       if ( !memoryLack && getSMESHGUI()->automaticUpdate() )
1045       {
1046         try {
1047 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1048           OCC_CATCH_SIGNALS;
1049 #endif
1050           SMESH::Update(myIObject, true);
1051         }
1052         catch (...) {
1053 #ifdef _DEBUG_
1054           MESSAGE ( "Exception thrown during mesh visualization" );
1055 #endif
1056           if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
1057             SMESH::OnVisuException();
1058           }
1059           else {
1060             memoryLack = true;
1061           }
1062         }
1063       }
1064       LightApp_SelectionMgr *Sel = selectionMgr();
1065       if ( Sel )
1066       {
1067         SALOME_ListIO selected;
1068         selected.Append( myIObject );
1069         Sel->setSelectedObjects( selected );
1070       }
1071     }
1072   }
1073
1074   if ( memoryLack )
1075     aMemoryReserve.release();
1076
1077   myCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
1078
1079   // SHOW ERRORS
1080   
1081   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
1082   bool noHypoError = ( aHypErrors.isEmpty() );
1083
1084   SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
1085   int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
1086
1087   bool isShowResultDlg = true;
1088   switch( aNotifyMode ) {
1089   case 0: // show the mesh computation result dialog NEVER
1090     isShowResultDlg = false;
1091     commit();
1092     break;
1093   case 1: // show the mesh computation result dialog if there are some errors
1094     if ( memoryLack || !noCompError || !noHypoError )
1095       isShowResultDlg = true;
1096     else
1097     {
1098       isShowResultDlg = false;
1099       commit();
1100     }
1101     break;
1102   default: // show the result dialog after each mesh computation
1103     isShowResultDlg = true;
1104   }
1105
1106   // SHOW RESULTS
1107   if ( isShowResultDlg )
1108     showComputeResult( memoryLack, noCompError,aCompErrors, noHypoError, aHypErrors );
1109 }
1110
1111 void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
1112                                                 const bool theNoCompError,
1113                                                 SMESH::compute_error_array_var& theCompErrors,
1114                                                 const bool     theNoHypoError,
1115                                                 const QString& theHypErrors )
1116 {
1117   bool hasShape = myMesh->HasShapeToMesh();
1118   SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
1119   aCompDlg->myMemoryLackGroup->hide();
1120
1121   if ( theMemoryLack )
1122   {
1123     aCompDlg->myMemoryLackGroup->show();
1124     aCompDlg->myFullInfo->hide();
1125     aCompDlg->myBriefInfo->hide();
1126     aCompDlg->myHypErrorGroup->hide();
1127     aCompDlg->myCompErrorGroup->hide();
1128   }
1129   else if ( theNoCompError && theNoHypoError )
1130   {
1131     aCompDlg->myFullInfo->SetInfoByMesh( myMesh );
1132     aCompDlg->myFullInfo->show();
1133     aCompDlg->myBriefInfo->hide();
1134     aCompDlg->myHypErrorGroup->hide();
1135     aCompDlg->myCompErrorGroup->hide();
1136   }
1137   else
1138   {
1139     QTableWidget* tbl = aCompDlg->myTable;
1140     aCompDlg->myBriefInfo->SetInfoByMesh( myMesh );
1141     aCompDlg->myBriefInfo->show();
1142     aCompDlg->myFullInfo->hide();
1143
1144     if ( theNoHypoError ) {
1145       aCompDlg->myHypErrorGroup->hide();
1146     }
1147     else {
1148       aCompDlg->myHypErrorGroup->show();
1149       aCompDlg->myHypErrorLabel->setText( theHypErrors );
1150     }
1151
1152     if ( theNoCompError ) {
1153       aCompDlg->myCompErrorGroup->hide();
1154     }
1155     else {
1156       aCompDlg->myCompErrorGroup->show();
1157
1158       if ( !hasShape ) {
1159         aCompDlg->myPublishBtn->hide();
1160         aCompDlg->myShowBtn->hide();
1161       }
1162       else {
1163         aCompDlg->myPublishBtn->show();
1164         aCompDlg->myShowBtn->show();
1165       }
1166
1167       // fill table of errors
1168       tbl->setRowCount( theCompErrors->length() );
1169       if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
1170       else             tbl->showColumn( COL_SHAPE );
1171       tbl->setColumnWidth( COL_ERROR, 200 );
1172
1173       bool hasBadMesh = false;
1174       for ( int row = 0; row < theCompErrors->length(); ++row )
1175       {
1176         SMESH::ComputeError & err = theCompErrors[ row ];
1177
1178         QString text = err.algoName.in();
1179         if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
1180         else tbl->item( row, COL_ALGO )->setText( text );
1181
1182         text = SMESH::errorText( err.code, err.comment.in() );
1183         if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
1184         else tbl->item( row, COL_ERROR )->setText( text );
1185
1186         text = QString("%1").arg( err.subShapeID );
1187         if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
1188         else tbl->item( row, COL_SHAPEID )->setText( text );
1189
1190         text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
1191         if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
1192         else tbl->item( row, COL_SHAPE )->setText( text );
1193
1194         text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
1195         if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
1196         else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
1197
1198         text = err.hasBadMesh ? "hasBadMesh" : "";
1199         if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
1200         else tbl->item( row, COL_BAD_MESH )->setText( text );
1201         if ( err.hasBadMesh ) hasBadMesh = true;
1202
1203         //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
1204         tbl->resizeRowToContents( row );
1205       }
1206       tbl->resizeColumnToContents( COL_ALGO );
1207       tbl->resizeColumnToContents( COL_SHAPE );
1208
1209       if ( hasBadMesh )
1210         aCompDlg->myBadMeshBtn->show();
1211       else
1212         aCompDlg->myBadMeshBtn->hide();
1213
1214       tbl->setCurrentCell(0,0);
1215       currentCellChanged(); // to update buttons
1216     }
1217   }
1218   // show dialog and wait, becase Compute can be invoked from Preview operation
1219   aCompDlg->exec();
1220 }
1221
1222 //================================================================================
1223 /*!
1224  * \brief Stops operation
1225  */
1226 //================================================================================
1227
1228 void SMESHGUI_BaseComputeOp::stopOperation()
1229 {
1230   SMESHGUI_Operation::stopOperation();
1231   if ( myTShapeDisplayer )
1232     myTShapeDisplayer->SetVisibility( false );
1233   if ( myBadMeshDisplayer ) {
1234     myBadMeshDisplayer->SetVisibility( false );
1235     // delete it in order not to have problems at its destruction when the viewer
1236     // where it worked is dead due to e.g. study closing
1237     delete myBadMeshDisplayer;
1238     myBadMeshDisplayer = 0;
1239   }
1240   myIObject.Nullify();
1241 }
1242
1243 //================================================================================
1244 /*!
1245  * \brief publish selected subshape
1246  */
1247 //================================================================================
1248
1249 void SMESHGUI_BaseComputeOp::onPublishShape()
1250 {
1251   GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
1252   SALOMEDS::Study_var study = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
1253
1254   QList<int> rows;
1255   SMESH::getSelectedRows( table(), rows );
1256   int row;
1257   foreach ( row, rows )
1258   {
1259     int curSub = table()->item(row, COL_SHAPEID)->text().toInt();
1260     GEOM::GEOM_Object_var shape = SMESH::getSubShape( curSub, myMainShape );
1261     if ( !shape->_is_nil() && ! SMESH::getSubShapeSO( curSub, myMainShape ))
1262     {
1263       if ( !SMESH::getSubShapeSO( 1, myMainShape )) // the main shape not published
1264       {
1265         QString name = GEOMBase::GetDefaultName( SMESH::shapeTypeName( myMainShape, "MAIN_SHAPE" ));
1266         SALOMEDS::SObject_var so =
1267           geomGen->AddInStudy( study, myMainShape, name.toLatin1().data(), GEOM::GEOM_Object::_nil());
1268         // look for myMainShape in the table
1269         for ( int r = 0, nr = table()->rowCount(); r < nr; ++r ) {
1270           if ( table()->item( r, COL_SHAPEID )->text() == "1" ) {
1271             if ( so->_is_nil() ) {
1272               table()->item( r, COL_SHAPE )->setText( so->GetName() );
1273               table()->item( r, COL_PUBLISHED )->setText( so->GetID() );
1274             }
1275             break;
1276           }
1277         }
1278         if ( curSub == 1 ) continue;
1279       }
1280       QString name = GEOMBase::GetDefaultName( SMESH::shapeTypeName( shape, "ERROR_SHAPE" ));
1281       SALOMEDS::SObject_var so = geomGen->AddInStudy( study, shape, name.toLatin1().data(), myMainShape);
1282       if ( !so->_is_nil() ) {
1283         table()->item( row, COL_SHAPE )->setText( so->GetName() );
1284         table()->item( row, COL_PUBLISHED )->setText( so->GetID() );
1285       }
1286     }
1287   }
1288   getSMESHGUI()->getApp()->updateObjectBrowser();
1289   currentCellChanged(); // to update buttons
1290 }
1291
1292 //================================================================================
1293 /*!
1294  * \brief show mesh elements preventing computation of a submesh of current row
1295  */
1296 //================================================================================
1297
1298 void SMESHGUI_BaseComputeOp::onShowBadMesh()
1299 {
1300   myTShapeDisplayer->SetVisibility( false );
1301   QList<int> rows;
1302   if ( SMESH::getSelectedRows( table(), rows ) == 1 ) {
1303     bool hasBadMesh = ( !table()->item(rows.front(), COL_BAD_MESH)->text().isEmpty() );
1304     if ( hasBadMesh ) {
1305       int curSub = table()->item(rows.front(), COL_SHAPEID)->text().toInt();
1306       SMESHGUI* gui = getSMESHGUI();
1307       SMESH::SMESH_Gen_var gen = gui->GetSMESHGen();
1308       SVTK_ViewWindow*    view = SMESH::GetViewWindow( gui );
1309       if ( myBadMeshDisplayer ) delete myBadMeshDisplayer;
1310       myBadMeshDisplayer = new SMESHGUI_MeshEditPreview( view );
1311       SMESH::MeshPreviewStruct_var aMeshData = gen->GetBadInputElements(myMesh,curSub);
1312       vtkFloatingPointType aPointSize = SMESH::GetFloat("SMESH:node_size",3);
1313       vtkFloatingPointType aLineWidth = SMESH::GetFloat("SMESH:element_width",1);
1314       // delete property !!!!!!!!!!
1315       vtkProperty* prop = vtkProperty::New();
1316       prop->SetLineWidth( aLineWidth * 3 );
1317       prop->SetPointSize( aPointSize * 3 );
1318       prop->SetColor( 250, 0, 250 );
1319       myBadMeshDisplayer->GetActor()->SetProperty( prop );
1320       myBadMeshDisplayer->SetData( aMeshData._retn() );
1321     }
1322   }
1323 }
1324
1325 //================================================================================
1326 /*!
1327  * \brief SLOT called when a selected cell in table() changed
1328  */
1329 //================================================================================
1330
1331 void SMESHGUI_BaseComputeOp::currentCellChanged()
1332 {
1333   myTShapeDisplayer->SetVisibility( false );
1334   if ( myBadMeshDisplayer )
1335     myBadMeshDisplayer->SetVisibility( false );
1336
1337   bool publishEnable = 0, showEnable = 0, showOnly = 1, hasBadMesh = 0;
1338   QList<int> rows;
1339   int nbSelected = SMESH::getSelectedRows( table(), rows );
1340   int row;
1341   foreach ( row, rows )
1342   {
1343     bool hasData     = ( !table()->item( row, COL_SHAPE )->text().isEmpty() );
1344     bool isPublished = ( !table()->item( row, COL_PUBLISHED )->text().isEmpty() );
1345     if ( hasData && !isPublished )
1346       publishEnable = true;
1347
1348     int curSub = table()->item( row, COL_SHAPEID )->text().toInt();
1349     bool prsReady = myTShapeDisplayer->HasReadyActorsFor( curSub, myMainShape );
1350     if ( prsReady ) {
1351       myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
1352       showOnly = false;
1353     }
1354     else {
1355       showEnable = true;
1356     }
1357
1358     if ( !table()->item(row, COL_BAD_MESH)->text().isEmpty() )
1359       hasBadMesh = true;
1360   }
1361   myCompDlg->myPublishBtn->setEnabled( publishEnable );
1362   myCompDlg->myShowBtn   ->setEnabled( showEnable );
1363   myCompDlg->myBadMeshBtn->setEnabled( hasBadMesh && ( nbSelected == 1 ));
1364 }
1365
1366 //================================================================================
1367 /*!
1368  * \brief update preview
1369  */
1370 //================================================================================
1371
1372 void SMESHGUI_BaseComputeOp::onPreviewShape()
1373 {
1374   if ( myTShapeDisplayer )
1375   {
1376     SUIT_OverrideCursor aWaitCursor;
1377     QList<int> rows;
1378     SMESH::getSelectedRows( table(), rows );
1379
1380     bool showOnly = true;
1381     int row;
1382     foreach ( row, rows )
1383     {
1384       int curSub = table()->item( row, COL_SHAPEID )->text().toInt();
1385       if ( curSub > 0 ) {
1386         myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
1387         showOnly = false;
1388       }
1389     }
1390     currentCellChanged(); // to update buttons
1391   }
1392 }
1393
1394 //================================================================================
1395 /*!
1396  * \brief Destructor
1397  */
1398 //================================================================================
1399
1400 SMESHGUI_BaseComputeOp::~SMESHGUI_BaseComputeOp()
1401 {
1402   delete myCompDlg;
1403   myCompDlg = 0;
1404   delete myTShapeDisplayer;
1405   if ( myBadMeshDisplayer )
1406     delete myBadMeshDisplayer;
1407 }
1408
1409 //================================================================================
1410 /*!
1411  * \brief Gets dialog of compute operation
1412  * \retval SMESHGUI_ComputeDlg* - pointer to dialog of this operation
1413  */
1414 //================================================================================
1415
1416 SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::computeDlg() const
1417 {
1418   if ( !myCompDlg )
1419   {
1420     SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
1421     me->myCompDlg = new SMESHGUI_ComputeDlg( desktop() );
1422     // connect signals and slots
1423     connect(myCompDlg->myShowBtn,    SIGNAL (clicked()), SLOT(onPreviewShape()));
1424     connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
1425     connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh()));
1426
1427     QTableWidget* aTable = me->table();
1428     connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged()));
1429     connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged()));
1430   }
1431   return myCompDlg;
1432 }
1433
1434 //================================================================================
1435 /*!
1436  * \brief Return a table
1437  */
1438 //================================================================================
1439
1440 QTableWidget* SMESHGUI_BaseComputeOp::table()
1441 {
1442   return myCompDlg->myTable;
1443 }
1444
1445
1446 //================================================================================
1447 /*!
1448  * \brief Constructor
1449 */
1450 //================================================================================
1451
1452 SMESHGUI_ComputeOp::SMESHGUI_ComputeOp()
1453  : SMESHGUI_BaseComputeOp()
1454 {
1455 }
1456
1457
1458 //================================================================================
1459 /*!
1460  * \brief Desctructor
1461 */
1462 //================================================================================
1463
1464 SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp()
1465 {
1466 }
1467
1468 //================================================================================
1469 /*!
1470  * \brief perform it's intention action: compute mesh
1471  */
1472 //================================================================================
1473
1474 void SMESHGUI_ComputeOp::startOperation()
1475 {
1476   SMESHGUI_BaseComputeOp::startOperation();
1477   computeMesh();
1478 }
1479
1480 //================================================================================
1481 /*!
1482  * \brief perform it's intention action: compute mesh
1483  */
1484 //================================================================================
1485
1486 bool SMESHGUI_ComputeOp::onApply()
1487 {
1488   return true;
1489 }
1490
1491 //================================================================================
1492 /*!
1493  * \brief Gets dialog of this operation
1494  * \retval LightApp_Dialog* - pointer to dialog of this operation
1495  */
1496 //================================================================================
1497
1498 LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
1499 {
1500   return computeDlg();
1501 }
1502
1503 //================================================================================
1504 /*!
1505  * \brief Constructor
1506 */
1507 //================================================================================
1508
1509 SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp()
1510  : SMESHGUI_BaseComputeOp(),
1511  myDlg( 0 ),
1512  myActiveDlg( 0 ),
1513  myPreviewDisplayer( 0 )
1514 {
1515   myHelpFileName = "preview_meshes_page.html"; // V4
1516 }
1517
1518 //================================================================================
1519 /*!
1520  * \brief Destructor
1521  */
1522 //================================================================================
1523
1524 SMESHGUI_PrecomputeOp::~SMESHGUI_PrecomputeOp()
1525 {
1526   delete myDlg;
1527   myDlg = 0;
1528   myActiveDlg = 0;
1529   if ( myPreviewDisplayer )
1530     delete myPreviewDisplayer;
1531   myPreviewDisplayer = 0;
1532 }
1533
1534 //================================================================================
1535 /*!
1536  * \brief Gets current dialog of this operation
1537  * \retval LightApp_Dialog* - pointer to dialog of this operation
1538  */
1539 //================================================================================
1540
1541 LightApp_Dialog* SMESHGUI_PrecomputeOp::dlg() const
1542 {
1543   return myActiveDlg;
1544 }
1545
1546 //================================================================================
1547 /*!
1548  * \brief perform it's intention action: prepare data
1549  */
1550 //================================================================================
1551
1552 void SMESHGUI_PrecomputeOp::startOperation()
1553 {
1554   if ( !myDlg )
1555   {
1556     myDlg = new SMESHGUI_PrecomputeDlg( desktop() );
1557     
1558     // connect signals
1559     connect( myDlg, SIGNAL( preview() ), this, SLOT( onPreview() ) );
1560   }
1561   myActiveDlg = myDlg;
1562
1563   // connect signal to compute dialog. which will be shown after Compute mesh operation
1564   SMESHGUI_ComputeDlg* cmpDlg = computeDlg();
1565   if ( cmpDlg )
1566   {
1567     // disconnect signals
1568     disconnect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
1569     disconnect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
1570     disconnect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
1571     disconnect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
1572     disconnect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
1573
1574     // connect signals
1575     if( cmpDlg->testButtonFlags( QtxDialog::OK ) )
1576       connect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
1577     if( cmpDlg->testButtonFlags( QtxDialog::Apply ) )
1578       connect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
1579     if( cmpDlg->testButtonFlags( QtxDialog::Help ) )
1580       connect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
1581     if( cmpDlg->testButtonFlags( QtxDialog::Cancel ) )
1582       connect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
1583     if( cmpDlg->testButtonFlags( QtxDialog::Close ) )
1584       connect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
1585   }
1586
1587   SMESHGUI_BaseComputeOp::startOperation();
1588
1589   myDlg->show();
1590 }
1591
1592 //================================================================================
1593 /*!
1594  * \brief Stops operation
1595  */
1596 //================================================================================
1597
1598 void SMESHGUI_PrecomputeOp::stopOperation()
1599 {
1600   if ( myPreviewDisplayer )
1601   {
1602     myPreviewDisplayer->SetVisibility( false );
1603     delete myPreviewDisplayer;
1604     myPreviewDisplayer = 0;
1605   }
1606   myMapShapeId.clear();
1607   SMESHGUI_BaseComputeOp::stopOperation();
1608 }
1609
1610 //================================================================================
1611 /*!
1612  * \brief perform it's intention action: reinitialise dialog
1613  */
1614 //================================================================================
1615
1616 void SMESHGUI_PrecomputeOp::resumeOperation()
1617 {
1618   if ( myActiveDlg == myDlg )
1619     initDialog();
1620   SMESHGUI_BaseComputeOp::resumeOperation();
1621 }
1622
1623 void SMESHGUI_PrecomputeOp::initDialog()
1624 {
1625   QList<int> modes;
1626   QMap<int, int> modeMap;
1627   _PTR(SObject)          aHypRoot;
1628   _PTR(GenericAttribute) anAttr;
1629   int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
1630
1631   _PTR(SObject) pMesh = studyDS()->FindObjectID( myIObject->getEntry() );
1632   if ( pMesh && pMesh->FindSubObject( aPart, aHypRoot ) )
1633   {
1634     _PTR(ChildIterator) anIter =
1635       SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
1636     for ( ; anIter->More(); anIter->Next() )
1637     {
1638       _PTR(SObject) anObj = anIter->Value();
1639       _PTR(SObject) aRefObj;
1640       if ( anObj->ReferencedObject( aRefObj ) )
1641         anObj = aRefObj;
1642       else
1643         continue;
1644       
1645       if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
1646       {
1647         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
1648         if ( CORBA::is_nil( aVar ) )
1649           continue;
1650
1651         SMESH::SMESH_Algo_var algo = SMESH::SMESH_3D_Algo::_narrow( aVar );
1652         if ( !algo->_is_nil() )
1653         {
1654           modeMap[ SMESH::DIM_1D ] = 0;
1655           modeMap[ SMESH::DIM_2D ] = 0;
1656         }
1657         else
1658         {
1659           algo = SMESH::SMESH_2D_Algo::_narrow( aVar );
1660           if ( !algo->_is_nil() )
1661             modeMap[ SMESH::DIM_2D ] = 0;
1662         }
1663       }
1664     }
1665   }
1666   if ( modeMap.contains( SMESH::DIM_1D ) )
1667     modes.append( SMESH::DIM_1D );
1668   if ( modeMap.contains( SMESH::DIM_2D ) )
1669     modes.append( SMESH::DIM_2D );
1670
1671   myDlg->setPreviewModes( modes );
1672 }
1673
1674 //================================================================================
1675 /*!
1676  * \brief perform it's intention action: 
1677  */
1678 //================================================================================
1679
1680 bool SMESHGUI_PrecomputeOp::onApply()
1681 {
1682   QObject* obj = sender();
1683   if ( obj != myDlg && myActiveDlg == myDlg )
1684     return true; // just return from error messages
1685   if ( myActiveDlg == myDlg )
1686   {
1687     myDlg->hide();
1688     myMapShapeId.clear();
1689     myActiveDlg = computeDlg();
1690     computeMesh();
1691   }
1692
1693   return true;
1694 }
1695
1696 //================================================================================
1697 /*!
1698  * \brief perform it's intention action: compute mesh
1699  */
1700 //================================================================================
1701
1702 void SMESHGUI_PrecomputeOp::onCancel()
1703 {
1704   QObject* curDlg = sender();
1705   if ( curDlg == computeDlg() )
1706   {
1707     if ( myActiveDlg == myDlg ) // return from error messages
1708       myDlg->show();
1709
1710     return;
1711   }
1712
1713   if ( myActiveDlg == myDlg  && !myMesh->_is_nil() && myMapShapeId.count() )
1714   {
1715     // ask to remove already computed mesh elements
1716     if ( SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
1717                                     tr( "CLEAR_SUBMESH_QUESTION" ),
1718                                     tr( "SMESH_BUT_DELETE" ), tr( "SMESH_BUT_NO" ), 0, 1 ) == 0 )
1719     {
1720       // remove all submeshes for collected shapes
1721       QMap<int,int>::const_iterator it = myMapShapeId.constBegin();
1722       for ( ; it != myMapShapeId.constEnd(); ++it )
1723         myMesh->ClearSubMesh( *it );
1724     }
1725   }
1726   myMapShapeId.clear();
1727   SMESHGUI_BaseComputeOp::onCancel();
1728 }
1729
1730 //================================================================================
1731 /*!
1732  * \brief perform it's intention action: preview mesh
1733  */
1734 //================================================================================
1735
1736 void SMESHGUI_PrecomputeOp::onPreview()
1737 {
1738   if ( !myDlg || myMesh->_is_nil() || myMainShape->_is_nil() )
1739     return;
1740
1741   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
1742   if ( !aMeshSObj )
1743     return;
1744   // Compute preview of mesh, 
1745   // i.e. compute mesh till indicated dimension
1746   int dim = myDlg->getPreviewMode();
1747   
1748   SMESH::MemoryReserve aMemoryReserve;
1749   
1750   SMESH::compute_error_array_var aCompErrors;
1751   QString                        aHypErrors;
1752
1753   bool computeFailed = true, memoryLack = false;
1754
1755   SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
1756     aCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
1757
1758   SMESHGUI* gui = getSMESHGUI();
1759   SMESH::SMESH_Gen_var gen = gui->GetSMESHGen();
1760   SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
1761   if ( errors->length() > 0 ) {
1762     aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
1763   }
1764
1765   SUIT_OverrideCursor aWaitCursor;
1766
1767   SVTK_ViewWindow*    view = SMESH::GetViewWindow( gui );
1768   if ( myPreviewDisplayer ) delete myPreviewDisplayer;
1769   myPreviewDisplayer = new SMESHGUI_MeshEditPreview( view );
1770   
1771   SMESH::long_array_var aShapesId = new SMESH::long_array();
1772   try {
1773 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1774     OCC_CATCH_SIGNALS;
1775 #endif
1776       
1777     SMESH::MeshPreviewStruct_var previewData =
1778       gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId);
1779     SMESH::MeshPreviewStruct* previewRes = previewData._retn();
1780     if ( previewRes && previewRes->nodesXYZ.length() > 0 )
1781     {
1782       computeFailed = false;
1783       myPreviewDisplayer->SetData( previewRes );
1784       // append shape indeces with computed mesh entities
1785       for ( int i = 0, n = aShapesId->length(); i < n; i++ )
1786         myMapShapeId[ aShapesId[ i ] ] = 0;
1787     }
1788     else
1789       myPreviewDisplayer->SetVisibility(false);
1790   }
1791   catch(const SALOME::SALOME_Exception & S_ex){
1792     memoryLack = true;
1793     myPreviewDisplayer->SetVisibility(false);
1794   }
1795
1796   try {
1797 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1798     OCC_CATCH_SIGNALS;
1799 #endif
1800     aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
1801     // check if there are memory problems
1802     for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
1803       memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB );
1804   }
1805   catch(const SALOME::SALOME_Exception & S_ex){
1806     memoryLack = true;
1807   }
1808
1809   if ( memoryLack )
1810     aMemoryReserve.release();
1811
1812   bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
1813   bool noHypoError = ( aHypErrors.isEmpty() );
1814
1815   SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( gui );
1816   int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
1817
1818   bool isShowError = true;
1819   switch( aNotifyMode ) {
1820   case 0: // show the mesh computation result dialog NEVER
1821     isShowError = false;
1822     break;
1823   case 1: // show the mesh computation result dialog if there are some errors
1824   default: // show the result dialog after each mesh computation
1825     if ( !computeFailed && !memoryLack && noCompError && noHypoError )
1826       isShowError = false;
1827     break;
1828   }
1829
1830   aWaitCursor.suspend();
1831   // SHOW ERRORS
1832   if ( isShowError )
1833   {
1834     myDlg->hide();
1835     aCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
1836     showComputeResult( memoryLack, noCompError, aCompErrors, noHypoError, aHypErrors );
1837   }
1838 }
1839
1840
1841 //================================================================================
1842 /*!
1843  * \brief Constructor
1844 */
1845 //================================================================================
1846
1847 SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent )
1848  : SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help )
1849 {
1850   setWindowTitle( tr( "CAPTION" ) );
1851
1852   setButtonText( OK, tr( "COMPUTE" ) );
1853   QFrame* main = mainFrame();
1854
1855   QVBoxLayout* layout = new QVBoxLayout( main );
1856
1857   QFrame* frame = new QFrame( main );
1858   layout->setMargin(0); layout->setSpacing(0);
1859   layout->addWidget( frame );
1860
1861   QHBoxLayout* frameLay = new QHBoxLayout( frame );
1862   frameLay->setMargin(0); frameLay->setSpacing(SPACING);
1863   
1864   myPreviewMode = new QtxComboBox( frame );
1865   frameLay->addWidget( myPreviewMode );
1866
1867   myPreviewBtn = new QPushButton( tr( "PREVIEW" ), frame );
1868   frameLay->addWidget( myPreviewBtn );
1869
1870   connect( myPreviewBtn, SIGNAL( clicked( bool ) ), this, SIGNAL( preview() ) );
1871 }
1872
1873 //================================================================================
1874 /*!
1875  * \brief Destructor
1876 */
1877 //================================================================================
1878
1879 SMESHGUI_PrecomputeDlg::~SMESHGUI_PrecomputeDlg()
1880 {
1881 }
1882
1883 //================================================================================
1884 /*!
1885  * \brief Sets available preview modes
1886 */
1887 //================================================================================
1888
1889 void SMESHGUI_PrecomputeDlg::setPreviewModes( const QList<int>& theModes )
1890 {
1891   myPreviewMode->clear();
1892   QList<int>::const_iterator it = theModes.constBegin();
1893   for ( int i = 0; it != theModes.constEnd(); ++it, i++ )
1894   {
1895     QString mode = QString( "PREVIEW_%1" ).arg( *it );
1896     myPreviewMode->addItem( tr( mode.toLatin1().data() ) );
1897     myPreviewMode->setId( i, *it );
1898   }
1899   myPreviewBtn->setEnabled( !theModes.isEmpty() );
1900 }
1901
1902 //================================================================================
1903 /*!
1904  * \brief Returns current preview mesh mode
1905 */
1906 //================================================================================
1907
1908 int SMESHGUI_PrecomputeDlg::getPreviewMode() const
1909 {
1910   return myPreviewMode->currentId();
1911 }