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