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