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