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