Salome HOME
23619: EDF 18055 - Detection of sharp edges
[modules/smesh.git] / src / SMESHGUI / SMESHGUI.cxx
1 // Copyright (C) 2007-2016  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, or (at your option) any later version.
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.cxx
23 //  Author : Nicolas REJNERI, Open CASCADE S.A.S.
24
25 #include <Standard_math.hxx>  // E.A. must be included before Python.h to fix compilation on windows
26 #ifdef HAVE_FINITE
27 #undef HAVE_FINITE            // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined
28 #endif
29 #include "Python.h"
30
31 //  SMESH includes
32 #include "SMESHGUI.h"
33 #include "SMESHGUI_Add0DElemsOnAllNodesDlg.h"
34 #include "SMESHGUI_AddMeshElementDlg.h"
35 #include "SMESHGUI_AddQuadraticElementDlg.h"
36 #include "SMESHGUI_BuildCompoundDlg.h"
37 #include "SMESHGUI_ClippingDlg.h"
38 #include "SMESHGUI_ComputeDlg.h"
39 #include "SMESHGUI_ConvToQuadOp.h"
40 #include "SMESHGUI_CopyMeshDlg.h"
41 #include "SMESHGUI_CreatePolyhedralVolumeDlg.h"
42 #include "SMESHGUI_DeleteGroupDlg.h"
43 #include "SMESHGUI_DisplayEntitiesDlg.h"
44 #include "SMESHGUI_Displayer.h"
45 #include "SMESHGUI_DuplicateNodesDlg.h"
46 #include "SMESHGUI_ExtrusionAlongPathDlg.h"
47 #include "SMESHGUI_ExtrusionDlg.h"
48 #include "SMESHGUI_FaceGroupsSeparatedByEdgesDlg.h"
49 #include "SMESHGUI_FieldSelectorWdg.h"
50 #include "SMESHGUI_FileInfoDlg.h"
51 #include "SMESHGUI_FileValidator.h"
52 #include "SMESHGUI_FilterDlg.h"
53 #include "SMESHGUI_FilterLibraryDlg.h"
54 #include "SMESHGUI_FilterUtils.h"
55 #include "SMESHGUI_FindElemByPointDlg.h"
56 #include "SMESHGUI_GEOMGenUtils.h"
57 #include "SMESHGUI_GroupDlg.h"
58 #include "SMESHGUI_GroupOnShapeDlg.h"
59 #include "SMESHGUI_GroupOpDlg.h"
60 #include "SMESHGUI_GroupUtils.h"
61 #include "SMESHGUI_Hypotheses.h"
62 #include "SMESHGUI_HypothesesUtils.h"
63 #include "SMESHGUI_Make2DFrom3DOp.h"
64 #include "SMESHGUI_MakeNodeAtPointDlg.h"
65 #include "SMESHGUI_Measurements.h"
66 #include "SMESHGUI_MergeDlg.h"
67 #include "SMESHGUI_MeshInfo.h"
68 #include "SMESHGUI_MeshOp.h"
69 #include "SMESHGUI_MeshOrderOp.h"
70 #include "SMESHGUI_MeshPatternDlg.h"
71 #include "SMESHGUI_MeshUtils.h"
72 #include "SMESHGUI_MultiEditDlg.h"
73 #include "SMESHGUI_NodesDlg.h"
74 #include "SMESHGUI_OffsetDlg.h"
75 #include "SMESHGUI_Operations.h"
76 #include "SMESHGUI_PatternUtils.h"
77 #include "SMESHGUI_Preferences_ScalarBarDlg.h"
78 #include "SMESHGUI_PropertiesDlg.h"
79 #include "SMESHGUI_RemoveElementsDlg.h"
80 #include "SMESHGUI_RemoveNodesDlg.h"
81 #include "SMESHGUI_RenumberingDlg.h"
82 #include "SMESHGUI_ReorientFacesDlg.h"
83 #include "SMESHGUI_RevolutionDlg.h"
84 #include "SMESHGUI_RotationDlg.h"
85 #include "SMESHGUI_ScaleDlg.h"
86 #include "SMESHGUI_Selection.h"
87 #include "SMESHGUI_SewingDlg.h"
88 #include "SMESHGUI_SingleEditDlg.h"
89 #include "SMESHGUI_SmoothingDlg.h"
90 #include "SMESHGUI_SpinBox.h"
91 #include "SMESHGUI_SplitBiQuad.h"
92 #include "SMESHGUI_SymmetryDlg.h"
93 #include "SMESHGUI_TranslationDlg.h"
94 #include "SMESHGUI_TransparencyDlg.h"
95 #include "SMESHGUI_Utils.h"
96 #include "SMESHGUI_VTKUtils.h"
97
98 #include "SMESH_version.h"
99
100 #include "SMESH_ControlsDef.hxx"
101 #include "SMESH_Actor.h"
102 #include "SMESH_ActorUtils.h"
103 #include "SMESH_Client.hxx"
104 #include "SMESH_ScalarBarActor.h"
105 #include <SMESH_Comment.hxx>
106 #include "SMESH_TypeFilter.hxx"
107
108 // SALOME GUI includes
109 #include <LightApp_DataOwner.h>
110 #include <LightApp_NameDlg.h>
111 #include <LightApp_Preferences.h>
112 #include <LightApp_SelectionMgr.h>
113 #include <LightApp_UpdateFlags.h>
114 #include <QtxFontEdit.h>
115 #include <QtxPopupMgr.h>
116 #include <SALOME_ListIO.hxx>
117 #include <SUIT_Desktop.h>
118 #include <SUIT_FileDlg.h>
119 #include <SUIT_MessageBox.h>
120 #include <SUIT_OverrideCursor.h>
121 #include <SUIT_ResourceMgr.h>
122 #include <SUIT_Session.h>
123 #include <SVTK_ViewManager.h>
124 #include <SVTK_ViewModel.h>
125 #include <SVTK_ViewWindow.h>
126 #include <SalomeApp_Application.h>
127 #include <SalomeApp_CheckFileDlg.h>
128 #include <SalomeApp_DataObject.h>
129 #include <SalomeApp_Study.h>
130 #include <SalomeApp_Tools.h>
131 #include <VTKViewer_Algorithm.h>
132
133 #ifndef DISABLE_PLOT2DVIEWER
134 #include <SPlot2d_ViewModel.h>
135 #include <SPlot2d_Histogram.h>
136 #endif
137
138 // IDL includes
139 #include <SALOMEconfig.h>
140 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
141 #include CORBA_CLIENT_HEADER(SMESH_MeshEditor)
142 #include CORBA_CLIENT_HEADER(SMESH_Measurements)
143 #include CORBA_CLIENT_HEADER(SMESH_Mesh)
144
145 // Qt includes
146 // #define       INCLUDE_MENUITEM_DEF // VSR commented ????????
147 #include <QApplication>
148 #include <QCheckBox>
149 #include <QDialogButtonBox>
150 #include <QLayout>
151 #include <QListView>
152 #include <QMenu>
153 #include <QTextStream>
154 #include <QTreeView>
155
156 // BOOST includes
157 #include <boost/shared_ptr.hpp>
158
159 // VTK includes
160 #include <vtkCallbackCommand.h>
161 #include <vtkCamera.h>
162 #include <vtkLookupTable.h>
163 #include <vtkPlane.h>
164 #include <vtkRenderer.h>
165
166 // SALOME KERNEL includes
167 #include <SALOMEDSClient_ClientFactory.hxx>
168 #include <SALOMEDSClient_IParameters.hxx>
169 #include <SALOMEDSClient_SComponent.hxx>
170 #include <SALOMEDSClient_StudyBuilder.hxx>
171 #include <SALOMEDS_Study.hxx>
172 #include <SALOMEDS_SObject.hxx>
173 #include "utilities.h"
174
175 // OCCT includes
176 #include <Standard_ErrorHandler.hxx>
177 #include <NCollection_DataMap.hxx>
178 #include <NCollection_DoubleMap.hxx>
179
180 #include <Basics_Utils.hxx>
181
182 // Below macro, when uncommented, switches on simplified (more performant) algorithm
183 // of auto-color picking up
184 #define SIMPLE_AUTOCOLOR
185
186 namespace
187 {
188   // Declarations
189   //=============================================================
190   void ImportMeshesFromFile(SMESH::SMESH_Gen_ptr theComponentMesh,
191                             int                  theCommandID);
192
193   void ExportMeshToFile(int theCommandID);
194
195   void SetDisplayMode(int theCommandID, VTK::MarkerMap& theMarkerMap);
196
197   void SetDisplayEntity(int theCommandID);
198
199   int  ActionToControl( int theID, bool theReversed = false );
200
201   void Control( int theCommandID );
202
203   // Definitions
204   //================================================================================
205   /*!
206    * \brief Reads meshes from file
207    */
208   //================================================================================
209
210   void ImportMeshesFromFile( SMESH::SMESH_Gen_ptr theComponentMesh,
211                              int                  theCommandID )
212   {
213     QStringList filter;
214     std::string myExtension;
215
216     if ( theCommandID == SMESHOp::OpImportMED ||
217          theCommandID == SMESHOp::OpPopupImportMED ) {
218       filter.append( QObject::tr( "MED_FILES_FILTER" ) + " (*.*med)" );
219       filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" );
220     }
221     else if ( theCommandID == SMESHOp::OpImportUNV ||
222               theCommandID == SMESHOp::OpPopupImportUNV ) {
223       filter.append( QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)" );
224     }
225     else if ( theCommandID == SMESHOp::OpImportDAT ||
226               theCommandID == SMESHOp::OpPopupImportDAT ) {
227       filter.append( QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)" );
228     }
229     else if ( theCommandID == SMESHOp::OpImportSTL ||
230               theCommandID == SMESHOp::OpPopupImportSTL ) {
231       filter.append( QObject::tr( "STL_FILES_FILTER" ) + " (*.stl)" );
232     }
233     else if ( theCommandID == SMESHOp::OpImportCGNS ||
234               theCommandID == SMESHOp::OpPopupImportCGNS ) {
235       filter.append( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" );
236     }
237     else if ( theCommandID == SMESHOp::OpImportSAUV ||
238               theCommandID == SMESHOp::OpPopupImportSAUV ) {
239       filter.append( QObject::tr( "SAUV_FILES_FILTER" ) + " (*.sauv *.sauve)" );
240       filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" );
241     }
242     else if ( theCommandID == SMESHOp::OpImportGMF ||
243               theCommandID == SMESHOp::OpPopupImportGMF ) {
244       filter.append( QObject::tr( "GMF_ASCII_FILES_FILTER" ) + " (*.mesh)"  );
245       filter.append( QObject::tr( "GMF_BINARY_FILES_FILTER") + " (*.meshb)" );
246     }
247
248     QString anInitialPath = "";
249     if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
250       anInitialPath = QDir::currentPath();
251
252     QStringList filenames;
253     bool toCreateGroups = true;
254
255     // if ( theCommandID == SMESHOp::OpImportGMF ) { // GMF
256     //   SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg
257     //     ( SMESHGUI::desktop(), true, QObject::tr("SMESH_REQUIRED_GROUPS"), true, true );
258     //   fd->setWindowTitle( QObject::tr( "SMESH_IMPORT_MESH" ) );
259     //   fd->setNameFilters( filter );
260     //   fd->SetChecked( true );
261     //   if ( fd->exec() )
262     //     filenames << fd->selectedFile();
263     //   toCreateGroups = fd->IsChecked();
264
265     //   delete fd;
266     // }
267     // else
268     {
269       filenames = SUIT_FileDlg::getOpenFileNames( SMESHGUI::desktop(),
270                                                   anInitialPath,
271                                                   filter,
272                                                   QObject::tr( "SMESH_IMPORT_MESH" ) );
273     }
274     if ( filenames.count() > 0 )
275     {
276       SUIT_OverrideCursor wc;
277       _PTR(Study) aStudy = SMESH::getStudy();
278
279       QStringList errors;
280       QStringList anEntryList;
281       bool isEmpty = false;
282       for ( QStringList::ConstIterator it = filenames.begin(); it != filenames.end(); ++it )
283       {
284         QString filename = *it;
285         SMESH::mesh_array_var aMeshes = new SMESH::mesh_array;
286         try {
287           switch ( theCommandID ) {
288           case SMESHOp::OpImportDAT:
289           case SMESHOp::OpPopupImportDAT:
290             {
291               // DAT format (currently unsupported)
292               errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
293                              arg( QObject::tr( "SMESH_ERR_NOT_SUPPORTED_FORMAT" ) ) );
294               break;
295             }
296           case SMESHOp::OpImportUNV:
297           case SMESHOp::OpPopupImportUNV:
298             {
299               // UNV format
300               aMeshes->length( 1 );
301               aMeshes[0] = theComponentMesh->CreateMeshesFromUNV( filename.toUtf8().constData() );
302               if ( aMeshes[0]->_is_nil() )
303                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
304                                arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
305               break;
306             }
307           case SMESHOp::OpImportMED:
308           case SMESHOp::OpPopupImportMED:
309             {
310               // MED format
311               SMESH::DriverMED_ReadStatus res;
312               aMeshes = theComponentMesh->CreateMeshesFromMED( filename.toUtf8().constData(), res );
313               if ( res != SMESH::DRS_OK ) {
314                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
315                                arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) );
316               }
317               break;
318             }
319           case SMESHOp::OpImportSTL:
320           case SMESHOp::OpPopupImportSTL:
321             {
322               // STL format
323               aMeshes->length( 1 );
324               aMeshes[0] = theComponentMesh->CreateMeshesFromSTL( filename.toUtf8().constData() );
325               if ( aMeshes[0]->_is_nil() ) {
326                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
327                                arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
328               }
329               break;
330             }
331           case SMESHOp::OpImportCGNS:
332           case SMESHOp::OpPopupImportCGNS:
333             {
334               // CGNS format
335               SMESH::DriverMED_ReadStatus res;
336               aMeshes = theComponentMesh->CreateMeshesFromCGNS( filename.toUtf8().constData(), res );
337               if ( res != SMESH::DRS_OK ) {
338                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
339                                arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) );
340               }
341               break;
342             }
343           case SMESHOp::OpImportSAUV:
344           case SMESHOp::OpPopupImportSAUV:
345             {
346               // SAUV format
347               SMESH::DriverMED_ReadStatus res;
348               aMeshes = theComponentMesh->CreateMeshesFromSAUV( filename.toUtf8().constData(), res );
349               if ( res != SMESH::DRS_OK ) {
350                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
351                                arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) );
352               }
353               break;
354             }
355           case SMESHOp::OpImportGMF:
356           case SMESHOp::OpPopupImportGMF:
357             {
358               // GMF format
359               SMESH::ComputeError_var res;
360               aMeshes->length( 1 );
361               aMeshes[0] = theComponentMesh->CreateMeshesFromGMF( filename.toUtf8().constData(),
362                                                                   toCreateGroups,
363                                                                   res.out() );
364               if ( res->code != SMESH::DRS_OK ) {
365                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
366                                arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res->code ).toLatin1().data() ) ) );
367                 if ( strlen( res->comment.in() ) > 0 ) {
368                   errors.back() += ": ";
369                   errors.back() += res->comment.in();
370                 }
371               }
372               break;
373             }
374           }
375         }
376         catch ( const SALOME::SALOME_Exception& S_ex ) {
377           errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
378                          arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
379         }
380
381         for ( int i = 0, iEnd = aMeshes->length(); i < iEnd; i++ )
382         {
383           _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[i] );
384           if ( aMeshSO ) {
385             _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
386             _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" );
387             aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" );
388             if ( theCommandID == SMESHOp::OpImportUNV ) // mesh names aren't taken from the file for UNV import
389               SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() );
390
391             anEntryList.append( aMeshSO->GetID().c_str() );
392           }
393           else {
394             isEmpty = true;
395           }
396         }
397       }
398
399       // update Object browser
400       SMESHGUI::GetSMESHGUI()->updateObjBrowser();
401
402       // browse to the published meshes
403       if( LightApp_Application* anApp =
404           dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
405         anApp->browseObjects( anEntryList );
406
407       // show Error message box if there were errors
408       if ( errors.count() > 0 ) {
409         SUIT_MessageBox::critical( SMESHGUI::desktop(),
410                                    QObject::tr( "SMESH_ERROR" ),
411                                    QObject::tr( "SMESH_IMPORT_ERRORS" ) + "\n" + errors.join( "\n" ) );
412       }
413
414       // show warning message box, if some imported mesh is empty
415       if ( isEmpty ) {
416           SUIT_MessageBox::warning( SMESHGUI::desktop(),
417                                     QObject::tr( "SMESH_WRN_WARNING" ),
418                                     QObject::tr( "SMESH_DRS_SOME_EMPTY" ) );
419       }
420     }
421   }
422
423   //================================================================================
424   /*!
425    * \brief Export selected meshes or groups into a file
426    */
427   //================================================================================
428
429   void ExportMeshToFile( int theCommandID )
430   {
431     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
432     SALOME_ListIO selected;
433     if( aSel )
434       aSel->selectedObjects( selected );
435
436     const bool isDAT = ( theCommandID == SMESHOp::OpExportDAT ||
437                          theCommandID == SMESHOp::OpPopupExportDAT );
438     const bool isMED = ( theCommandID == SMESHOp::OpExportMED ||
439                          theCommandID == SMESHOp::OpPopupExportMED );
440     const bool isUNV = ( theCommandID == SMESHOp::OpExportUNV ||
441                          theCommandID == SMESHOp::OpPopupExportUNV );
442     const bool isSTL = ( theCommandID == SMESHOp::OpExportSTL ||
443                          theCommandID == SMESHOp::OpPopupExportSTL );
444     const bool isCGNS= ( theCommandID == SMESHOp::OpExportCGNS ||
445                          theCommandID == SMESHOp::OpPopupExportCGNS );
446     const bool isSAUV= ( theCommandID == SMESHOp::OpExportSAUV ||
447                          theCommandID == SMESHOp::OpPopupExportSAUV );
448     const bool isGMF = ( theCommandID == SMESHOp::OpExportGMF ||
449                          theCommandID == SMESHOp::OpPopupExportGMF );
450
451     const bool multiMeshSupported = ( isMED || isCGNS ); // file can hold several meshes
452     if ( selected.Extent() == 0 || ( selected.Extent() > 1 && !multiMeshSupported ))
453       return;
454     SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
455     bool aCheckWarn = true;
456     if ( resMgr )
457       aCheckWarn = resMgr->booleanValue( "SMESH", "show_warning", false );
458     // get mesh object from selection and check duplication of their names
459     bool hasDuplicatedMeshNames = false;
460     QList< QPair< SMESH::SMESH_IDSource_var, QString > >           aMeshList;
461     QList< QPair< SMESH::SMESH_IDSource_var, QString > >::iterator aMeshIter;
462     SALOME_ListIteratorOfListIO It( selected );
463     for( ; It.More(); It.Next() )
464     {
465       Handle(SALOME_InteractiveObject) anIObject = It.Value();
466       SMESH::SMESH_IDSource_var aMeshItem =
467         SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(anIObject);
468       if ( aMeshItem->_is_nil() ) {
469         SUIT_MessageBox::warning( SMESHGUI::desktop(),
470                                   QObject::tr( "SMESH_WRN_WARNING" ),
471                                   QObject::tr( "SMESH_BAD_MESH_SELECTION" ));
472         return;
473       }
474       SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( aMeshItem );
475       if ( aCheckWarn && !aGroup->_is_nil() )
476       {
477         QMessageBox msgBox(SUIT_MessageBox::Warning,
478                            QObject::tr("SMESH_WRN_WARNING"),
479                            QObject::tr("SMESH_EXPORT_ONLY_GPOUP"),
480                            QMessageBox::StandardButton::NoButton,
481                            SMESHGUI::desktop());
482         QCheckBox dontShowCheckBox(QObject::tr("SMESH_WRN_SHOW_DLG_CHECKBOX"));
483         msgBox.addButton(QMessageBox::Ok);
484         msgBox.addButton(QMessageBox::Cancel);
485         msgBox.setDefaultButton(QMessageBox::Cancel);
486         QGridLayout* lt = qobject_cast<QGridLayout*>(msgBox.layout());
487         QDialogButtonBox* btnbox = msgBox.findChild<QDialogButtonBox*>();
488         lt->addWidget(&dontShowCheckBox, lt->rowCount(), lt->columnCount()-1, lt->rowCount(), lt->columnCount());
489         lt->addWidget(btnbox, lt->rowCount(), 0, lt->rowCount(), lt->columnCount());
490         if ( msgBox.exec() != QMessageBox::Ok )
491           return;
492
493         if ( dontShowCheckBox.checkState() == Qt::Checked && resMgr )
494           resMgr->setValue( "SMESH", "show_warning", false);
495       }
496
497       QString aMeshName = anIObject->getName();
498
499       // check for name duplications
500       if ( !hasDuplicatedMeshNames )
501         for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) {
502           if( aMeshName == (*aMeshIter).second ) {
503             hasDuplicatedMeshNames = true;
504             break;
505           }
506         }
507
508       aMeshList.append( QPair< SMESH::SMESH_IDSource_var, QString >( aMeshItem, aMeshName ) );
509     }
510
511     if( hasDuplicatedMeshNames && isMED ) {
512       int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(),
513                                           QObject::tr("SMESH_WRN_WARNING"),
514                                           QObject::tr("SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES"),
515                                           QObject::tr("SMESH_BUT_YES"),
516                                           QObject::tr("SMESH_BUT_NO"), 0, 1);
517       if (aRet != 0)
518         return;
519     }
520
521     aMeshIter = aMeshList.begin();
522     SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first;
523     SMESH::SMESH_Mesh_var            aMesh = aMeshOrGroup->GetMesh();
524     QString                      aMeshName = (*aMeshIter).second;
525
526     if ( isMED || isCGNS || isSAUV ) // formats where group names must be unique
527     {
528       // check for equal group names within each mesh
529       for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) {
530         SMESH::SMESH_Mesh_var aMeshItem = SMESH::SMESH_Mesh::_narrow( (*aMeshIter).first );
531         if ( !aMeshItem->_is_nil() && aMeshItem->HasDuplicatedGroupNamesMED()) {
532           int aRet = SUIT_MessageBox::warning
533             (SMESHGUI::desktop(),
534              QObject::tr("SMESH_WRN_WARNING"),
535              QObject::tr("SMESH_EXPORT_MED_DUPLICATED_GRP").arg((*aMeshIter).second),
536              QObject::tr("SMESH_BUT_YES"),
537              QObject::tr("SMESH_BUT_NO"), 0, 1);
538           if (aRet != 0)
539             return;
540         }
541       }
542     }
543
544     // Warn the user about presence of not supported elements
545     QString format;
546     std::vector< SMESH::EntityType > notSupportedElemTypes, presentNotSupported;
547     if ( isDAT )
548     {
549       format = "DAT";
550       notSupportedElemTypes.push_back( SMESH::Entity_0D );
551       notSupportedElemTypes.push_back( SMESH::Entity_Ball );
552     }
553     else if ( isUNV )
554     {
555       format = "UNV";
556       notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
557       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
558       notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
559       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polyhedra );
560       notSupportedElemTypes.push_back( SMESH::Entity_Pyramid );
561       notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
562       notSupportedElemTypes.push_back( SMESH::Entity_0D );
563       notSupportedElemTypes.push_back( SMESH::Entity_Ball );
564     }
565     else if ( isSTL )
566     {
567       format = "STL";
568       notSupportedElemTypes.push_back( SMESH::Entity_Edge );
569       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Edge );
570       notSupportedElemTypes.push_back( SMESH::Entity_0D );
571       notSupportedElemTypes.push_back( SMESH::Entity_Ball );
572     }
573     else if ( isCGNS )
574     {
575       format = "CGNS";
576       notSupportedElemTypes.push_back( SMESH::Entity_Ball );
577     }
578     else if ( isSAUV )
579     {
580       format = "SAUV";
581       notSupportedElemTypes.push_back( SMESH::Entity_Ball );
582       notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Triangle );
583       notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Quadrangle );
584       notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa );
585       notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
586       notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
587       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
588       notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
589     }
590     else if ( isGMF )
591     {
592       format = "GMF";
593       notSupportedElemTypes.push_back( SMESH::Entity_0D );
594       notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
595       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
596       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Pyramid );
597       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Penta );
598       notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Penta );
599       notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
600       notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
601       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polyhedra );
602       notSupportedElemTypes.push_back( SMESH::Entity_Ball );
603     }
604     if ( ! notSupportedElemTypes.empty() )
605     {
606       SMESH::long_array_var nbElems = aMeshOrGroup->GetMeshInfo();
607       for ( size_t iType = 0; iType < notSupportedElemTypes.size(); ++iType )
608         if ( nbElems[ notSupportedElemTypes[ iType ]] > 0 )
609           presentNotSupported.push_back( notSupportedElemTypes[ iType ]);
610     }
611     if ( !presentNotSupported.empty() )
612     {
613       QString typeNames;
614       const char* typeMsg[] = {
615         "SMESH_NODES", "SMESH_ELEMS0D","SMESH_EDGES","SMESH_QUADRATIC_EDGES",
616         "SMESH_TRIANGLES", "SMESH_QUADRATIC_TRIANGLES", "SMESH_BIQUADRATIC_TRIANGLES",
617         "SMESH_QUADRANGLES","SMESH_QUADRATIC_QUADRANGLES", "SMESH_BIQUADRATIC_QUADRANGLES",
618         "SMESH_POLYGONS","SMESH_QUADRATIC_POLYGONS",
619         "SMESH_TETRAHEDRA","SMESH_QUADRATIC_TETRAHEDRONS","SMESH_PYRAMIDS",
620         "SMESH_QUADRATIC_PYRAMIDS","SMESH_HEXAHEDRA","SMESH_QUADRATIC_HEXAHEDRONS",
621         "SMESH_TRIQUADRATIC_HEXAHEDRONS","SMESH_PENTAHEDRA","SMESH_QUADRATIC_PENTAHEDRONS",
622         "SMESH_BIQUADRATIC_PENTAHEDRONS",
623         "SMESH_OCTAHEDRA","SMESH_POLYEDRONS","SMESH_QUADRATIC_POLYEDRONS","SMESH_BALLS"
624       };
625       // is typeMsg complete? (compilation failure mains that enum SMDSAbs_EntityType changed)
626       const int nbTypes = sizeof( typeMsg ) / sizeof( const char* );
627       int _assert[( nbTypes == SMESH::Entity_Last ) ? 2 : -1 ]; _assert[0]=_assert[1]=0;
628
629       QString andStr = " " + QObject::tr("SMESH_AND") + " ", comma(", ");
630       for ( size_t iType = 0; iType < presentNotSupported.size(); ++iType ) {
631         typeNames += QObject::tr( typeMsg[ presentNotSupported[ iType ]]);
632         if ( iType != presentNotSupported.size() - 1 )
633           typeNames += ( iType == presentNotSupported.size() - 2 ) ? andStr : comma;
634       }
635       int aRet = SUIT_MessageBox::warning
636         (SMESHGUI::desktop(),
637          QObject::tr("SMESH_WRN_WARNING"),
638          QObject::tr("EXPORT_NOT_SUPPORTED").arg(aMeshName).arg(format).arg(typeNames),
639          QObject::tr("SMESH_BUT_YES"),
640          QObject::tr("SMESH_BUT_NO"), 0, 1);
641       if (aRet != 0)
642         return;
643     }
644
645     // Get parameters of export operation
646
647     QString aFilename;
648     int aFormat =-1;         // for MED version used for write
649     bool isOkToWrite = true; // to check MED file version compatibility before adding a mesh in an existing file
650
651     // Init the parameters with the default values
652     bool aIsASCII_STL   = true;
653     bool toCreateGroups = false;
654     if ( resMgr )
655       toCreateGroups = resMgr->booleanValue( "SMESH", "auto_groups", false );
656     bool toOverwrite  = true;
657     bool toFindOutDim = true;
658     double       zTol = resMgr ? resMgr->doubleValue( "SMESH", "med_ztolerance", 0. ) : 0.;
659
660     QString aFilter, aTitle = QObject::tr("SMESH_EXPORT_MESH");
661     QString anInitialPath = "";
662     if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
663       anInitialPath = QDir::currentPath();
664
665     QList< QPair< GEOM::ListOfFields_var, QString > > aFieldList;
666
667     // Get a file name to write in and additional options
668     if ( isUNV || isDAT || isGMF ) // Export w/o options
669     {
670       if ( isUNV )
671         aFilter = QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)";
672       else if ( isDAT )
673         aFilter = QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)";
674       else if ( isGMF )
675         aFilter = QObject::tr( "GMF_ASCII_FILES_FILTER" ) + " (*.mesh)" +
676           ";;" +  QObject::tr( "GMF_BINARY_FILES_FILTER" )  + " (*.meshb)";
677      if ( anInitialPath.isEmpty() ) anInitialPath = SUIT_FileDlg::getLastVisitedPath();
678       aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(),
679                                             anInitialPath + QString("/") + aMeshName,
680                                             aFilter, aTitle, false);
681     }
682     else if ( isCGNS )// Export to CGNS
683     {
684       const char* theByTypeResource = "cgns_group_elems_by_type";
685       toCreateGroups = SMESHGUI::resourceMgr()->booleanValue( "SMESH", theByTypeResource, false );
686
687       QStringList checkBoxes;
688       checkBoxes << QObject::tr("CGNS_EXPORT_ELEMS_BY_TYPE");
689
690       SalomeApp_CheckFileDlg* fd =
691         new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, checkBoxes, true, true );
692       fd->setWindowTitle( aTitle );
693       fd->setNameFilter( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" );
694       if ( !anInitialPath.isEmpty() )
695         fd->setDirectory( anInitialPath );
696       fd->selectFile(aMeshName);
697       SMESHGUI_FileValidator* fv = new SMESHGUI_FileValidator( fd );
698       fd->setValidator( fv );
699       fd->SetChecked( toCreateGroups, 0 );
700
701       if ( fd->exec() )
702         aFilename = fd->selectedFile();
703       toOverwrite    = fv->isOverwrite(aFilename);
704       toCreateGroups = fd->IsChecked(0);
705       SMESHGUI::resourceMgr()->setValue("SMESH", theByTypeResource, toCreateGroups );
706
707       delete fd;
708     }
709     else if ( isSTL ) // Export to STL
710     {
711       QMap<QString, int> aFilterMap;
712       aFilterMap.insert( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)", 1 );
713       aFilterMap.insert( QObject::tr( "STL_BIN_FILES_FILTER" )   + " (*.stl)", 0 );
714
715       QStringList filters;
716       QMap<QString, int>::const_iterator it = aFilterMap.begin();
717       for ( ; it != aFilterMap.end(); ++it )
718         filters.push_back( it.key() );
719
720       SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true );
721       fd->setWindowTitle( aTitle );
722       fd->setNameFilters( filters );
723       fd->selectNameFilter( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)" );
724       if ( !anInitialPath.isEmpty() )
725         fd->setDirectory( anInitialPath );
726       fd->selectFile(aMeshName);
727       bool is_ok = false;
728       while (!is_ok) {
729         if ( fd->exec() )
730           aFilename = fd->selectedFile();
731         aIsASCII_STL = (aFilterMap[fd->selectedNameFilter()]) == 1 ? true: false;
732         is_ok = true;
733       }
734       delete fd;
735     }
736     else if ( isMED || isSAUV ) // Export to MED or SAUV
737     {
738       int defaultVersion = 0;
739       QMap<QString, int> aFilterMap;
740       if ( isMED ) {
741         //filters << QObject::tr( "MED_FILES_FILTER" ) + " (*.med)";
742         //QString vmed (aMesh->GetVersionString(-1, 2));
743         SMESH::long_array_var mvok = aMesh->GetMEDVersionsCompatibleForAppend();
744         if ( mvok->length() > 0)
745           defaultVersion = mvok[0]; // the current version to set the default filter on it
746         for ( CORBA::ULong i = 0; i < mvok->length(); ++i )
747         {
748           QString vs = (char*)( SMESH_Comment( mvok[i]/10 ) << "." << mvok[i]%10 );
749           MESSAGE("MED version: " << vs.toStdString());
750           aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( vs ) + " (*.med)",  mvok[i]);
751         }
752       }
753       else { // isSAUV
754         aFilterMap.insert("All files (*)", -1 );
755         aFilterMap.insert("SAUV files (*.sauv)", defaultVersion ); // 0 = default filter (defaultVersion)
756         aFilterMap.insert("SAUV files (*.sauve)", -1 );
757       }
758       QStringList filters;
759       QMap<QString, int>::const_iterator it = aFilterMap.begin();
760       QString aDefaultFilter = it.key();
761       for ( ; it != aFilterMap.end(); ++it ) {
762         filters.push_back( it.key() );
763         if (it.value() == defaultVersion) // explicit default for MED = current MED version
764           aDefaultFilter = it.key();
765       }
766       QStringList checkBoxes;
767       checkBoxes << QObject::tr("SMESH_AUTO_GROUPS") << QObject::tr("SMESH_AUTO_DIM");
768
769       SMESHGUI_FieldSelectorWdg* fieldSelWdg = new SMESHGUI_FieldSelectorWdg();
770       QList< QWidget* > wdgList;
771       if ( fieldSelWdg->GetAllFields( aMeshList, aFieldList ))
772         wdgList.append( fieldSelWdg );
773
774       QWidget*           zTolWdg = new QWidget();
775       QCheckBox*       zTolCheck = new QCheckBox( QObject::tr( "SMESH_ZTOLERANCE" ), zTolWdg );
776       SMESHGUI_SpinBox* zTolSpin = new SMESHGUI_SpinBox( zTolWdg );
777       QHBoxLayout*    zTolLayout = new QHBoxLayout( zTolWdg );
778       zTolLayout->addWidget( zTolCheck );
779       zTolLayout->addWidget( zTolSpin );
780       zTolLayout->setMargin( 0 );
781       zTolSpin->RangeStepAndValidator( 0, 1e+100, 1., "length_precision" );
782       zTolSpin->setValue( zTol );
783       QObject::connect( zTolCheck, SIGNAL( toggled(bool)), zTolSpin, SLOT( setEnabled(bool)));
784       zTolCheck->setChecked( resMgr->booleanValue( "SMESH", "enable_ztolerance", false ));
785       zTolSpin ->setEnabled( zTolCheck->isChecked() );
786       wdgList.append( zTolWdg );
787
788       SalomeApp_CheckFileDlg* fd =
789         new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, checkBoxes, true, true, wdgList );
790       fd->setWindowTitle( aTitle );
791       fd->setNameFilters( filters );
792       fd->selectNameFilter( aDefaultFilter );
793       fd->SetChecked( toCreateGroups, 0 );
794       fd->SetChecked( toFindOutDim,   1 );
795       if ( !anInitialPath.isEmpty() )
796         fd->setDirectory( anInitialPath );
797       fd->selectFile(aMeshName);
798
799
800       QListView *lview = fd->findChild<QListView*>("listView");
801       if( lview ) {
802         lview->setMinimumHeight(200);
803       }
804       QTreeView *tview = fd->findChild<QTreeView*>("treeView");
805       if( tview ) {
806         tview->setMinimumHeight(200);
807       }
808
809       SMESHGUI_FileValidator* fv = new SMESHGUI_FileValidator( fd );
810       fd->setValidator( fv );
811
812       bool is_ok = false;
813       while (!is_ok)
814       {
815         //MESSAGE("******* Loop on file dialog ***********");
816         isOkToWrite =true;
817         if ( fd->exec() )
818           aFilename = fd->selectedFile();
819         else {
820           aFilename = QString::null;
821           break;
822         }
823         aFormat = aFilterMap[fd->selectedNameFilter()];
824         //MESSAGE("selected version: " << aFormat << " file: " << aFilename.toUtf8().constData());
825         toOverwrite = fv->isOverwrite(aFilename);
826         //MESSAGE("toOverwrite:" << toOverwrite);
827         is_ok = true;
828         if ( !aFilename.isEmpty() ) {
829           if( !toOverwrite ) {
830             // append is only possible if the existing file format is compatible
831             bool isVersionOk = SMESHGUI::GetSMESHGen()->CheckWriteCompatibility( aFilename.toUtf8().constData() );
832             MESSAGE("Append check, isVersionOk:" << isVersionOk);
833             if ( !isVersionOk ) {
834               int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(),
835                                                   QObject::tr("SMESH_WRN_WARNING"),
836                                                   QObject::tr("SMESH_EXPORT_MED_VERSION_COLLISION").arg(aFilename),
837                                                   QObject::tr("SMESH_BUT_YES"),
838                                                   QObject::tr("SMESH_BUT_NO"), 0, 1);
839               if (aRet == 0)
840               {
841                 toOverwrite = true;
842                 //MESSAGE("incompatible MED file version for add, overwrite accepted");
843               }
844               else
845               {
846                 isOkToWrite = false;
847                 is_ok = false;
848                 //MESSAGE("incompatible MED file version for add, overwrite refused");
849               }
850             }
851             QStringList aMeshNamesCollisionList;
852             SMESH::string_array_var aMeshNames = SMESHGUI::GetSMESHGen()->GetMeshNames( aFilename.toUtf8().constData() );
853             for( int i = 0, n = aMeshNames->length(); i < n; i++ ) {
854               QString anExistingMeshName( aMeshNames[ i ] );
855               for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) {
856                 QString anExportMeshName = (*aMeshIter).second;
857                 if( anExportMeshName == anExistingMeshName ) {
858                   aMeshNamesCollisionList.append( anExportMeshName );
859                   break;
860                 }
861               }
862             }
863             if( !aMeshNamesCollisionList.isEmpty() ) {
864               isOkToWrite = false;
865               QString aMeshNamesCollisionString = aMeshNamesCollisionList.join( ", " );
866               int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(),
867                                                   QObject::tr("SMESH_WRN_WARNING"),
868                                                   QObject::tr("SMESH_EXPORT_MED_MESH_NAMES_COLLISION").arg(aMeshNamesCollisionString),
869                                                   QObject::tr("SMESH_BUT_YES"),
870                                                   QObject::tr("SMESH_BUT_NO"),
871                                                   QObject::tr("SMESH_BUT_CANCEL"), 0, 2);
872               MESSAGE("answer collision name " << aRet);
873               if (aRet == 0) {
874                 toOverwrite = true;
875                 isOkToWrite = true;
876               }
877               else if (aRet == 2)
878                 is_ok = false;
879             }
880           }
881         }
882       }
883       toCreateGroups = fd->IsChecked(0);
884       toFindOutDim   = fd->IsChecked(1);
885       zTol           = zTolCheck->isChecked() ? zTolSpin->value() : -1;
886       fieldSelWdg->GetSelectedFields();
887       if ( resMgr ) resMgr->setValue( "SMESH", "enable_ztolerance", zTolCheck->isChecked() );
888
889       if ( !fieldSelWdg->parent() )
890         delete fieldSelWdg;
891       if ( !zTolWdg->parent() )
892         delete zTolWdg;
893       delete fd;
894     }
895     else
896     {
897       return;
898     }
899
900     // Perform export
901
902     if ( !aFilename.isEmpty() ) {
903       // Check whether the file already exists and delete it if yes
904       QFile aFile( aFilename );
905       if ( aFile.exists() && toOverwrite )
906         aFile.remove();
907       SUIT_OverrideCursor wc;
908
909       try {
910         // Renumbering is not needed since SMDS redesign in V6.2.0 (Nov 2010)
911         //         bool Renumber = false;
912         //         // PAL 14172  : Check of we have to renumber or not from the preferences before export
913         //         if (resMgr)
914         //           Renumber= resMgr->booleanValue("renumbering");
915         //         if (Renumber){
916         //           SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
917 //           aMeshEditor->RenumberNodes();
918 //           aMeshEditor->RenumberElements();
919 //           if ( SMESHGUI::automaticUpdate() )
920 //             SMESH::UpdateView();
921 //         }
922         if ( isMED && isOkToWrite)
923         {
924           MESSAGE("OK to write MED file "<< aFilename.toUtf8().constData());
925           aMeshIter = aMeshList.begin();
926           for( int aMeshIndex = 0; aMeshIter != aMeshList.end(); aMeshIter++, aMeshIndex++ )
927           {
928             SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first;
929             SMESH::SMESH_Mesh_var        aMeshItem = aMeshOrGroup->GetMesh();
930             const GEOM::ListOfFields&       fields = aFieldList[ aMeshIndex ].first.in();
931             const QString&            geoAssFields = aFieldList[ aMeshIndex ].second;
932             const bool                   hasFields = ( fields.length() || !geoAssFields.isEmpty() );
933             if ( !hasFields && aMeshOrGroup->_is_equivalent( aMeshItem ) && zTol < 0 )
934               aMeshItem->ExportMED( aFilename.toUtf8().data(), toCreateGroups, aFormat,
935                                     toOverwrite && aMeshIndex == 0, toFindOutDim );
936             else
937               aMeshItem->ExportPartToMED( aMeshOrGroup, aFilename.toUtf8().data(),
938                                           toCreateGroups, aFormat,
939                                           toOverwrite && aMeshIndex == 0, toFindOutDim,
940                                           fields, geoAssFields.toLatin1().data(), zTol );
941           }
942         }
943         else if ( isSAUV )
944         {
945           for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ )
946           {
947             SMESH::SMESH_Mesh_var aMeshItem = SMESH::SMESH_Mesh::_narrow( (*aMeshIter).first );
948             if( !aMeshItem->_is_nil() )
949               aMeshItem->ExportSAUV( aFilename.toUtf8().data(), toCreateGroups );
950           }
951         }
952         else if ( isDAT )
953         {
954           if ( aMeshOrGroup->_is_equivalent( aMesh ))
955             aMesh->ExportDAT( aFilename.toUtf8().data() );
956           else
957             aMesh->ExportPartToDAT( aMeshOrGroup, aFilename.toUtf8().data() );
958         }
959         else if ( isUNV )
960         {
961           if ( aMeshOrGroup->_is_equivalent( aMesh ))
962             aMesh->ExportUNV( aFilename.toUtf8().data() );
963           else
964             aMesh->ExportPartToUNV( aMeshOrGroup, aFilename.toUtf8().data() );
965         }
966         else if ( isSTL )
967         {
968           if ( aMeshOrGroup->_is_equivalent( aMesh ))
969             aMesh->ExportSTL( aFilename.toUtf8().data(), aIsASCII_STL );
970           else
971             aMesh->ExportPartToSTL( aMeshOrGroup, aFilename.toUtf8().data(), aIsASCII_STL );
972         }
973         else if ( isCGNS )
974         {
975           aMeshIter = aMeshList.begin();
976           for( int aMeshIndex = 0; aMeshIter != aMeshList.end(); aMeshIter++, aMeshIndex++ )
977           {
978             SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first;
979             SMESH::SMESH_Mesh_var        aMeshItem = aMeshOrGroup->GetMesh();
980             aMeshItem->ExportCGNS( aMeshOrGroup,
981                                    aFilename.toUtf8().data(),
982                                    toOverwrite && aMeshIndex == 0,
983                                    toCreateGroups );
984           }
985         }
986         else if ( isGMF )
987         {
988           toCreateGroups = true;
989           aMesh->ExportGMF( aMeshOrGroup, aFilename.toUtf8().data(), toCreateGroups );
990         }
991       }
992       catch (const SALOME::SALOME_Exception& S_ex){
993         wc.suspend();
994         SUIT_MessageBox::warning(SMESHGUI::desktop(),
995                                  QObject::tr("SMESH_WRN_WARNING"),
996                                  QObject::tr("SMESH_EXPORT_FAILED") + SalomeApp_Tools::ExceptionToString(S_ex));
997         wc.resume();
998       }
999     }
1000   }
1001
1002   inline void InverseEntityMode(unsigned int& theOutputMode,
1003                                 unsigned int  theMode)
1004   {
1005     bool anIsNotPresent = ~theOutputMode & theMode;
1006     if(anIsNotPresent)
1007       theOutputMode |= theMode;
1008     else
1009       theOutputMode &= ~theMode;
1010   }
1011
1012   void SetDisplayEntity(int theCommandID)
1013   {
1014     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
1015     SALOME_ListIO selected;
1016     if ( aSel )
1017       aSel->selectedObjects( selected );
1018
1019     if ( selected.Extent() >= 1 ) {
1020       SUIT_OverrideCursor wc;
1021       SALOME_ListIteratorOfListIO It( selected );
1022       for( ; It.More(); It.Next()){
1023         Handle(SALOME_InteractiveObject) IObject = It.Value();
1024         if(IObject->hasEntry()){
1025           if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
1026             unsigned int aMode = anActor->GetEntityMode();
1027             switch(theCommandID){
1028             case SMESHOp::OpDE0DElements: InverseEntityMode(aMode,SMESH_Actor::e0DElements); break;
1029             case SMESHOp::OpDEEdges:      InverseEntityMode(aMode,SMESH_Actor::eEdges); break;
1030             case SMESHOp::OpDEFaces:      InverseEntityMode(aMode,SMESH_Actor::eFaces); break;
1031             case SMESHOp::OpDEVolumes:    InverseEntityMode(aMode,SMESH_Actor::eVolumes); break;
1032             case SMESHOp::OpDEBalls:      InverseEntityMode(aMode,SMESH_Actor::eBallElem); break;
1033             case SMESHOp::OpDEAllEntity:  aMode = SMESH_Actor::eAllEntity; break;
1034             }
1035             if(aMode)
1036               anActor->SetEntityMode(aMode);
1037           }
1038         }
1039       }
1040     }
1041   }
1042
1043   void AutoColor()
1044   {
1045     SalomeApp_Application* app =
1046       dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
1047     if ( !app )
1048       return;
1049
1050     LightApp_SelectionMgr* aSel = app->selectionMgr();
1051     SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
1052     if ( !aSel || !appStudy )
1053       return;
1054
1055     SALOME_ListIO selected;
1056     aSel->selectedObjects( selected );
1057     if ( selected.IsEmpty() )
1058       return;
1059
1060     Handle(SALOME_InteractiveObject) anIObject = selected.First();
1061
1062     _PTR(Study)         aStudy = appStudy->studyDS();
1063     _PTR(SObject) aMainSObject = aStudy->FindObjectID( anIObject->getEntry() );
1064     SMESH::SMESH_Mesh_var aMainObject = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(anIObject);
1065     if ( aMainObject->_is_nil() )
1066       return;
1067
1068     SUIT_OverrideCursor wc;
1069
1070     aMainObject->SetAutoColor( true ); // mesh groups are re-colored here
1071
1072     QList<SALOMEDS::Color> aReservedColors;
1073
1074     SMESH::ListOfGroups aListOfGroups = *aMainObject->GetGroups();
1075     for ( int i = 0, n = aListOfGroups.length(); i < n; i++ )
1076     {
1077       SMESH::SMESH_GroupBase_var aGroupObject = aListOfGroups[i];
1078
1079 #ifdef SIMPLE_AUTOCOLOR   // simplified algorithm for auto-colors
1080       SALOMEDS::Color aColor = SMESHGUI::getPredefinedUniqueColor();
1081 #else                     // old algorithm  for auto-colors
1082       SALOMEDS::Color aColor = SMESHGUI::getUniqueColor( aReservedColors );
1083       aReservedColors.append( aColor );
1084 #endif                    // SIMPLE_AUTOCOLOR
1085       aGroupObject->SetColor( aColor );
1086
1087       _PTR(SObject) aGroupSObject = SMESH::FindSObject(aGroupObject);
1088       if ( aGroupSObject ) {
1089         QColor c;
1090         int delta;
1091         if ( SMESH_Actor *anActor = SMESH::FindActorByEntry(aGroupSObject->GetID().c_str())) {
1092           switch ( aGroupObject->GetType ()) {
1093           case SMESH::NODE:
1094             anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); break;
1095           case SMESH::EDGE:
1096             anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); break;
1097           case SMESH::ELEM0D:
1098             anActor->Set0DColor( aColor.R, aColor.G, aColor.B ); break;
1099           case SMESH::BALL:
1100             anActor->SetBallColor( aColor.R, aColor.G, aColor.B ); break;
1101           case SMESH::VOLUME:
1102             SMESH::GetColor("SMESH", "volume_color", c, delta, "255,0,170|-100");
1103             anActor->SetVolumeColor( aColor.R, aColor.G, aColor.B, delta ); break;
1104           case SMESH::FACE:
1105           default:
1106             SMESH::GetColor("SMESH", "fill_color", c, delta, "0,170,255|-100");
1107             anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta );
1108           }
1109         }
1110       }
1111     }
1112
1113     SMESH::RepaintCurrentView();
1114   }
1115
1116   void OverallMeshQuality()
1117   {
1118     SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
1119     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
1120     SALOME_ListIO selected;
1121     if( aSel )
1122       aSel->selectedObjects( selected );
1123
1124     if ( selected.IsEmpty() ) return;
1125     SALOME_ListIteratorOfListIO It( selected );
1126     for ( ; It.More(); It.Next() ) {
1127       SMESHGUI_CtrlInfoDlg* ctrlDlg = new SMESHGUI_CtrlInfoDlg( SMESHGUI::desktop() );
1128       ctrlDlg->showInfo( It.Value() );
1129       ctrlDlg->show();
1130     }
1131   }
1132
1133   QString functorToString( SMESH::Controls::FunctorPtr f )
1134   {
1135     QString type = QObject::tr( "UNKNOWN_CONTROL" );
1136     if ( dynamic_cast< SMESH::Controls::Volume* >( f.get() ) )
1137       type = QObject::tr( "VOLUME_3D_ELEMENTS" );
1138     else if ( dynamic_cast< SMESH::Controls::MaxElementLength2D* >( f.get() ) )
1139       type = QObject::tr( "MAX_ELEMENT_LENGTH_2D" );
1140     else if ( dynamic_cast< SMESH::Controls::MaxElementLength3D* >( f.get() ) )
1141       type = QObject::tr( "MAX_ELEMENT_LENGTH_3D" );
1142     else if ( dynamic_cast< SMESH::Controls::MinimumAngle* >( f.get() ) )
1143       type = QObject::tr( "MINIMUMANGLE_ELEMENTS" );
1144     else if ( dynamic_cast< SMESH::Controls::AspectRatio* >( f.get() ) )
1145       type = QObject::tr( "ASPECTRATIO_ELEMENTS" );
1146     else if ( dynamic_cast< SMESH::Controls::AspectRatio3D* >( f.get() ) )
1147       type = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" );
1148     else if ( dynamic_cast< SMESH::Controls::Warping* >( f.get() ) )
1149       type = QObject::tr( "WARP_ELEMENTS" );
1150     else if ( dynamic_cast< SMESH::Controls::Taper* >( f.get() ) )
1151       type = QObject::tr( "TAPER_ELEMENTS" );
1152     else if ( dynamic_cast< SMESH::Controls::Skew* >( f.get() ) )
1153       type = QObject::tr( "SKEW_ELEMENTS" );
1154     else if ( dynamic_cast< SMESH::Controls::Area* >( f.get() ) )
1155       type = QObject::tr( "AREA_ELEMENTS" );
1156     else if ( dynamic_cast< SMESH::Controls::Length* >( f.get() ) )
1157       type = QObject::tr( "LENGTH_EDGES" );
1158     else if ( dynamic_cast< SMESH::Controls::Length2D* >( f.get() ) )
1159       type = QObject::tr( "LENGTH2D_EDGES" );
1160     else if ( dynamic_cast< SMESH::Controls::Deflection2D* >( f.get() ) )
1161       type = QObject::tr( "DEFLECTION2D_FACES" );
1162     else if ( dynamic_cast< SMESH::Controls::MultiConnection* >( f.get() ) )
1163       type = QObject::tr( "MULTI_BORDERS" );
1164     else if ( dynamic_cast< SMESH::Controls::MultiConnection2D* >( f.get() ) )
1165       type = QObject::tr( "MULTI2D_BORDERS" );
1166     else if ( dynamic_cast< SMESH::Controls::FreeNodes* >( f.get() ) )
1167       type = QObject::tr( "FREE_NODES" );
1168     else if ( dynamic_cast< SMESH::Controls::FreeEdges* >( f.get() ) )
1169       type = QObject::tr( "FREE_EDGES" );
1170     else if ( dynamic_cast< SMESH::Controls::FreeBorders* >( f.get() ) )
1171       type = QObject::tr( "FREE_BORDERS" );
1172     else if ( dynamic_cast< SMESH::Controls::FreeFaces* >( f.get() ) )
1173       type = QObject::tr( "FREE_FACES" );
1174     else if ( dynamic_cast< SMESH::Controls::BareBorderVolume* >( f.get() ) )
1175       type = QObject::tr( "BARE_BORDER_VOLUME" );
1176     else if ( dynamic_cast< SMESH::Controls::BareBorderFace* >( f.get() ) )
1177       type = QObject::tr( "BARE_BORDER_FACE" );
1178     else if ( dynamic_cast< SMESH::Controls::OverConstrainedVolume* >( f.get() ) )
1179       type = QObject::tr( "OVER_CONSTRAINED_VOLUME" );
1180     else if ( dynamic_cast< SMESH::Controls::OverConstrainedFace* >( f.get() ) )
1181       type = QObject::tr( "OVER_CONSTRAINED_FACE" );
1182     else if ( dynamic_cast< SMESH::Controls::CoincidentNodes* >( f.get() ) )
1183       type = QObject::tr( "EQUAL_NODE" );
1184     else if ( dynamic_cast< SMESH::Controls::CoincidentElements1D* >( f.get() ) )
1185       type = QObject::tr( "EQUAL_EDGE" );
1186     else if ( dynamic_cast< SMESH::Controls::CoincidentElements2D* >( f.get() ) )
1187       type = QObject::tr( "EQUAL_FACE" );
1188     else if ( dynamic_cast< SMESH::Controls::CoincidentElements3D* >( f.get() ) )
1189       type = QObject::tr( "EQUAL_VOLUME" );
1190     else if ( dynamic_cast< SMESH::Controls::NodeConnectivityNumber* >( f.get() ) )
1191       type = QObject::tr( "NODE_CONNECTIVITY_NB" );
1192     return type;
1193   }
1194
1195   void SaveDistribution()
1196   {
1197     LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
1198     SALOME_ListIO selected;
1199     if ( aSel )
1200       aSel->selectedObjects( selected );
1201
1202     if ( selected.Extent() == 1 ) {
1203       Handle(SALOME_InteractiveObject) anIO = selected.First();
1204       if ( anIO->hasEntry() ) {
1205         SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
1206         if ( anActor &&
1207              anActor->GetScalarBarActor() &&
1208              anActor->GetControlMode() != SMESH_Actor::eNone )
1209         {
1210           SMESH_ScalarBarActor* aScalarBarActor = anActor->GetScalarBarActor();
1211           SMESH::Controls::FunctorPtr aFunctor = anActor->GetFunctor();
1212           if ( aScalarBarActor && aFunctor ) {
1213             SMESH::Controls::NumericalFunctor* aNumFun =
1214               dynamic_cast<SMESH::Controls::NumericalFunctor*>( aFunctor.get() );
1215             if ( aNumFun ) {
1216               std::vector<int> elements;
1217               SMESH::SMESH_Mesh_var mesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(anIO);
1218               if ( mesh->_is_nil() ) {
1219                 SMESH::SMESH_IDSource_var idSource =
1220                   SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(anIO);
1221                 if ( !idSource->_is_nil() )
1222                 {
1223                   SMESH::long_array_var ids = idSource->GetIDs();
1224                   elements.resize( ids->length() );
1225                   for ( unsigned i = 0; i < elements.size(); ++i )
1226                     elements[i] = ids[i];
1227                 }
1228               }
1229               int nbIntervals = aScalarBarActor->GetMaximumNumberOfColors();
1230               vtkLookupTable* lookupTable =
1231                 static_cast<vtkLookupTable*>(aScalarBarActor->GetLookupTable());
1232               double * minmax = lookupTable->GetRange();
1233               bool isLogarithmic = lookupTable->GetScale() == VTK_SCALE_LOG10;
1234               std::vector<int>    nbEvents;
1235               std::vector<double> funValues;
1236               aNumFun->GetHistogram( nbIntervals, nbEvents, funValues,
1237                                      elements, minmax, isLogarithmic );
1238               QString anInitialPath = "";
1239               if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
1240                 anInitialPath = QDir::currentPath();
1241               QString aMeshName = anIO->getName();
1242               QStringList filter;
1243               filter.append( QObject::tr( "TEXT_FILES_FILTER" ) + " (*.txt)" );
1244               filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" );
1245               QString aFilename = anInitialPath + "/" + aMeshName + "_" +
1246                 functorToString( aFunctor ).toLower().simplified().replace( QRegExp( " |-" ), "_" ) + ".txt";
1247               aFilename = SUIT_FileDlg::getFileName( SMESHGUI::desktop(),
1248                                                      aFilename,
1249                                                      filter,
1250                                                      QObject::tr( "SMESH_SAVE_DISTRIBUTION" ),
1251                                                      false );
1252               if ( !aFilename.isEmpty() ) {
1253                 QFile f( aFilename );
1254                 if ( f.open( QFile::WriteOnly | QFile::Truncate ) ) {
1255                   QTextStream out( &f );
1256                   out << "# Mesh: " << aMeshName << endl;
1257                   out << "# Control: " << functorToString( aFunctor ) << endl;
1258                   out << "#" << endl;
1259                   out.setFieldWidth( 10 );
1260                   for ( int i = 0; i < (int)qMin( nbEvents.size(), funValues.size()-1 ); i++ )
1261                     out << funValues[i] << "\t" << funValues[i+1] << "\t" << nbEvents[i] << endl;
1262                   f.close();
1263                 }
1264               }
1265             }
1266           }
1267         }
1268       }
1269     }
1270   }
1271
1272   void ShowElement( int theCommandID )
1273   {
1274     LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
1275     SALOME_ListIO selected;
1276     if ( aSel )
1277       aSel->selectedObjects( selected );
1278
1279     if ( selected.Extent() == 1 ) {
1280       Handle(SALOME_InteractiveObject) anIO = selected.First();
1281       if ( anIO->hasEntry() ) {
1282         SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
1283         if ( anActor &&
1284              anActor->GetScalarBarActor() &&
1285              anActor->GetControlMode() != SMESH_Actor::eNone )
1286         {
1287           SMESH_ScalarBarActor *aScalarBarActor = anActor->GetScalarBarActor();
1288           if ( theCommandID == SMESHOp::OpShowDistribution ) {
1289             aScalarBarActor->SetDistributionVisibility(!aScalarBarActor->GetDistributionVisibility());
1290           }
1291           else if ( theCommandID == SMESHOp::OpShowScalarBar ) {
1292             aScalarBarActor->SetVisibility( !aScalarBarActor->GetVisibility());
1293           }
1294         }
1295       }
1296     }
1297   }
1298
1299 #ifndef DISABLE_PLOT2DVIEWER
1300   void PlotDistribution()
1301   {
1302     SalomeApp_Application* app =
1303       dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
1304     if( !app )
1305       return;
1306
1307     LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
1308     SALOME_ListIO selected;
1309     if ( aSel )
1310       aSel->selectedObjects( selected );
1311
1312     if ( selected.Extent() == 1 ) {
1313       Handle(SALOME_InteractiveObject) anIO = selected.First();
1314       if ( anIO->hasEntry() ) {
1315         //Find Actor by entry before getting Plot2d viewer,
1316         //because after call getViewManager( Plot2d_Viewer::Type(), true ) active window is Plot2d Viewer
1317         SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
1318
1319         SUIT_ViewManager* aViewManager =
1320           app->getViewManager( Plot2d_Viewer::Type(), true ); // create if necessary
1321         if( !aViewManager )
1322           return;
1323
1324         SPlot2d_Viewer* aView = dynamic_cast<SPlot2d_Viewer*>(aViewManager->getViewModel());
1325         if ( !aView )
1326           return;
1327
1328         Plot2d_ViewFrame* aPlot = aView->getActiveViewFrame();
1329         if ( !aPlot )
1330           return;
1331
1332         if ( anActor && anActor->GetControlMode() != SMESH_Actor::eNone )
1333         {
1334           SPlot2d_Histogram* aHistogram = anActor->UpdatePlot2Histogram();
1335           QString functorName = functorToString( anActor->GetFunctor());
1336           QString aHistogramName("%1 : %2");
1337           aHistogramName = aHistogramName.arg(anIO->getName()).arg(functorName);
1338           aHistogram->setName(aHistogramName);
1339           aHistogram->setHorTitle(functorName);
1340           aHistogram->setVerTitle(QObject::tr("DISTRIBUTION_NB_ENT"));
1341           aPlot->displayObject(aHistogram, true);
1342         }
1343       }
1344     }
1345   }
1346 #endif //DISABLE_PLOT2DVIEWER
1347
1348   void DisableAutoColor()
1349   {
1350     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
1351     SALOME_ListIO selected;
1352     if ( aSel )
1353       aSel->selectedObjects( selected );
1354
1355     if ( selected.Extent() ) {
1356       Handle(SALOME_InteractiveObject) anIObject = selected.First();
1357       SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(anIObject);
1358       if ( !aMesh->_is_nil() ) {
1359         aMesh->SetAutoColor( false );
1360       }
1361     }
1362   }
1363
1364   void sortChildren()
1365   {
1366     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
1367     SALOME_ListIO selected;
1368     if ( aSel ) {
1369       aSel->selectedObjects( selected );
1370       if ( selected.Extent() )
1371       {
1372         Handle(SALOME_InteractiveObject) anIObject = selected.First();
1373         _PTR(Study) aStudy = SMESH::getStudy();
1374         _PTR(SObject) aSObj = aStudy->FindObjectID(anIObject->getEntry());
1375         if (aSObj) {
1376           if ( aStudy->GetUseCaseBuilder()->SortChildren( aSObj, true/*AscendingOrder*/ ) ) {
1377             SMESHGUI::GetSMESHGUI()->updateObjBrowser();
1378           }
1379         }
1380       }
1381     }
1382   }
1383
1384   void SetDisplayMode(int theCommandID, VTK::MarkerMap& theMarkerMap)
1385   {
1386     SALOME_ListIO selected;
1387     SalomeApp_Application* app =
1388       dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
1389     if ( !app )
1390       return;
1391
1392     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
1393     SalomeApp_Study*   appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
1394     if ( !aSel || !appStudy )
1395       return;
1396
1397     if ( theCommandID == SMESHOp::OpClipping ) { // Clipping dialog can be activated without selection
1398       if ( SMESHGUI* aModule = SMESHGUI::GetSMESHGUI() ) {
1399         aModule->EmitSignalDeactivateDialog();
1400         if( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aModule ) )
1401           (new SMESHGUI_ClippingDlg( aModule, aViewWindow ))->show();
1402       }
1403       return;
1404     }
1405
1406     aSel->selectedObjects( selected );
1407
1408     if ( selected.Extent() >= 1 )
1409     {
1410       switch ( theCommandID ) {
1411       case SMESHOp::OpTransparency:
1412       {
1413         SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
1414         (new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI() ))->show();
1415         return;
1416       }
1417       case SMESHOp::OpProperties:
1418       {
1419         double color[3];
1420         QColor faceColor, edgeColor, nodeColor, elem0dColor, ballColor;
1421         QColor orientationColor, outlineColor, volumeColor;
1422         int deltaF = 0, deltaV = 0;
1423         int elem0dSize   = 1;
1424         //int ballSize     = 1;
1425         double ballScale = 1.0;
1426         int edgeWidth    = 1;
1427         int outlineWidth = 1;
1428         double shrinkCoef = 0.0;
1429         double orientationScale = 0.0;
1430         bool orientation3d = false;
1431         VTK::MarkerType markerType = VTK::MT_NONE;
1432         VTK::MarkerScale markerScale = VTK::MS_NONE;
1433         int markerId = 0;
1434         bool hasNodes = false;
1435         int presentEntities = 0;
1436         bool firstTime  = true;
1437
1438         SALOME_ListIteratorOfListIO It( selected );
1439         for ( ; It.More(); It.Next() ) {
1440           Handle(SALOME_InteractiveObject) IObject = It.Value();
1441           if ( !IObject->hasEntry() ) continue;
1442           SMESH_Actor* anActor = SMESH::FindActorByEntry( IObject->getEntry() );
1443           if ( !anActor || !anActor->GetObject() ) continue;
1444
1445           if ( firstTime ) {
1446             // nodes: color, marker
1447             anActor->GetNodeColor( color[0], color[1], color[2] );
1448             nodeColor.setRgbF( color[0], color[1], color[2] );
1449             markerType  = anActor->GetMarkerType();
1450             markerScale = anActor->GetMarkerScale();
1451             markerId    = anActor->GetMarkerTexture();
1452             // edges: color, width
1453             anActor->GetEdgeColor( color[0], color[1], color[2] );
1454             edgeColor.setRgbF( color[0], color[1], color[2] );
1455             edgeWidth = qMax( (int)anActor->GetLineWidth(), 1 ); // minimum allowed width is 1
1456             // faces: front color, back color (delta)
1457             anActor->GetSufaceColor( color[0], color[1], color[2], deltaF );
1458             faceColor.setRgbF( color[0], color[1], color[2] );
1459             // faces: front color, back color (delta)
1460             anActor->GetVolumeColor( color[0], color[1], color[2], deltaV );
1461             volumeColor.setRgbF( color[0], color[1], color[2] );
1462             // 0d elements: color, size
1463             anActor->Get0DColor( color[0], color[1], color[2] );
1464             elem0dColor.setRgbF( color[0], color[1], color[2] );
1465             elem0dSize = qMax( (int)anActor->Get0DSize(), 1 ); // minimum allowed size is 1
1466             // balls: color, size
1467             anActor->GetBallColor( color[0], color[1], color[2] );
1468             ballColor.setRgbF( color[0], color[1], color[2] );
1469             //ballSize = qMax( (int)anActor->GetBallSize(), 1 ); // minimum allowed size is 1
1470             ballScale = qMax( (double)anActor->GetBallScale(), 1e-2 ); // minimum allowed scale is 1e-2
1471             // outlines: color
1472             anActor->GetOutlineColor( color[0], color[1], color[2] );
1473             outlineColor.setRgbF( color[0], color[1], color[2] );
1474             outlineWidth = qMax( (int)anActor->GetOutlineWidth(), 1 ); // minimum allowed width is 1
1475             // orientation vectors: color, scale, 3d flag
1476             anActor->GetFacesOrientationColor( color[0], color[1], color[2] );
1477             orientationColor.setRgbF( color[0], color[1], color[2] );
1478             orientationScale = anActor->GetFacesOrientationScale();
1479             orientation3d = anActor->GetFacesOrientation3DVectors();
1480             // shrink factor
1481             shrinkCoef = anActor->GetShrinkFactor();
1482           }
1483
1484           firstTime = false; // we only take properties from first object (for performance reasons)
1485
1486           if ( !hasNodes )
1487             hasNodes = anActor->GetObject()->GetNbEntities( SMDSAbs_Node );
1488           if ( !(presentEntities & SMESH_Actor::eEdges) && anActor->GetObject()->GetNbEntities( SMDSAbs_Edge ) )
1489             presentEntities = presentEntities | SMESH_Actor::eEdges;
1490           if ( !(presentEntities & SMESH_Actor::eFaces) && anActor->GetObject()->GetNbEntities( SMDSAbs_Face ) )
1491             presentEntities = presentEntities | SMESH_Actor::eFaces;
1492           if ( !(presentEntities & SMESH_Actor::eVolumes) && anActor->GetObject()->GetNbEntities( SMDSAbs_Volume ) )
1493             presentEntities = presentEntities | SMESH_Actor::eVolumes;
1494           if ( !(presentEntities & SMESH_Actor::e0DElements) && anActor->GetObject()->GetNbEntities( SMDSAbs_0DElement ) )
1495             presentEntities = presentEntities | SMESH_Actor::e0DElements;
1496           if ( !(presentEntities & SMESH_Actor::eBallElem) && anActor->GetObject()->GetNbEntities( SMDSAbs_Ball ) )
1497             presentEntities = presentEntities | SMESH_Actor::eBallElem;
1498
1499           // as we know that all types of elements are present, we can exit the loop
1500           if ( presentEntities == SMESH_Actor::eAllEntity )
1501             break;
1502         }
1503
1504         SMESHGUI_PropertiesDlg dlg( theMarkerMap, SMESHGUI::desktop() );
1505         // nodes: color, marker
1506         dlg.setNodeColor( nodeColor );
1507         if( markerType != VTK::MT_USER )
1508           dlg.setNodeMarker( markerType, markerScale );
1509         else
1510           dlg.setNodeCustomMarker( markerId );
1511         // edges: color, line width
1512         dlg.setEdgeColor( edgeColor );
1513         dlg.setEdgeWidth( edgeWidth );
1514         // faces: front color, back color
1515         dlg.setFaceColor( faceColor, deltaF );
1516         // volumes: normal color, reversed color
1517         dlg.setVolumeColor( volumeColor, deltaV );
1518         // outlines: color, line width
1519         dlg.setOutlineColor( outlineColor );
1520         dlg.setOutlineWidth( outlineWidth );
1521         // 0d elements: color, size
1522         dlg.setElem0dColor( elem0dColor );
1523         dlg.setElem0dSize( elem0dSize );
1524         // balls: color, size
1525         dlg.setBallColor( ballColor );
1526         //dlg.setBallSize( ballSize );
1527         dlg.setBallScale( ballScale );
1528         // orientation: color, scale, 3d flag
1529         dlg.setOrientationColor( orientationColor );
1530         dlg.setOrientationSize( int( orientationScale * 100. ) );
1531         dlg.setOrientation3d( orientation3d );
1532         // shrink: scale factor
1533         dlg.setShrinkCoef( int( shrinkCoef * 100. ) );
1534         // hide unused controls
1535         dlg.showControls( presentEntities, hasNodes );
1536
1537         if ( dlg.exec() ) {
1538           nodeColor        = dlg.nodeColor();
1539           markerType       = dlg.nodeMarkerType();
1540           markerScale      = dlg.nodeMarkerScale();
1541           markerId         = dlg.nodeMarkerId();
1542           edgeColor        = dlg.edgeColor();
1543           edgeWidth        = dlg.edgeWidth();
1544           faceColor        = dlg.faceColor();
1545           deltaF           = dlg.faceColorDelta();
1546           volumeColor      = dlg.volumeColor();
1547           deltaV           = dlg.volumeColorDelta();
1548           outlineColor     = dlg.outlineColor();
1549           outlineWidth     = dlg.outlineWidth();
1550           elem0dColor      = dlg.elem0dColor();
1551           elem0dSize       = dlg.elem0dSize();
1552           ballColor        = dlg.ballColor();
1553          // ballSize         = dlg.ballSize();
1554           ballScale        = dlg.ballScale();
1555           orientationColor = dlg.orientationColor();
1556           orientationScale = dlg.orientationSize() / 100.;
1557           orientation3d    = dlg.orientation3d();
1558           shrinkCoef       = dlg.shrinkCoef() / 100.;
1559
1560           // store point markers that might be changed by the user
1561           theMarkerMap = dlg.customMarkers();
1562
1563           // set properties from dialog box to the presentations
1564           SALOME_ListIteratorOfListIO It( selected );
1565           for ( ; It.More(); It.Next() ) {
1566             Handle(SALOME_InteractiveObject) IObject = It.Value();
1567             if ( !IObject->hasEntry() ) continue;
1568             SMESH_Actor* anActor = SMESH::FindActorByEntry( IObject->getEntry() );
1569             if ( !anActor ) continue;
1570
1571             // nodes: color, marker
1572             anActor->SetNodeColor( nodeColor.redF(), nodeColor.greenF(), nodeColor.blueF() );
1573             if ( markerType != VTK::MT_USER ) {
1574               anActor->SetMarkerStd( markerType, markerScale );
1575             }
1576             else {
1577               VTK::MarkerMap::const_iterator iter = theMarkerMap.find( markerId );
1578               if ( iter != theMarkerMap.end() )
1579                 anActor->SetMarkerTexture( markerId, iter->second.second );
1580             }
1581             // volumes: normal color, reversed color (delta)
1582             anActor->SetVolumeColor( volumeColor.redF(), volumeColor.greenF(), volumeColor.blueF(), deltaV );
1583             // faces: front color, back color (delta)
1584             anActor->SetSufaceColor( faceColor.redF(), faceColor.greenF(), faceColor.blueF(), deltaF );
1585             // edges: color, width
1586             anActor->SetEdgeColor( edgeColor.redF(), edgeColor.greenF(), edgeColor.blueF() );
1587             anActor->SetLineWidth( edgeWidth );
1588             // outlines: color
1589             anActor->SetOutlineColor( outlineColor.redF(), outlineColor.greenF(), outlineColor.blueF() );
1590             anActor->SetOutlineWidth( outlineWidth );
1591             // 0D elements: color, size
1592             anActor->Set0DColor( elem0dColor.redF(), elem0dColor.greenF(), elem0dColor.blueF() );
1593             anActor->Set0DSize( elem0dSize );
1594             // balls: color, size
1595             anActor->SetBallColor( ballColor.redF(), ballColor.greenF(), ballColor.blueF() );
1596             // anActor->SetBallSize( ballSize );
1597             anActor->SetBallScale( ballScale );
1598             // orientation: color, scale, 3d flag
1599             anActor->SetFacesOrientationColor( orientationColor.redF(), orientationColor.greenF(), orientationColor.blueF() );
1600             anActor->SetFacesOrientationScale( orientationScale );
1601             anActor->SetFacesOrientation3DVectors( orientation3d );
1602             // shrink factor
1603             anActor->SetShrinkFactor( shrinkCoef );
1604
1605             // for groups, set also proper color
1606             SMESH::SMESH_GroupBase_var aGroupObject = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IObject);
1607             if ( !aGroupObject->_is_nil() ) {
1608               SMESH::ElementType anElementType = aGroupObject->GetType();
1609               QColor aColor;
1610               switch( anElementType ) {
1611               case SMESH::NODE:
1612                 aColor = nodeColor; break;
1613               case SMESH::EDGE:
1614                 aColor = edgeColor; break;
1615               case SMESH::FACE:
1616                 aColor = faceColor; break;
1617               case SMESH::VOLUME:
1618                 aColor = volumeColor; break;
1619               case SMESH::ELEM0D:
1620                 aColor = elem0dColor; break;
1621               case SMESH::BALL:
1622                 aColor = ballColor; break;
1623               default: break;
1624               }
1625
1626               if ( aColor.isValid() ) {
1627                 SALOMEDS::Color aGroupColor;
1628                 aGroupColor.R = aColor.redF();
1629                 aGroupColor.G = aColor.greenF();
1630                 aGroupColor.B = aColor.blueF();
1631                 aGroupObject->SetColor( aGroupColor );
1632               }
1633             } // if ( !aGroupObject->_is_nil() )
1634           } // for ( ; It.More(); It.Next() )
1635           SMESH::RepaintCurrentView();
1636         } // if ( dlg.exec() )
1637         return;
1638       } // case SMESHOp::OpProperties:
1639       } // switch(theCommandID)
1640       SUIT_OverrideCursor wc;
1641       SALOME_ListIteratorOfListIO It( selected );
1642       for( ; It.More(); It.Next()){
1643         Handle(SALOME_InteractiveObject) IObject = It.Value();
1644         if(IObject->hasEntry()){
1645           if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
1646             switch(theCommandID){
1647             case SMESHOp::OpDMWireframe:
1648               anActor->SetRepresentation(SMESH_Actor::eEdge);
1649               break;
1650             case SMESHOp::OpDMShading:
1651               anActor->SetRepresentation(SMESH_Actor::eSurface);
1652               break;
1653             case SMESHOp::OpDMShrink:
1654               if(anActor->IsShrunk())
1655                 anActor->UnShrink();
1656               else
1657                 anActor->SetShrink();
1658               break;
1659             case SMESHOp::OpDMNodes:
1660               anActor->SetRepresentation(SMESH_Actor::ePoint);
1661               break;
1662             case SMESHOp::OpRepresentationLines:
1663               if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eLines)
1664                 anActor->SetQuadratic2DRepresentation(SMESH_Actor::eLines);
1665               break;
1666             case SMESHOp::OpRepresentationArcs:
1667               if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eArcs)
1668                 anActor->SetQuadratic2DRepresentation(SMESH_Actor::eArcs);
1669               break;
1670             }
1671           }
1672         }
1673       }
1674       SMESH::RepaintCurrentView();
1675     }
1676   }
1677
1678   int ActionToControl( int theID, bool theReversed )
1679   {
1680     NCollection_DoubleMap<int,int> ActionControl;
1681     ActionControl.Bind( 0,                                SMESH_Actor::eNone );
1682     ActionControl.Bind( SMESHOp::OpFreeNode,              SMESH_Actor::eFreeNodes );
1683     ActionControl.Bind( SMESHOp::OpEqualNode,             SMESH_Actor::eCoincidentNodes );
1684     ActionControl.Bind( SMESHOp::OpNodeConnectivityNb,    SMESH_Actor::eNodeConnectivityNb );
1685     ActionControl.Bind( SMESHOp::OpFreeEdge,              SMESH_Actor::eFreeEdges );
1686     ActionControl.Bind( SMESHOp::OpFreeBorder,            SMESH_Actor::eFreeBorders );
1687     ActionControl.Bind( SMESHOp::OpLength,                SMESH_Actor::eLength );
1688     ActionControl.Bind( SMESHOp::OpConnection,            SMESH_Actor::eMultiConnection );
1689     ActionControl.Bind( SMESHOp::OpEqualEdge,             SMESH_Actor::eCoincidentElems1D );
1690     ActionControl.Bind( SMESHOp::OpFreeFace,              SMESH_Actor::eFreeFaces );
1691     ActionControl.Bind( SMESHOp::OpBareBorderFace,        SMESH_Actor::eBareBorderFace );
1692     ActionControl.Bind( SMESHOp::OpOverConstrainedFace,   SMESH_Actor::eOverConstrainedFace );
1693     ActionControl.Bind( SMESHOp::OpLength2D,              SMESH_Actor::eLength2D );
1694     ActionControl.Bind( SMESHOp::OpDeflection2D,          SMESH_Actor::eDeflection2D );
1695     ActionControl.Bind( SMESHOp::OpConnection2D,          SMESH_Actor::eMultiConnection2D );
1696     ActionControl.Bind( SMESHOp::OpArea,                  SMESH_Actor::eArea );
1697     ActionControl.Bind( SMESHOp::OpTaper,                 SMESH_Actor::eTaper );
1698     ActionControl.Bind( SMESHOp::OpAspectRatio,           SMESH_Actor::eAspectRatio );
1699     ActionControl.Bind( SMESHOp::OpMinimumAngle,          SMESH_Actor::eMinimumAngle );
1700     ActionControl.Bind( SMESHOp::OpWarpingAngle,          SMESH_Actor::eWarping );
1701     ActionControl.Bind( SMESHOp::OpSkew,                  SMESH_Actor::eSkew );
1702     ActionControl.Bind( SMESHOp::OpMaxElementLength2D,    SMESH_Actor::eMaxElementLength2D );
1703     ActionControl.Bind( SMESHOp::OpEqualFace,             SMESH_Actor::eCoincidentElems2D );
1704     ActionControl.Bind( SMESHOp::OpAspectRatio3D,         SMESH_Actor::eAspectRatio3D );
1705     ActionControl.Bind( SMESHOp::OpVolume,                SMESH_Actor::eVolume3D );
1706     ActionControl.Bind( SMESHOp::OpMaxElementLength3D,    SMESH_Actor::eMaxElementLength3D );
1707     ActionControl.Bind( SMESHOp::OpBareBorderVolume,      SMESH_Actor::eBareBorderVolume );
1708     ActionControl.Bind( SMESHOp::OpOverConstrainedVolume, SMESH_Actor::eOverConstrainedVolume );
1709     ActionControl.Bind( SMESHOp::OpEqualVolume,           SMESH_Actor::eCoincidentElems3D );
1710
1711     if ( theReversed )
1712       return ActionControl.IsBound2( theID ) ? ActionControl.Find2( theID ) : 0;
1713     return   ActionControl.IsBound1( theID ) ? ActionControl.Find1( theID ) : 0;
1714   }
1715
1716   void Control( int theCommandID )
1717   {
1718     SMESH_Actor::eControl aControl = SMESH_Actor::eControl( ActionToControl( theCommandID ));
1719     _PTR(Study) aStudy = SMESH::getStudy();
1720
1721     SALOME_ListIO selected;
1722     if ( LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr() )
1723       aSel->selectedObjects( selected );
1724
1725     if ( !selected.IsEmpty() ) {
1726       SALOME_ListIteratorOfListIO It(selected);
1727       for ( ; It.More(); It.Next())
1728       {
1729         Handle(SALOME_InteractiveObject) anIO = It.Value();
1730         if ( !anIO.IsNull() ) {
1731           _PTR(SObject) SO = aStudy->FindObjectID( It.Value()->getEntry() );
1732           if ( SO ) {
1733             CORBA::Object_var         aObject = SMESH::SObjectToObject( SO );
1734             SMESH::SMESH_IDSource_var anIDSrc = SMESH::SMESH_IDSource::_narrow( aObject );
1735             if ( !anIDSrc->_is_nil() ) {
1736               SMESH_Actor *anActor = SMESH::FindActorByEntry( anIO->getEntry());
1737               if (( !anActor && selected.Extent() == 1 ) &&
1738                   ( anActor = SMESH::CreateActor( anIO->getEntry() )))
1739               {
1740                 anActor->SetControlMode( aControl );
1741                 SMESH::DisplayActor( SMESH::GetCurrentVtkView(), anActor );
1742                 SMESH::UpdateView  ( SMESH::eDisplay, anIO->getEntry() );
1743               }
1744               if ( anActor )
1745               {
1746                 if ( anActor->GetControlMode() != aControl )
1747                   anActor->SetControlMode( aControl );
1748                 QString functorName = functorToString( anActor->GetFunctor() );
1749                 int anEntitiesCount = anActor->GetNumberControlEntities();
1750                 if (anEntitiesCount >= 0)
1751                   functorName = functorName + ": " + QString::number(anEntitiesCount);
1752                 anActor->GetScalarBarActor()->SetTitle( functorName.toLatin1().constData() );
1753                 SMESH::RepaintCurrentView();
1754 #ifndef DISABLE_PLOT2DVIEWER
1755                 if ( anActor->GetPlot2Histogram() ) {
1756                   SPlot2d_Histogram* aHistogram = anActor->UpdatePlot2Histogram();
1757                   QString aHistogramName("%1 : %2");
1758                   aHistogramName = aHistogramName.arg( anIO->getName() ).arg( functorName );
1759                   aHistogram->setName( aHistogramName );
1760                   aHistogram->setHorTitle( functorName );
1761                   SMESH::ProcessIn2DViewers( anActor );
1762                 }
1763 #endif
1764               }
1765             }
1766           }
1767         }
1768       }
1769     }
1770   }
1771
1772
1773   bool CheckOIType(const Handle(SALOME_InteractiveObject) & theIO,
1774                    SMESH::MeshObjectType                    theType,
1775                    const QString                            theInTypeName,
1776                    QString &                                theOutTypeName)
1777   {
1778     SMESH_TypeFilter aTypeFilter( theType );
1779     QString entry;
1780     if ( !theIO.IsNull() )
1781     {
1782       entry = theIO->getEntry();
1783       LightApp_DataOwner owner( entry );
1784       if ( aTypeFilter.isOk( &owner )) {
1785         theOutTypeName = theInTypeName;
1786         return true;
1787       }
1788     }
1789     return false;
1790   }
1791
1792
1793   QString CheckTypeObject(const Handle(SALOME_InteractiveObject) & theIO)
1794   {
1795     _PTR(Study)  aStudy = SMESH::getStudy();
1796     _PTR(SObject) aSObj = aStudy->FindObjectID(theIO->getEntry());
1797     if (aSObj) {
1798       _PTR(SComponent) aSComp = aSObj->GetFatherComponent();
1799       CORBA::String_var  anID = aSComp->GetID().c_str();
1800       if ( !strcmp(anID.in(),theIO->getEntry()) )
1801         return "Component";
1802     }
1803
1804     QString aTypeName;
1805     if (
1806         CheckOIType ( theIO, SMESH::HYPOTHESIS,    "Hypothesis", aTypeName ) ||
1807         CheckOIType ( theIO, SMESH::ALGORITHM,     "Algorithm",  aTypeName ) ||
1808         CheckOIType ( theIO, SMESH::MESH,          "Mesh",       aTypeName ) ||
1809         CheckOIType ( theIO, SMESH::SUBMESH,       "SubMesh",    aTypeName ) ||
1810         CheckOIType ( theIO, SMESH::GROUP,         "Group",      aTypeName )
1811         )
1812       return aTypeName;
1813
1814     return "NoType";
1815   }
1816
1817
1818   // QString CheckHomogeneousSelection()
1819   // {
1820   //   LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
1821   //   SALOME_ListIO selected;
1822   //   if ( aSel )
1823   //     aSel->selectedObjects( selected );
1824
1825   //   QString RefType = CheckTypeObject(selected.First());
1826   //   SALOME_ListIteratorOfListIO It(selected);
1827   //   for ( ; It.More(); It.Next())
1828   //   {
1829   //     Handle(SALOME_InteractiveObject) IObject = It.Value();
1830   //     QString Type = CheckTypeObject(IObject);
1831   //     if ( Type.compare(RefType) != 0 )
1832   //       return "Heterogeneous Selection";
1833   //   }
1834
1835   //   return RefType;
1836   // }
1837
1838   uint randomize( uint size )
1839   {
1840     static bool initialized = false;
1841     if ( !initialized ) {
1842       qsrand( QDateTime::currentDateTime().toTime_t() );
1843       initialized = true;
1844     }
1845     uint v = qrand();
1846     v = uint( (double)( v ) / RAND_MAX * size );
1847     v = qMax( uint(0), qMin ( v, size-1 ) );
1848     return v;
1849   }
1850
1851 } //namespace
1852
1853 void SMESHGUI::OnEditDelete()
1854 {
1855   // VSR 17/11/04: check if all objects selected belong to SMESH component --> start
1856   LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
1857   SALOME_ListIO selected; aSel->selectedObjects( selected, QString::null, false );
1858
1859   _PTR(Study) aStudy = SMESH::getStudy();
1860   _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
1861   _PTR(GenericAttribute) anAttr;
1862   _PTR(AttributeIOR) anIOR;
1863
1864   const int objectCountLimit = 30; // PAL23599
1865   int objectCount = 0;
1866   QString aNameList;
1867   QString aParentComponent = QString::null;
1868   
1869   for( SALOME_ListIteratorOfListIO anIt( selected ); anIt.More(); anIt.Next() )
1870   {
1871     Handle(SALOME_InteractiveObject) anIO = anIt.Value();
1872     if ( anIO.IsNull() ) continue;
1873     
1874     QString father = "unknown", name;
1875
1876     _PTR(SObject) aSO = aStudy->FindObjectID( anIO->getEntry() );
1877     if (aSO) {
1878       father = QString::fromStdString( aSO->GetFatherComponent()->ComponentDataType() );
1879       // check if object is reference
1880       _PTR(SObject) aRefSObj;
1881       if ( aSO->ReferencedObject( aRefSObj ) ) {
1882         name = QString::fromStdString ( aRefSObj->GetName() );
1883         father = QString::fromStdString ( aRefSObj->GetFatherComponent()->ComponentDataType() );
1884       }
1885       else
1886         name = anIO->getName();
1887       objectCount++;
1888     }
1889     if ( objectCount < objectCountLimit ) { // avoid occupying the whole screen
1890       aNameList.append("\n    - ");
1891       aNameList.append( name );
1892     }
1893
1894     if( aParentComponent.isNull() )
1895       aParentComponent = father;
1896     else if( !aParentComponent.isEmpty() && aParentComponent!=father )
1897       aParentComponent = "";
1898   }
1899   if ( objectCount >= objectCountLimit )
1900     aNameList.append("\n    - ...");
1901
1902   if ( objectCount == 0 )
1903     return; // No Valid Objects Selected
1904
1905   if ( aParentComponent != SMESHGUI::GetSMESHGUI()->name() )  {
1906     SUIT_MessageBox::warning( SMESHGUI::desktop(),
1907                               QObject::tr("ERR_ERROR"),
1908                               QObject::tr("NON_SMESH_OBJECTS_SELECTED").arg( SMESHGUI::GetSMESHGUI()->moduleName() ) );
1909     return;
1910   }
1911   // VSR 17/11/04: check if all objects selected belong to SMESH component <-- finish
1912   if (SUIT_MessageBox::warning
1913       (SMESHGUI::desktop(),
1914        QObject::tr("SMESH_WRN_WARNING"),
1915        QObject::tr("SMESH_REALLY_DELETE").arg( objectCount ).arg( aNameList ),
1916        SUIT_MessageBox::Yes | SUIT_MessageBox::No,
1917        SUIT_MessageBox::Yes) != SUIT_MessageBox::Yes)
1918     return;
1919
1920   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
1921
1922   // Put the whole hierarchy of sub-objects of the selected SO's into a list and
1923   // then treat them all starting from the deepest objects (at list back)
1924   std::list< _PTR(SObject) > listSO;
1925   SALOME_ListIteratorOfListIO It(selected);
1926   for( ; It.More(); It.Next()) // loop on selected IO's
1927   {
1928     Handle(SALOME_InteractiveObject) IObject = It.Value();
1929     if(IObject->hasEntry()) {
1930       _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry());
1931
1932       // disable removal of "SMESH" component object
1933       if(aSO->FindAttribute(anAttr, "AttributeIOR")){
1934         anIOR = anAttr;
1935         if ( engineIOR() == anIOR->Value().c_str() )
1936           continue;
1937       }
1938       //Check the referenced object
1939       _PTR(SObject) aRefSObject;
1940       if ( aSO && aSO->ReferencedObject( aRefSObject ) )
1941         aSO = aRefSObject; // Delete main Object instead of reference
1942
1943       listSO.push_back( aSO );
1944       std::list< _PTR(SObject) >::iterator itSO = --listSO.end();
1945       for ( ; itSO != listSO.end(); ++itSO ) {
1946         _PTR(ChildIterator) it = aStudy->NewChildIterator( *itSO );
1947         for (it->InitEx(false); it->More(); it->Next())
1948           listSO.push_back( it->Value() );
1949       }
1950     }
1951   }
1952   // Check if none of objects to delete is referred from outside
1953   std::list< _PTR(SObject) >::reverse_iterator ritSO;
1954   for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
1955   {
1956     _PTR(SObject) SO = *ritSO;
1957     if ( !SO ) continue;
1958     std::vector<_PTR(SObject)> aReferences = aStudy->FindDependances( *ritSO  );
1959     for (size_t i = 0; i < aReferences.size(); i++) {
1960       _PTR(SComponent) aComponent = aReferences[i]->GetFatherComponent();
1961       std::string type = aComponent->ComponentDataType();
1962       if ( type != "SMESH" )
1963       {
1964         SUIT_MessageBox::warning( anApp->desktop(),
1965                                   QObject::tr("WRN_WARNING"),
1966                                   QObject::tr("DEP_OBJECT") );
1967         return; // outside SMESH, there is an object depending on a SMESH object
1968       }
1969     }
1970   }
1971
1972   // Call mesh->Clear() to prevent loading mesh from file caused by hypotheses removal
1973   for( It.Initialize( selected ); It.More(); It.Next()) // loop on selected IO's
1974   {
1975     Handle(SALOME_InteractiveObject) IObject = It.Value();
1976     SMESH::SMESH_Mesh_var mesh = SMESH::IObjectToInterface< SMESH::SMESH_Mesh >( IObject );
1977     if ( !mesh->_is_nil() )
1978       mesh->Clear();
1979   }
1980
1981   // Treat SO's in the list starting from the back
1982   aStudyBuilder->NewCommand();  // There is a transaction
1983   for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
1984   {
1985     _PTR(SObject) SO = *ritSO;
1986     if ( !SO ) continue;
1987     std::string anEntry = SO->GetID();
1988
1989     /** Erase graphical object and remove all its data **/
1990     if(SO->FindAttribute(anAttr, "AttributeIOR")) {
1991       SMESH::RemoveVisualObjectWithActors( anEntry.c_str(), true);
1992     }
1993     /** Remove an object from data structures **/
1994     SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( SO ));
1995     SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( SO ));
1996     if ( !aGroup->_is_nil() ) {                          // DELETE GROUP
1997       SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh();
1998       aMesh->RemoveGroup( aGroup );
1999     }
2000     else if ( !aSubMesh->_is_nil() ) {                   // DELETE SUBMESH
2001       SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
2002       aMesh->RemoveSubMesh( aSubMesh );
2003     }
2004     else {
2005       Handle(SALOME_InteractiveObject) IObject = new SALOME_InteractiveObject
2006         ( anEntry.c_str(), engineIOR().toLatin1().data(), SO->GetName().c_str() );
2007       QString objType = CheckTypeObject(IObject);
2008       if ( objType == "Hypothesis" || objType == "Algorithm" ) {// DELETE HYPOTHESIS
2009         SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject);
2010         aStudyBuilder->RemoveObjectWithChildren( SO );
2011       }
2012       else {// default action: remove SObject from the study
2013         // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH
2014         //SUIT_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy);
2015         //op->start();
2016         aStudyBuilder->RemoveObjectWithChildren( SO );
2017         //op->finish();
2018       }
2019     }
2020   } /* listSO back loop */
2021
2022   aStudyBuilder->CommitCommand();
2023
2024   /* Clear any previous selection */
2025   SALOME_ListIO l1;
2026   aSel->setSelectedObjects( l1 );
2027
2028   SMESHGUI::GetSMESHGUI()->updateObjBrowser();
2029 }
2030
2031 extern "C" {
2032   SMESHGUI_EXPORT CAM_Module* createModule()
2033   {
2034     return new SMESHGUI();
2035   }
2036
2037   SMESHGUI_EXPORT  char* getModuleVersion() {
2038     return (char*)SMESH_VERSION_STR;
2039   }
2040 }
2041
2042 SMESH::SMESH_Gen_var SMESHGUI::myComponentSMESH = SMESH::SMESH_Gen::_nil();
2043
2044 //=============================================================================
2045 /*!
2046  *
2047  */
2048 //=============================================================================
2049 SMESHGUI::SMESHGUI() :
2050 SalomeApp_Module( "SMESH" )
2051 {
2052   if ( CORBA::is_nil( myComponentSMESH ) )
2053   {
2054     CORBA::Boolean anIsEmbeddedMode;
2055     myComponentSMESH = SMESH_Client::GetSMESHGen(getApp()->orb(),anIsEmbeddedMode);
2056     //MESSAGE("-------------------------------> anIsEmbeddedMode=" << anIsEmbeddedMode);
2057
2058     //  0019923: EDF 765 SMESH : default values of hypothesis
2059     SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this);
2060     int nbSeg = aResourceMgr->integerValue( "SMESH", "segmentation", 10 );
2061     myComponentSMESH->SetBoundaryBoxSegmentation( nbSeg );
2062     nbSeg = aResourceMgr->integerValue( "SMESH", "nb_segments_per_edge", 15 );
2063     myComponentSMESH->SetDefaultNbSegments( nbSeg );
2064
2065     const char* options[] = { "historical_python_dump", "forget_mesh_on_hyp_modif", "default_grp_color" };
2066     for ( size_t i = 0; i < sizeof(options)/sizeof(char*); ++i )
2067       if ( aResourceMgr->hasValue( "SMESH", options[i] ))
2068       {
2069         QString val = aResourceMgr->stringValue( "SMESH", options[i] );
2070         myComponentSMESH->SetOption( options[i], val.toLatin1().constData() );
2071       }
2072   }
2073
2074   myActiveDialogBox = 0;
2075   myFilterLibraryDlg = 0;
2076   myState = -1;
2077   myDisplayer = 0;
2078
2079   myEventCallbackCommand = vtkCallbackCommand::New();
2080   myEventCallbackCommand->Delete();
2081   myEventCallbackCommand->SetClientData( this );
2082   myEventCallbackCommand->SetCallback( SMESHGUI::ProcessEvents );
2083   myPriority = 0.0;
2084
2085   /* load resources for all available meshers */
2086   SMESH::InitAvailableHypotheses();
2087 }
2088
2089 //=============================================================================
2090 /*!
2091  *
2092  */
2093 //=============================================================================
2094 SMESHGUI::~SMESHGUI()
2095 {
2096 }
2097
2098 //=============================================================================
2099 /*!
2100  *
2101  */
2102 //=============================================================================
2103 LightApp_SelectionMgr* SMESHGUI::selectionMgr()
2104 {
2105   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
2106   if( anApp )
2107     return dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
2108   else
2109     return 0;
2110 }
2111
2112 //=============================================================================
2113 /*!
2114  *
2115  */
2116 //=============================================================================
2117 bool SMESHGUI::automaticUpdate(unsigned int requestedSize, bool* limitExceeded)
2118 {
2119   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
2120   if ( !resMgr )
2121     return false;
2122
2123   bool autoUpdate  = resMgr->booleanValue( "SMESH", "auto_update",  false );
2124   long updateLimit = resMgr->integerValue( "SMESH", "update_limit", 500000 );
2125   bool exceeded = updateLimit > 0 && requestedSize > updateLimit;
2126   if ( limitExceeded ) *limitExceeded = autoUpdate && exceeded;
2127   return autoUpdate && !exceeded;
2128 }
2129
2130 //=============================================================================
2131 /*!
2132  *
2133  */
2134 //=============================================================================
2135 bool SMESHGUI::automaticUpdate( SMESH::SMESH_IDSource_ptr theMesh,
2136                                 int* entities, bool* limitExceeded, int* hidden, long* nbElements )
2137 {
2138   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
2139   if ( !resMgr )
2140     return false;
2141
2142   bool autoUpdate  = resMgr->booleanValue( "SMESH", "auto_update", false );
2143   long updateLimit = resMgr->integerValue( "SMESH", "update_limit", 500000 );
2144   bool incrementalLimit = resMgr->booleanValue( "SMESH", "incremental_limit", false );
2145
2146   SMESH::long_array_var info = theMesh->GetMeshInfo();
2147   long nbOdElems = info[SMDSEntity_0D];
2148   long nbEdges   = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
2149   long nbFaces   = info[SMDSEntity_Triangle]   + info[SMDSEntity_Quad_Triangle]   + info[SMDSEntity_BiQuad_Triangle] +
2150                    info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle] +
2151                    info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
2152   long nbVolumes = info[SMDSEntity_Tetra]   + info[SMDSEntity_Quad_Tetra] +
2153                    info[SMDSEntity_Hexa]    + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] +
2154                    info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid] +
2155                    info[SMDSEntity_Penta]   + info[SMDSEntity_Quad_Penta] + info[SMDSEntity_BiQuad_Penta] +
2156                    info[SMDSEntity_Polyhedra] +
2157                    info[SMDSEntity_Hexagonal_Prism];
2158   long nbBalls   = info[SMDSEntity_Ball];
2159
2160   long requestedSize = nbOdElems + nbBalls + nbEdges + nbFaces + nbVolumes;
2161   *nbElements = requestedSize;
2162
2163   *entities = SMESH_Actor::eAllEntity;
2164   *hidden   = 0;
2165
2166   bool exceeded = updateLimit > 0 && requestedSize > updateLimit;
2167
2168   if ( limitExceeded ) *limitExceeded = autoUpdate && exceeded;
2169
2170   if ( incrementalLimit ) {
2171     long total     = 0;
2172
2173     if ( nbOdElems > 0 ) {
2174       if ( total + nbOdElems > updateLimit ) {
2175         *entities = *entities & ~SMESH_Actor::e0DElements;
2176         *hidden = *hidden | SMESH_Actor::e0DElements;
2177       }
2178       else
2179         exceeded = false;
2180     }
2181     total += nbOdElems;
2182
2183     if ( nbEdges > 0 ) {
2184       if ( total + nbEdges > updateLimit ) {
2185         *entities = *entities & ~SMESH_Actor::eEdges;
2186         *hidden = *hidden | SMESH_Actor::eEdges;
2187       }
2188       else
2189         exceeded = false;
2190     }
2191     total += nbEdges;
2192
2193     if ( nbFaces > 0 ) {
2194       if ( total + nbFaces > updateLimit ) {
2195         *entities = *entities & ~SMESH_Actor::eFaces;
2196         *hidden = *hidden | SMESH_Actor::eFaces;
2197       }
2198       else
2199         exceeded = false;
2200     }
2201     total += nbFaces;
2202
2203     if ( nbVolumes > 0 ) {
2204       if ( total + nbVolumes > updateLimit ) {
2205         *entities = *entities & ~SMESH_Actor::eVolumes;
2206         *hidden = *hidden | SMESH_Actor::eVolumes;
2207       }
2208       else
2209         exceeded = false;
2210     }
2211     total += nbVolumes;
2212
2213     if ( nbBalls > 0 ) {
2214       if ( total + nbBalls > updateLimit ) {
2215         *entities = *entities & ~SMESH_Actor::eBallElem;
2216         *hidden = *hidden | SMESH_Actor::eBallElem;
2217       }
2218       else
2219         exceeded = false;
2220     }
2221     total += nbBalls;
2222   }
2223
2224   return autoUpdate && !exceeded;
2225 }
2226
2227 //=============================================================================
2228 /*!
2229  *
2230  */
2231 //=============================================================================
2232 SUIT_ResourceMgr* SMESHGUI::resourceMgr()
2233 {
2234   return dynamic_cast<SUIT_ResourceMgr*>( SUIT_Session::session()->resourceMgr() );
2235 }
2236
2237 //=============================================================================
2238 /*!
2239  *
2240  */
2241 //=============================================================================
2242 SMESHGUI* SMESHGUI::GetSMESHGUI()
2243 {
2244   SMESHGUI* smeshMod = 0;
2245   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>(SUIT_Session::session()->activeApplication());
2246   if ( app )
2247   {
2248     CAM_Module* module = app->module( "Mesh" );
2249     smeshMod = dynamic_cast<SMESHGUI*>( module );
2250   }
2251
2252   return smeshMod;
2253 }
2254
2255 extern "C"
2256 {
2257   Standard_EXPORT SMESHGUI* GetComponentGUI()
2258   {
2259     return SMESHGUI::GetSMESHGUI();
2260   }
2261 }
2262
2263 //=============================================================================
2264 /*!
2265  *
2266  */
2267 //=============================================================================
2268 void SMESHGUI::SetState(int aState)
2269 {
2270   myState = aState;
2271 }
2272
2273 //=============================================================================
2274 /*!
2275  *
2276  */
2277 //=============================================================================
2278 void SMESHGUI::ResetState()
2279 {
2280   myState = -1;
2281 }
2282
2283 //=============================================================================
2284 /*!
2285  *
2286  */
2287 //=============================================================================
2288 void SMESHGUI::EmitSignalDeactivateDialog()
2289 {
2290   emit SignalDeactivateActiveDialog();
2291 }
2292
2293 //=============================================================================
2294 /*!
2295  *
2296  */
2297 //=============================================================================
2298 void SMESHGUI::EmitSignalStudyFrameChanged()
2299 {
2300   emit SignalStudyFrameChanged();
2301 }
2302
2303 //=============================================================================
2304 /*!
2305  *
2306  */
2307 //=============================================================================
2308 void SMESHGUI::EmitSignalCloseAllDialogs()
2309 {
2310   emit SignalCloseAllDialogs();
2311 }
2312
2313 //=============================================================================
2314 /*!
2315  *
2316  */
2317 //=============================================================================
2318 void SMESHGUI::EmitSignalVisibilityChanged()
2319 {
2320   emit SignalVisibilityChanged();
2321 }
2322
2323 //=============================================================================
2324 /*!
2325  *
2326  */
2327 //=============================================================================
2328 void SMESHGUI::EmitSignalCloseView()
2329 {
2330   emit SignalCloseView();
2331 }
2332
2333 //=============================================================================
2334 /*!
2335  *
2336  */
2337 //=============================================================================
2338 void SMESHGUI::EmitSignalActivatedViewManager()
2339 {
2340   emit SignalActivatedViewManager();
2341 }
2342
2343 //=============================================================================
2344 /*!
2345  *
2346  */
2347 //=============================================================================
2348 QDialog *SMESHGUI::GetActiveDialogBox()
2349 {
2350   return myActiveDialogBox;
2351 }
2352
2353 //=============================================================================
2354 /*!
2355  *
2356  */
2357 //=============================================================================
2358 void SMESHGUI::SetActiveDialogBox(QDialog * aDlg)
2359 {
2360   myActiveDialogBox = (QDialog *) aDlg;
2361   return;
2362 }
2363
2364 //=============================================================================
2365 /*!
2366  *
2367  */
2368 //=============================================================================
2369 SUIT_Desktop* SMESHGUI::desktop()
2370 {
2371   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
2372   if( app )
2373     return app->desktop();
2374   else
2375     return 0;
2376 }
2377
2378 //=============================================================================
2379 /*!
2380  *
2381  */
2382 //=============================================================================
2383 SalomeApp_Study* SMESHGUI::activeStudy()
2384 {
2385   SUIT_Application* app = SUIT_Session::session()->activeApplication();
2386   if( app )
2387     return dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
2388   else
2389     return NULL;
2390 }
2391
2392 //=============================================================================
2393 /*!
2394  *
2395  */
2396 //=============================================================================
2397 void SMESHGUI::Modified( bool theIsUpdateActions )
2398 {
2399   if( SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() ) ) {
2400     if( SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() ) ) {
2401       appStudy->Modified();
2402       if( theIsUpdateActions )
2403         app->updateActions();
2404     }
2405   }
2406 }
2407
2408 //=============================================================================
2409 /*!
2410  *
2411  */
2412 //=============================================================================
2413 bool SMESHGUI::DefineDlgPosition(QWidget * aDlg, int &x, int &y)
2414 {
2415   /* Here the position is on the bottom right corner - 10 */
2416   // aDlg->resize(QSize().expandedTo(aDlg->minimumSizeHint()));
2417   aDlg->adjustSize();
2418   SUIT_Desktop *PP = desktop();
2419   x = abs(PP->x() + PP->size().width() - aDlg->size().width() - 10);
2420   y = abs(PP->y() + PP->size().height() - aDlg->size().height() - 10);
2421   return true;
2422 }
2423
2424 /*!
2425  * \brief Verifies whether study of operation is locked
2426   * \param theMess - specifies whether message box must be shown if study is locked
2427   * \return State of study.
2428 *
2429 * Verifies whether study of operation is locked. If second parameter is TRUE and study
2430 * is locked when corresponding message box appears
2431 */
2432 bool SMESHGUI::isStudyLocked( bool theMessage )
2433 {
2434   if ( SMESH::getStudy()->GetProperties()->IsLocked() )
2435   {
2436     if ( theMessage )
2437       SUIT_MessageBox::warning( SMESHGUI::desktop(),
2438                                 QObject::tr( "WRN_WARNING" ),
2439                                 QObject::tr( "WRN_STUDY_LOCKED" ) );
2440     return true;
2441   }
2442   return false;
2443 }
2444
2445 //=============================================================================
2446 /*!
2447  *
2448  */
2449 //=============================================================================
2450 bool SMESHGUI::OnGUIEvent( int theCommandID )
2451 {
2452   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( application() );
2453   if( !anApp )
2454     return false;
2455
2456   SUIT_ResourceMgr* mgr = resourceMgr();
2457   if( !mgr )
2458     return false;
2459
2460   SUIT_ViewWindow* view = application()->desktop()->activeWindow();
2461   SVTK_ViewWindow* vtkwnd = dynamic_cast<SVTK_ViewWindow*>( view );
2462
2463   //QAction* act = action( theCommandID );
2464
2465   switch (theCommandID) {
2466   case SMESHOp::OpDelete:
2467     if(isStudyLocked()) break;
2468     OnEditDelete();
2469     break;
2470   case SMESHOp::OpImportDAT:
2471   case SMESHOp::OpImportUNV:
2472   case SMESHOp::OpImportMED:
2473   case SMESHOp::OpImportSTL:
2474   case SMESHOp::OpImportCGNS:
2475   case SMESHOp::OpImportSAUV:
2476   case SMESHOp::OpImportGMF:
2477   case SMESHOp::OpPopupImportDAT:
2478   case SMESHOp::OpPopupImportUNV:
2479   case SMESHOp::OpPopupImportMED:
2480   case SMESHOp::OpPopupImportSTL:
2481   case SMESHOp::OpPopupImportCGNS:
2482   case SMESHOp::OpPopupImportSAUV:
2483   case SMESHOp::OpPopupImportGMF:
2484     {
2485       if(isStudyLocked()) break;
2486       ::ImportMeshesFromFile(GetSMESHGen(),theCommandID);
2487       break;
2488     }
2489
2490   case SMESHOp::OpFileInformation:
2491     {
2492       SALOME_ListIO selected;
2493       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
2494       if( aSel )
2495         aSel->selectedObjects( selected );
2496       if( selected.Extent() )
2497       {
2498         Handle(SALOME_InteractiveObject) anIObject = selected.First();
2499         SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(anIObject);
2500         if ( !aMesh->_is_nil() )
2501         {
2502           SMESHGUI_FileInfoDlg dlg( desktop(), aMesh->GetMEDFileInfo() );
2503           dlg.exec();
2504         }
2505       }
2506       break;
2507     }
2508   case SMESHOp::OpExportDAT:
2509   case SMESHOp::OpExportMED:
2510   case SMESHOp::OpExportUNV:
2511   case SMESHOp::OpExportSTL:
2512   case SMESHOp::OpExportCGNS:
2513   case SMESHOp::OpExportSAUV:
2514   case SMESHOp::OpExportGMF:
2515   case SMESHOp::OpPopupExportDAT:
2516   case SMESHOp::OpPopupExportMED:
2517   case SMESHOp::OpPopupExportUNV:
2518   case SMESHOp::OpPopupExportSTL:
2519   case SMESHOp::OpPopupExportCGNS:
2520   case SMESHOp::OpPopupExportSAUV:
2521   case SMESHOp::OpPopupExportGMF:
2522     {
2523       ::ExportMeshToFile(theCommandID);
2524       break;
2525     }
2526
2527   case SMESHOp::OpReset:                      // SCALAR BAR
2528     {
2529       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
2530       SALOME_ListIO selected;
2531       if( aSel )
2532         aSel->selectedObjects( selected );
2533
2534       SALOME_ListIteratorOfListIO it(selected);
2535       for( ; it.More(); it.Next()) {
2536         Handle(SALOME_InteractiveObject) anIO = it.Value();
2537         if( anIO->hasEntry() ) {
2538           if( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) {
2539             anActor->SetControlMode( SMESH_Actor::eNone );
2540 #ifndef DISABLE_PLOT2DVIEWER
2541             SMESH::ProcessIn2DViewers(anActor,SMESH::RemoveFrom2dViewer);
2542 #endif
2543           }
2544         }
2545       }
2546       SMESH::UpdateView();
2547       break;
2548     }
2549   case SMESHOp::OpScalarBarProperties:
2550     {
2551       SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( this );
2552       break;
2553     }
2554   case SMESHOp::OpShowScalarBar:
2555     {
2556       // show/hide scalar bar
2557       ::ShowElement(theCommandID);
2558       break;
2559     }
2560   case SMESHOp::OpSaveDistribution:
2561     {
2562       // dump control distribution data to the text file
2563       ::SaveDistribution();
2564       break;
2565     }
2566
2567   case SMESHOp::OpShowDistribution:
2568     {
2569       // show/hide distribution
2570       ::ShowElement(theCommandID);
2571       break;
2572     }
2573
2574 #ifndef DISABLE_PLOT2DVIEWER
2575   case SMESHOp::OpPlotDistribution:
2576     {
2577       // plot distribution
2578       ::PlotDistribution();
2579       break;
2580     }
2581 #endif
2582
2583     // Auto-color
2584   case SMESHOp::OpAutoColor:
2585     ::AutoColor();
2586   break;
2587
2588   case SMESHOp::OpDisableAutoColor:
2589     ::DisableAutoColor();
2590   break;
2591
2592   case SMESHOp::OpClipping:
2593   case SMESHOp::OpTransparency:
2594   case SMESHOp::OpProperties: // Display preferences (colors, shrink size, line width, ...)
2595
2596     // Display Mode
2597   case SMESHOp::OpDMWireframe:
2598   case SMESHOp::OpDMShading:
2599   case SMESHOp::OpDMNodes:
2600   case SMESHOp::OpDMShrink:
2601     ::SetDisplayMode(theCommandID, myMarkerMap);
2602   break;
2603
2604   //2D quadratic representation
2605   case SMESHOp::OpRepresentationLines:
2606   case SMESHOp::OpRepresentationArcs:
2607     ::SetDisplayMode(theCommandID, myMarkerMap);
2608   break;
2609
2610   // Display Entity
2611   case SMESHOp::OpDE0DElements:
2612   case SMESHOp::OpDEEdges:
2613   case SMESHOp::OpDEFaces:
2614   case SMESHOp::OpDEVolumes:
2615   case SMESHOp::OpDEBalls:
2616   case SMESHOp::OpDEAllEntity:
2617     ::SetDisplayEntity(theCommandID);
2618   break;
2619
2620   // Choose entities to be displayed
2621   case SMESHOp::OpDEChoose:
2622     {
2623       ( new SMESHGUI_DisplayEntitiesDlg( SMESHGUI::desktop() ) )->exec();
2624       break;
2625     }
2626
2627   case SMESHOp::OpOrientationOnFaces:
2628     {
2629       SUIT_OverrideCursor wc;
2630       LightApp_SelectionMgr* mgr = selectionMgr();
2631       SALOME_ListIO selected; mgr->selectedObjects( selected );
2632
2633       SALOME_ListIteratorOfListIO it(selected);
2634       for( ; it.More(); it.Next()) {
2635         Handle(SALOME_InteractiveObject) anIObject = it.Value();
2636         if(anIObject->hasEntry()) {
2637           if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){
2638             anActor->SetFacesOriented( !anActor->GetFacesOriented() );
2639           }
2640         }
2641       }
2642       break;
2643     }
2644
2645   case SMESHOp::OpUpdate:
2646     {
2647       if(isStudyLocked()) break;
2648       SUIT_OverrideCursor wc;
2649       try {
2650         OCC_CATCH_SIGNALS;
2651         SMESH::UpdateView();
2652       }
2653       catch (std::bad_alloc) { // PAL16774 (Crash after display of many groups)
2654         SMESH::OnVisuException();
2655       }
2656       catch (...) { // PAL16774 (Crash after display of many groups)
2657         SMESH::OnVisuException();
2658       }
2659
2660       SALOME_ListIO l;
2661       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
2662       aSel->selectedObjects( l );
2663       aSel->setSelectedObjects( l );
2664       break;
2665     }
2666
2667   case SMESHOp::OpHide:
2668   case SMESHOp::OpShow:
2669   case SMESHOp::OpShowOnly:
2670     {
2671       SUIT_OverrideCursor wc;
2672       SMESH::EDisplaing anAction;
2673       switch (theCommandID) {
2674       case SMESHOp::OpHide:     anAction = SMESH::eErase; break;
2675       case SMESHOp::OpShow:     anAction = SMESH::eDisplay; break;
2676       case SMESHOp::OpShowOnly: anAction = SMESH::eDisplayOnly; break;
2677       }
2678
2679       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
2680       SALOME_ListIO sel_objects, to_process;
2681       if (aSel)
2682         aSel->selectedObjects( sel_objects );
2683
2684       if ( theCommandID==SMESHOp::OpShowOnly )
2685       {
2686         //MESSAGE("anAction = SMESH::eDisplayOnly");
2687         startOperation( myEraseAll );
2688       }
2689
2690       extractContainers( sel_objects, to_process );
2691
2692       try {
2693         OCC_CATCH_SIGNALS;
2694         if (vtkwnd) {
2695           SALOME_ListIteratorOfListIO It( to_process );
2696           for ( ; It.More(); It.Next())
2697           {
2698             Handle(SALOME_InteractiveObject) IOS = It.Value();
2699             if ( IOS->hasEntry() )
2700             {
2701               if ( !SMESH::UpdateView( anAction, IOS->getEntry() )) {
2702                 SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged();
2703                 break; // PAL16774 (Crash after display of many groups)
2704               }
2705               if (anAction == SMESH::eDisplayOnly)
2706                 anAction = SMESH::eDisplay;
2707             }
2708           }
2709         }
2710
2711         // PAL13338 + PAL15161 -->
2712         if ( ( theCommandID==SMESHOp::OpShow || theCommandID==SMESHOp::OpShowOnly ) && !isStudyLocked()) {
2713           SMESH::UpdateView();
2714           SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged();
2715         }
2716         // PAL13338 + PAL15161 <--
2717       }
2718       catch (...) { // PAL16774 (Crash after display of many groups)
2719         SMESH::OnVisuException();
2720       }
2721
2722       if (anAction == SMESH::eErase) {
2723         SALOME_ListIO l1;
2724         aSel->setSelectedObjects( l1 );
2725       }
2726       else
2727         aSel->setSelectedObjects( to_process );
2728
2729       break;
2730     }
2731
2732   case SMESHOp::OpNode:
2733     {
2734       if(isStudyLocked()) break;
2735
2736       if ( vtkwnd ) {
2737         EmitSignalDeactivateDialog();
2738
2739         ( new SMESHGUI_NodesDlg( this ) )->show();
2740       }
2741       else {
2742         SUIT_MessageBox::warning(desktop(),tr("SMESH_WRN_WARNING"),tr("SMESH_WRN_VIEWER_VTK"));
2743       }
2744       break;
2745     }
2746
2747   case SMESHOp::OpCreateMesh:
2748   case SMESHOp::OpCreateSubMesh:
2749   case SMESHOp::OpEditMeshOrSubMesh:
2750   case SMESHOp::OpEditMesh:
2751   case SMESHOp::OpEditSubMesh:
2752   case SMESHOp::OpCompute:
2753   case SMESHOp::OpComputeSubMesh:
2754   case SMESHOp::OpPreCompute:
2755   case SMESHOp::OpEvaluate:
2756   case SMESHOp::OpMeshOrder:
2757     startOperation( theCommandID );
2758     break;
2759   case SMESHOp::OpCopyMesh:
2760     {
2761       if (isStudyLocked()) break;
2762       EmitSignalDeactivateDialog();
2763       ( new SMESHGUI_CopyMeshDlg( this ) )->show();
2764     }
2765     break;
2766   case SMESHOp::OpBuildCompoundMesh:
2767     {
2768       if (isStudyLocked()) break;
2769       EmitSignalDeactivateDialog();
2770       ( new SMESHGUI_BuildCompoundDlg( this ) )->show();
2771     }
2772     break;
2773
2774   case SMESHOp::OpDiagonalInversion:
2775   case SMESHOp::OpUnionOfTwoTriangle:
2776     {
2777       if ( !vtkwnd )
2778       {
2779         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), tr( "NOT_A_VTK_VIEWER" ) );
2780         break;
2781       }
2782
2783       if ( isStudyLocked() )
2784         break;
2785
2786       /*Standard_Boolean aRes;
2787       SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IObject);
2788       if ( aMesh->_is_nil() )
2789       {
2790         SUIT_MessageBox::warning(GetDesktop(), tr( "SMESH_WRN_WARNING" ),
2791           tr( "SMESH_BAD_SELECTION" ) );
2792         break;
2793       }
2794       */
2795       EmitSignalDeactivateDialog();
2796       if ( theCommandID == SMESHOp::OpDiagonalInversion )
2797         ( new SMESHGUI_TrianglesInversionDlg( this ) )->show();
2798       else
2799         ( new SMESHGUI_UnionOfTwoTrianglesDlg( this ) )->show();
2800       break;
2801     }
2802   case SMESHOp::OpOrientation:
2803   case SMESHOp::OpUnionOfTriangles:
2804   case SMESHOp::OpCuttingOfQuadrangles:
2805   case SMESHOp::OpSplitVolumes:
2806     {
2807       if ( !vtkwnd )
2808       {
2809         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), tr( "NOT_A_VTK_VIEWER" ) );
2810         break;
2811       }
2812
2813       if ( isStudyLocked() )
2814         break;
2815
2816       EmitSignalDeactivateDialog();
2817       SMESHGUI_MultiEditDlg* aDlg = NULL;
2818       if ( theCommandID == SMESHOp::OpOrientation )
2819         aDlg = new SMESHGUI_ChangeOrientationDlg(this);
2820       else if ( theCommandID == SMESHOp::OpUnionOfTriangles )
2821         aDlg = new SMESHGUI_UnionOfTrianglesDlg(this);
2822       else if ( theCommandID == SMESHOp::OpSplitVolumes )
2823         aDlg = new SMESHGUI_SplitVolumesDlg(this);
2824       else
2825         aDlg = new SMESHGUI_CuttingOfQuadsDlg(this);
2826
2827       aDlg->show();
2828       break;
2829     }
2830   case SMESHOp::OpSmoothing:
2831     {
2832       if(isStudyLocked()) break;
2833       if( vtkwnd ) {
2834         EmitSignalDeactivateDialog();
2835         ( new SMESHGUI_SmoothingDlg( this ) )->show();
2836       }
2837       else {
2838         SUIT_MessageBox::warning(desktop(), tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
2839       }
2840       break;
2841     }
2842   case SMESHOp::OpExtrusion:
2843     {
2844       if (isStudyLocked()) break;
2845       if (vtkwnd) {
2846         EmitSignalDeactivateDialog();
2847         ( new SMESHGUI_ExtrusionDlg ( this ) )->show();
2848       } else {
2849         SUIT_MessageBox::warning(desktop(),tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
2850       }
2851       break;
2852     }
2853   case SMESHOp::OpExtrusionAlongAPath:
2854     {
2855       if (isStudyLocked()) break;
2856       if (vtkwnd) {
2857         EmitSignalDeactivateDialog();
2858         ( new SMESHGUI_ExtrusionAlongPathDlg( this ) )->show();
2859       } else {
2860         SUIT_MessageBox::warning(desktop(),tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
2861       }
2862       break;
2863     }
2864   case SMESHOp::OpRevolution:
2865     {
2866       if(isStudyLocked()) break;
2867       if( vtkwnd ) {
2868         EmitSignalDeactivateDialog();
2869         ( new SMESHGUI_RevolutionDlg( this ) )->show();
2870       }
2871       else {
2872         SUIT_MessageBox::warning(desktop(),tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
2873       }
2874       break;
2875     }
2876   case SMESHOp::OpPatternMapping:
2877     {
2878       if ( isStudyLocked() )
2879         break;
2880       if ( vtkwnd )
2881       {
2882         EmitSignalDeactivateDialog();
2883         ( new SMESHGUI_MeshPatternDlg( this ) )->show();
2884       }
2885       else {
2886         SUIT_MessageBox::warning(desktop(),tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
2887       }
2888       break;
2889     }
2890   case SMESHOp::OpSplitBiQuadratic:
2891   case SMESHOp::OpConvertMeshToQuadratic:
2892   case SMESHOp::OpCreateBoundaryElements: // create 2D mesh from 3D
2893   case SMESHOp::OpReorientFaces:
2894   case SMESHOp::OpCreateGeometryGroup:
2895     {
2896       startOperation( theCommandID );
2897       break;
2898     }
2899   case SMESHOp::OpCreateGroup:
2900     {
2901       if ( !vtkwnd )
2902       {
2903         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),tr( "NOT_A_VTK_VIEWER" ) );
2904         break;
2905       }
2906
2907       if(isStudyLocked()) break;
2908       EmitSignalDeactivateDialog();
2909       SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_nil();
2910
2911       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
2912       SALOME_ListIO selected;
2913       if( aSel )
2914         aSel->selectedObjects( selected );
2915
2916       int nbSel = selected.Extent();
2917       if (nbSel == 1) {
2918         // check if mesh is selected
2919         aMesh = SMESH::GetMeshByIO( selected.First() );
2920       }
2921       SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, aMesh);
2922       aDlg->show();
2923       break;
2924     }
2925
2926   case SMESHOp::OpConstructGroup:
2927     {
2928       if ( !vtkwnd )
2929       {
2930         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),tr( "NOT_A_VTK_VIEWER" ) );
2931         break;
2932       }
2933
2934       if(isStudyLocked()) break;
2935       EmitSignalDeactivateDialog();
2936
2937       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
2938       SALOME_ListIO selected;
2939       if( aSel )
2940         aSel->selectedObjects( selected );
2941
2942       int nbSel = selected.Extent();
2943       if (nbSel == 1) {
2944         // check if submesh is selected
2945         Handle(SALOME_InteractiveObject) IObject = selected.First();
2946         if (IObject->hasEntry()) {
2947           _PTR(SObject) aSObj = SMESH::getStudy()->FindObjectID(IObject->getEntry());
2948           if( aSObj ) {
2949             SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( aSObj ) );
2950             if (!aSubMesh->_is_nil()) {
2951               try {
2952                 SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
2953                 // get submesh elements list by types
2954                 SMESH::long_array_var aNodes = aSubMesh->GetElementsByType(SMESH::NODE);
2955                 SMESH::long_array_var aEdges = aSubMesh->GetElementsByType(SMESH::EDGE);
2956                 SMESH::long_array_var aFaces = aSubMesh->GetElementsByType(SMESH::FACE);
2957                 SMESH::long_array_var aVolumes = aSubMesh->GetElementsByType(SMESH::VOLUME);
2958                 // create group for each type o elements
2959                 QString aName = IObject->getName();
2960                 QStringList anEntryList;
2961                 if (aNodes->length() > 0) {
2962                   SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::NODE, aName + "_Nodes");
2963                   aGroup->Add(aNodes.inout());
2964                   if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) )
2965                     anEntryList.append( aSObject->GetID().c_str() );
2966                 }
2967                 if (aEdges->length() > 0) {
2968                   SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::EDGE, aName + "_Edges");
2969                   aGroup->Add(aEdges.inout());
2970                   if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) )
2971                     anEntryList.append( aSObject->GetID().c_str() );
2972                 }
2973                 if (aFaces->length() > 0) {
2974                   SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::FACE, aName + "_Faces");
2975                   aGroup->Add(aFaces.inout());
2976                   if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) )
2977                     anEntryList.append( aSObject->GetID().c_str() );
2978                 }
2979                 if (aVolumes->length() > 0) {
2980                   SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::VOLUME, aName + "_Volumes");
2981                   aGroup->Add(aVolumes.inout());
2982                   if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) )
2983                     anEntryList.append( aSObject->GetID().c_str() );
2984                 }
2985                 updateObjBrowser();
2986                 anApp->browseObjects( anEntryList );
2987               }
2988               catch(const SALOME::SALOME_Exception & S_ex){
2989                 SalomeApp_Tools::QtCatchCorbaException(S_ex);
2990               }
2991             }
2992           }
2993         }
2994       }
2995       else if(nbSel==0) {
2996         SUIT_MessageBox::warning(desktop(),
2997                                  tr("SMESH_WRN_WARNING"),
2998                                  tr("SMESH_WRN_NO_AVAILABLE_DATA"));
2999       }
3000       break;
3001     }
3002
3003   case SMESHOp::OpEditGroup:
3004     {
3005       if ( !vtkwnd )
3006       {
3007         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),tr( "NOT_A_VTK_VIEWER" ) );
3008         break;
3009       }
3010
3011       if(isStudyLocked()) break;
3012       EmitSignalDeactivateDialog();
3013
3014       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
3015       SALOME_ListIO selected;
3016       if( aSel )
3017         aSel->selectedObjects( selected );
3018
3019       SALOME_ListIteratorOfListIO It (selected);
3020       int nbSelectedGroups = 0;
3021       for ( ; It.More(); It.Next() )
3022       {
3023         SMESH::SMESH_GroupBase_var aGroup =
3024           SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(It.Value());
3025         if (!aGroup->_is_nil()) {
3026           nbSelectedGroups++;
3027           SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, aGroup);
3028           aDlg->show();
3029         }
3030       }
3031       if (nbSelectedGroups == 0)
3032         {
3033           SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, SMESH::SMESH_GroupBase::_nil());
3034           aDlg->show();
3035         }
3036       break;
3037     }
3038
3039   case SMESHOp::OpAddElemGroupPopup:     // Add elements to group
3040     {
3041       if(isStudyLocked()) break;
3042       if (myState == 800) {
3043         SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox;
3044         if (aDlg) aDlg->onAdd();
3045       }
3046       break;
3047     }
3048
3049   case SMESHOp::OpRemoveElemGroupPopup:  // Remove elements from group
3050     {
3051       if(isStudyLocked()) break;
3052       if (myState == 800) {
3053         SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox;
3054         if (aDlg) aDlg->onRemove();