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