Salome HOME
Messages for sewing and pattern mapping dialogs, concerning polygons and polyedres...
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MeshPatternDlg.cxx
1 //  SMESH SMESHGUI : GUI for SMESH component
2 //
3 //  Copyright (C) 2003  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. 
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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESHGUI_MeshPatternDlg.cxx
25 //  Author : Sergey LITONIN
26 //  Module : SMESH
27
28 #include "SMESHGUI_MeshPatternDlg.h"
29
30 #include "QAD_Desktop.h"
31 #include "QAD_FileDlg.h"
32
33 #include "SMESHGUI_SpinBox.h"
34 #include "SMESHGUI.h"
35 #include "SALOME_Selection.h"
36 #include "SMESH_NumberFilter.hxx"
37 #include "SMESHGUI_Utils.h"
38 #include "SMESHGUI_VTKUtils.h"
39 #include "SMESHGUI_CreatePatternDlg.h"
40 #include "SMESHGUI_PatternWidget.h"
41 #include "SMESH_Actor.h"
42 #include "SALOMEGUI_QtCatchCorbaException.hxx"
43 #include "VTKViewer_ViewFrame.h"
44 #include "SMESHGUI_PatternUtils.h"
45 #include "SMESH_ActorUtils.h"
46 #include "SMDS_MeshElement.hxx"
47 #include "SMDS_Mesh.hxx"
48
49 #include "QAD_Config.h"
50
51 #include <TColStd_MapOfInteger.hxx>
52
53 #include <qframe.h>
54 #include <qlayout.h>
55 #include <qlineedit.h>
56 #include <qpushbutton.h>
57 #include <qgroupbox.h>
58 #include <qlabel.h>
59 #include <qradiobutton.h>
60 #include <qcheckbox.h>
61 #include <qbuttongroup.h>
62 #include <qmessagebox.h>
63 #include <qcstring.h>
64 #include <qspinbox.h>
65 #include <qvaluelist.h>
66
67 #include <vtkCell.h>
68 #include <vtkIdList.h>
69 #include <vtkIntArray.h>
70 #include <vtkCellArray.h>
71 #include <vtkUnsignedCharArray.h>
72 #include <vtkUnstructuredGrid.h>
73 #include <vtkDataSetMapper.h>
74
75 #define SPACING 5
76 #define MARGIN  10
77
78 /*
79   Class       : SMESHGUI_MeshPatternDlg
80   Description : Dialog to specify filters for VTK viewer
81 */
82
83 //=======================================================================
84 // name    : SMESHGUI_MeshPatternDlg::SMESHGUI_MeshPatternDlg
85 // Purpose : Constructor
86 //=======================================================================
87 SMESHGUI_MeshPatternDlg::SMESHGUI_MeshPatternDlg( QWidget*          theParent,
88                                             SALOME_Selection* theSelection,
89                                             const char*       theName )
90 : QDialog( theParent, theName, false,
91           WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ),
92   myBusy( false )
93 {
94   setCaption( tr( "CAPTION" ) );
95
96   QVBoxLayout* aDlgLay = new QVBoxLayout( this, MARGIN, SPACING );
97
98   QFrame* aMainFrame = createMainFrame  ( this );
99   QFrame* aBtnFrame  = createButtonFrame( this );
100
101
102
103
104   aDlgLay->addWidget( aMainFrame );
105   aDlgLay->addWidget( aBtnFrame );
106
107   aDlgLay->setStretchFactor( aMainFrame, 1 );
108
109   myCreationDlg = 0;
110   Init( theSelection );
111 }
112
113 //=======================================================================
114 // name    : SMESHGUI_MeshPatternDlg::createMainFrame
115 // Purpose : Create frame containing dialog's input fields
116 //=======================================================================
117 QFrame* SMESHGUI_MeshPatternDlg::createMainFrame( QWidget* theParent )
118 {
119   QPixmap iconSlct( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH", tr( "ICON_SELECT" ) ) );
120   QPixmap icon2d  ( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH", tr( "ICON_PATTERN_2d" ) ) );
121   QPixmap icon3d  ( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH", tr( "ICON_PATTERN_3d" ) ) );
122   QPixmap iconOpen( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH", tr( "ICON_FILE_OPEN" ) ) );
123
124   QPixmap iconSample2d( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH", tr( "ICON_PATTERN_SAMPLE_2D" ) ) );
125   QPixmap iconSample3d( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH", tr( "ICON_PATTERN_SAMPLE_3D" ) ) );
126
127   QGroupBox* aMainGrp = new QGroupBox( 1, Qt::Horizontal, theParent );
128   aMainGrp->setFrameStyle( QFrame::NoFrame );
129   aMainGrp->setInsideMargin( 0 );
130
131   // Pattern type group
132   
133   myTypeGrp = new QButtonGroup( 1, Qt::Vertical, tr( "PATTERN_TYPE" ), aMainGrp );
134   mySwitch2d = new QRadioButton( myTypeGrp );
135   mySwitch3d = new QRadioButton( myTypeGrp );
136   mySwitch2d->setPixmap( icon2d );
137   mySwitch3d->setPixmap( icon3d );
138   myTypeGrp->insert( mySwitch2d, Type_2d );
139   myTypeGrp->insert( mySwitch3d, Type_3d );
140
141
142   // Mesh group
143   
144   QGroupBox* aMeshGrp = new QGroupBox( 1, Qt::Vertical, tr( "SMESH_MESH" ), aMainGrp );
145   new QLabel( tr( "SMESH_MESH" ), aMeshGrp );
146   mySelBtn[ Mesh ] = new QPushButton( aMeshGrp );
147   mySelBtn[ Mesh ]->setPixmap( iconSlct );
148   mySelEdit[ Mesh ] = new QLineEdit( aMeshGrp );
149   mySelEdit[ Mesh ]->setReadOnly( true );
150
151   // Pattern group
152   
153   QGroupBox* aPatGrp = new QGroupBox( 1, Qt::Horizontal, tr( "PATTERN" ), aMainGrp );
154
155   // pattern name
156   QGroupBox* aNameGrp = new QGroupBox( 1, Qt::Vertical, aPatGrp );
157   aNameGrp->setFrameStyle( QFrame::NoFrame );
158   aNameGrp->setInsideMargin( 0 );
159   new QLabel( tr( "PATTERN" ), aNameGrp );
160   myName = new QLineEdit( aNameGrp );
161   myName->setReadOnly( true );
162   myOpenBtn = new QPushButton( aNameGrp );
163   myOpenBtn->setPixmap( iconOpen );
164   myNewBtn = new QPushButton( tr( "NEW" ), aNameGrp );
165
166   // Mode selection check box
167   myRefine = new QCheckBox( tr( "REFINE" ), aPatGrp );
168
169   // selection widgets for Apply to geom mode
170   myGeomGrp = new QGroupBox( 3, Qt::Horizontal, aPatGrp );
171   myGeomGrp->setFrameStyle( QFrame::NoFrame );
172   myGeomGrp->setInsideMargin( 0 );
173
174   for ( int i = Object; i <= Vertex2; i++ )
175   {
176     mySelLbl[ i ] = new QLabel( myGeomGrp );
177     mySelBtn[ i ] = new QPushButton( myGeomGrp );
178     mySelBtn[ i ]->setPixmap( iconSlct );
179     mySelEdit[ i ] = new QLineEdit( myGeomGrp );
180     mySelEdit[ i ]->setReadOnly( true );
181   }
182
183   // Widgets for refinement of existing mesh elements
184   myRefineGrp = new QFrame( aPatGrp );
185   myRefineGrp->setFrameStyle( QFrame::NoFrame );
186   QGridLayout* aRefGrid = new QGridLayout( myRefineGrp, 3, 3, 0, 5 );
187
188   mySelLbl[ Ids ] = new QLabel( myRefineGrp );
189   mySelBtn[ Ids ] = new QPushButton( myRefineGrp );
190   mySelBtn[ Ids ]->setPixmap( iconSlct );
191   mySelEdit[ Ids ] = new QLineEdit( myRefineGrp );
192
193   QLabel* aNodeLbl = new QLabel( tr( "NODE_1" ), myRefineGrp );
194   myNode1          = new QSpinBox( myRefineGrp );
195   myNode2Lbl       = new QLabel( tr( "NODE_2" ), myRefineGrp );
196   myNode2          = new QSpinBox( myRefineGrp );
197
198   aRefGrid->addWidget( mySelLbl [ Ids ], 0, 0 );
199   aRefGrid->addWidget( mySelBtn [ Ids ], 0, 1 );
200   aRefGrid->addWidget( mySelEdit[ Ids ], 0, 2 );
201   aRefGrid->addWidget( aNodeLbl, 1, 0 );
202   aRefGrid->addMultiCellWidget( myNode1, 1, 1, 1, 2 );
203   aRefGrid->addWidget( myNode2Lbl, 2, 0 );
204   aRefGrid->addMultiCellWidget( myNode2, 2, 2, 1, 2 );
205
206   // reverse check box
207   myReverseChk = new QCheckBox( tr( "REVERSE" ), aPatGrp );
208
209   // CreatePoly check box
210   myCreatePolygonsChk = new QCheckBox( tr( "CREATE_POLYGONS_NEAR_BOUNDARY" ), aPatGrp );
211   myCreatePolyedrsChk = new QCheckBox( tr( "CREATE_POLYEDRS_NEAR_BOUNDARY" ), aPatGrp );
212
213   // Pictures 2d and 3d
214   for ( int i = 0; i < 2; i++ )
215   {
216     if ( i == 0 )
217     {
218       myPicture2d = new SMESHGUI_PatternWidget( aPatGrp ),
219       myPicture2d->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
220     }
221     else
222     {
223       myPicture3d = new QFrame( aPatGrp ),
224       myPreview3d = new QLabel( myPicture3d );
225       myPreview3d->setPixmap( iconSample3d );
226       QGridLayout* aLay = new QGridLayout( myPicture3d, 3, 3, 0, 0 );
227       QSpacerItem* aSpacerH1 = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
228       QSpacerItem* aSpacerH2 = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
229       QSpacerItem* aSpacerV1 = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding );
230       QSpacerItem* aSpacerV2 = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding );
231       aLay->addItem( aSpacerH1, 1, 0 );
232       aLay->addItem( aSpacerH2, 1, 2 );
233       aLay->addItem( aSpacerV1, 0, 1 );
234       aLay->addItem( aSpacerV2, 2, 1 );
235       aLay->addWidget( myPreview3d, 1, 1 );
236     }
237   }
238
239   myPreviewChk = new QCheckBox( tr( "PREVIEW" ), aPatGrp );
240
241   // Connect signals and slots
242
243   connect( myTypeGrp,      SIGNAL( clicked( int )  ),               SLOT( onTypeChanged( int ) ) );
244   connect( myOpenBtn,      SIGNAL( clicked()       ),               SLOT( onOpen()             ) );
245   connect( myNewBtn,       SIGNAL( clicked()       ),               SLOT( onNew()              ) );
246   connect( myReverseChk,   SIGNAL( toggled( bool ) ),               SLOT( onReverse( bool )    ) );
247   connect( myPreviewChk,   SIGNAL( toggled( bool ) ),               SLOT( onPreview( bool )    ) );
248   connect( myRefine,       SIGNAL( toggled( bool ) ),               SLOT( onModeToggled( bool ) ) );
249   connect( myNode1,        SIGNAL( valueChanged( int ) ),           SLOT( onNodeChanged( int ) ) );
250   connect( myNode2,        SIGNAL( valueChanged( int ) ),           SLOT( onNodeChanged( int ) ) );
251   connect( mySelEdit[Ids], SIGNAL( textChanged( const QString& ) ), SLOT( onTextChanged( const QString& ) ) );
252
253   QMap< int, QPushButton* >::iterator anIter;
254   for ( anIter = mySelBtn.begin(); anIter != mySelBtn.end(); ++anIter )
255     connect( *anIter, SIGNAL( clicked() ), SLOT( onSelInputChanged() ) );
256
257   return aMainGrp;
258 }
259
260 //=======================================================================
261
262 // name    : SMESHGUI_MeshPatternDlg::createButtonFrame
263 // Purpose : Create frame containing buttons
264 //=======================================================================
265 QFrame* SMESHGUI_MeshPatternDlg::createButtonFrame( QWidget* theParent )
266 {
267   QFrame* aFrame = new QFrame( theParent );
268   aFrame->setFrameStyle( QFrame::Box | QFrame::Sunken );
269
270   myOkBtn     = new QPushButton( tr( "SMESH_BUT_OK"    ), aFrame );
271   myApplyBtn  = new QPushButton( tr( "SMESH_BUT_APPLY" ), aFrame );
272   myCloseBtn  = new QPushButton( tr( "SMESH_BUT_CLOSE" ), aFrame );
273
274   QSpacerItem* aSpacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
275
276   QHBoxLayout* aLay = new QHBoxLayout( aFrame, MARGIN, SPACING );
277
278   aLay->addWidget( myOkBtn );
279   aLay->addWidget( myApplyBtn );
280   aLay->addItem( aSpacer);
281   aLay->addWidget( myCloseBtn );
282
283   connect( myOkBtn,    SIGNAL( clicked() ), SLOT( onOk() ) );
284   connect( myCloseBtn, SIGNAL( clicked() ), SLOT( onClose() ) ) ;
285   connect( myApplyBtn, SIGNAL( clicked() ), SLOT( onApply() ) );
286
287   return aFrame;
288 }
289
290 //=======================================================================
291 // name    : SMESHGUI_MeshPatternDlg::~SMESHGUI_MeshPatternDlg
292 // Purpose : Destructor
293 //=======================================================================
294 SMESHGUI_MeshPatternDlg::~SMESHGUI_MeshPatternDlg()
295 {
296 }
297
298 //=======================================================================
299 // name    : SMESHGUI_MeshPatternDlg::Init
300 // Purpose : Init dialog fields, connect signals and slots, show dialog
301 //=======================================================================
302 void SMESHGUI_MeshPatternDlg::Init( SALOME_Selection* theSelection )
303 {
304   myPattern = SMESH::GetPattern();
305   myPreviewActor = 0;
306   myIsCreateDlgOpen = false;
307   mySelInput = Mesh;
308   myType = -1;
309   myNbPoints = -1;
310   mySelection = theSelection;
311   SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
312   aSMESHGUI->SetActiveDialogBox( ( QDialog* )this );
313   myMesh = SMESH::SMESH_Mesh::_nil();
314
315   myMeshShape = GEOM::GEOM_Object::_nil();
316   myGeomObj[ Object  ] = GEOM::GEOM_Object::_nil();
317   myGeomObj[ Vertex1 ] = GEOM::GEOM_Object::_nil();
318   myGeomObj[ Vertex2 ] = GEOM::GEOM_Object::_nil();
319
320   // selection and SMESHGUI
321   connect( mySelection, SIGNAL( currentSelectionChanged() ), SLOT( onSelectionDone() ) );
322   connect( aSMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( onDeactivate() ) );
323   connect( aSMESHGUI, SIGNAL( SignalCloseAllDialogs() ), SLOT( onClose() ) );
324
325   myTypeGrp->setButton( Type_2d );
326   onTypeChanged( Type_2d );
327   onModeToggled( isRefine() );
328
329   updateGeometry();
330
331   resize( minimumSize() );
332
333   activateSelection();
334   onSelectionDone();
335
336   int x, y ;
337   aSMESHGUI->DefineDlgPosition( this, x, y );
338   this->move( x, y );
339   this->show();
340 }
341
342 //=======================================================================
343 // name    : SMESHGUI_MeshPatternDlg::isValid
344 // Purpose : Verify validity of entry data
345 //=======================================================================
346 bool SMESHGUI_MeshPatternDlg::isValid( const bool theMess )
347 {
348   QValueList<int> ids;
349   if ( ( isRefine() && ( myMesh->_is_nil() || !getIds( ids ) || getNode( false ) < 0 || myType == Type_3d && ( getNode( true ) < 0 || getNode( false ) == getNode( true ) ) ) ) 
350        || ( !isRefine() && ( myMesh->_is_nil() || myMeshShape->_is_nil() || myGeomObj[ Object ]->_is_nil() ||
351        myGeomObj[ Vertex1 ]->_is_nil() || myType == Type_3d && myGeomObj[ Vertex2 ]->_is_nil() ) ) )
352   {
353     if ( theMess )
354       QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
355         tr( "SMESH_INSUFFICIENT_DATA" ), tr( "SMESHGUI_INVALID_PARAMETERS" ), QMessageBox::Ok );
356     return false;
357   }
358   else
359     return true;
360 }
361
362 //=======================================================================
363 // name    : SMESHGUI_MeshPatternDlg::onApply
364 // Purpose : SLOT called when "Apply" button pressed.
365 //=======================================================================
366 bool SMESHGUI_MeshPatternDlg::onApply()
367 {
368   try
369   {
370     if ( !isValid() )
371       return false;
372
373     erasePreview();
374
375     if ( isRefine() ) { // Refining existing mesh elements
376       QValueList<int> ids;
377       getIds( ids );
378       SMESH::long_array_var varIds = new SMESH::long_array();
379       varIds->length( ids.count() );
380       int i = 0;
381       for ( QValueList<int>::iterator it = ids.begin(); it != ids.end(); ++it )
382         varIds[i++] = *it;
383       myType == Type_2d
384         ? myPattern->ApplyToMeshFaces  ( myMesh, varIds, getNode( false ), myReverseChk->isChecked() )
385         : myPattern->ApplyToHexahedrons( myMesh, varIds, getNode( false ), getNode( true ) );
386     }
387     else { // Applying a pattern to geometrical object
388     if ( myType == Type_2d )
389       myPattern->ApplyToFace(
390         myGeomObj[ Object ], myGeomObj[ Vertex1 ], myReverseChk->isChecked() );
391     else
392       myPattern->ApplyTo3DBlock(
393         myGeomObj[ Object ], myGeomObj[ Vertex1 ], myGeomObj[ Vertex2 ] );
394     }
395
396     bool toCreatePolygons = myCreatePolygonsChk->isChecked();
397     bool toCreatePolyedrs = myCreatePolyedrsChk->isChecked();
398
399     if ( myPattern->MakeMesh( myMesh, toCreatePolygons, toCreatePolyedrs ) )
400     {
401       mySelection->ClearIObjects();
402       SMESHGUI* aCompGUI = SMESHGUI::GetSMESHGUI();
403       if ( !isRefine() && !QAD_CONFIG->getSetting( "SMESH:AutomaticUpdate" ).compare( "true" ) ) {
404         SALOMEDS::SObject_var aSO = SMESH::FindSObject( myMesh.in() );
405         SMESH_Actor* anActor = SMESH::FindActorByEntry( aSO->GetID() );
406         if(!anActor){
407           anActor = SMESH::CreateActor( aSO->GetStudy(), aSO->GetID() );
408           if(anActor){
409             SMESH::DisplayActor( aCompGUI->GetActiveStudy()->getActiveStudyFrame(), anActor );
410             SMESH::FitAll();
411           }
412         }
413       }
414       SMESH::UpdateView();
415
416       aCompGUI->GetActiveStudy()->updateObjBrowser( true );
417       return true;
418     }
419     else
420     {
421       QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
422         tr( "SMESH_ERROR" ), tr( "SMESH_OPERATION_FAILED" ), QMessageBox::Ok );
423       return false;
424     }
425   }
426   catch( const SALOME::SALOME_Exception& S_ex )
427   {
428     QtCatchCorbaException( S_ex );    
429   }
430   catch( ... )
431   {
432   }
433
434   return false;
435 }
436
437 //=======================================================================
438 // name    : SMESHGUI_MeshPatternDlg::onOk
439 // Purpose : SLOT called when "Ok" button pressed.
440 //=======================================================================
441 void SMESHGUI_MeshPatternDlg::onOk()
442 {
443   if ( onApply() )
444     onClose();
445 }
446
447 //=======================================================================
448 // name    : SMESHGUI_MeshPatternDlg::onClose
449 // Purpose : SLOT called when "Close" button pressed. Close dialog
450 //=======================================================================
451 void SMESHGUI_MeshPatternDlg::onClose()
452 {
453   mySelection->ClearFilters();
454   SMESH::SetPickable();
455   QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
456   disconnect( mySelection, 0, this, 0 );
457   disconnect( SMESHGUI::GetSMESHGUI(), 0, this, 0 );
458   SMESHGUI::GetSMESHGUI()->ResetState();
459   erasePreview();
460   reject();
461 }
462
463
464
465 //=======================================================================
466 // name    : SMESHGUI_MeshPatternDlg::onSelectionDone
467 // Purpose : SLOT called when selection changed
468 //=======================================================================
469 void SMESHGUI_MeshPatternDlg::onSelectionDone()
470 {
471   if ( myBusy )
472     return;
473   
474   try
475   {
476     if ( mySelInput == Mesh )
477     {
478       if ( mySelection->IObjectCount() != 1 )
479         return;
480
481       // Retrieve mesh from selection
482       Handle(SALOME_InteractiveObject) anIO = mySelection->firstIObject();
483       SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>( anIO );
484       if ( aMesh->_is_nil() )
485         return;
486
487       // Get geom object corresponding to the mesh
488       SALOMEDS::Study_var aStudy =
489         SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getStudyDocument();
490
491       SALOMEDS::SObject_var aSO = SMESH::FindSObject( aMesh.in() );
492       if ( aSO->_is_nil() )
493         return;
494
495       bool isFound = false;
496       SALOMEDS::ChildIterator_var anIter = aStudy->NewChildIterator( aSO );
497       for( ; anIter->More(); anIter->Next() )
498       {
499         SALOMEDS::SObject_var aSO = anIter->Value();
500         SALOMEDS::SObject_var aRefSO;
501
502         GEOM::GEOM_Object_var aMeshShape = GEOM::GEOM_Object::_narrow(
503           aSO->ReferencedObject( aRefSO )? aRefSO->GetObject() : aSO->GetObject() );
504
505         if ( !aMeshShape->_is_nil() )
506         {
507           isFound = true;
508           myMeshShape = aMeshShape;
509           break;
510
511         }
512       }
513
514       if ( !isFound )
515         myMeshShape = GEOM::GEOM_Object::_nil();
516
517       // Clear fields of geom objects if mesh was changed
518       if ( myMesh != aMesh )
519       {
520         for ( int i = Object; i <= Ids; i++ )
521         {
522           myGeomObj[ i ] = GEOM::GEOM_Object::_nil();
523           mySelEdit[ i ]->setText( "" );
524         }
525       }
526
527       myMesh = aMesh;
528
529       // Set name of mesh in line edit
530       QString aName;
531       SMESH::GetNameOfSelectedIObjects( mySelection, aName );
532       mySelEdit[ Mesh ]->setText( aName );
533     }
534     else if ( mySelInput == Ids ) {
535       QString anIds;
536       if ( !SMESH::GetNameOfSelectedElements( mySelection, anIds ) )
537         anIds = "";
538  
539       myBusy = true;
540       mySelEdit[ Ids ]->setText( anIds );
541       myBusy = false;
542     }
543     else
544     {
545       if ( mySelection->IObjectCount() != 1 )
546         return;
547
548       // Get geom object from selection
549       Handle(SALOME_InteractiveObject) anIO = mySelection->firstIObject();
550       GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>( anIO );
551       if ( anObj->_is_nil() )
552         return;
553
554       // Clear fields of vertexes if face or 3d block was changed
555       if ( anObj != myGeomObj[ mySelInput ] && mySelInput == Object )
556       {
557         for ( int i = Vertex1; i <= Vertex2; i++ )
558         {
559           myGeomObj[ i ] = GEOM::GEOM_Object::_nil();
560           mySelEdit[ i ]->setText( "" );
561         }
562       }
563
564       myGeomObj[ mySelInput ] = anObj;
565
566       // Set name of geom object in line edit
567       QString aName;
568       SMESH::GetNameOfSelectedIObjects( mySelection, aName );
569       mySelEdit[ mySelInput ]->setText( aName );
570     }
571   }
572   catch( const SALOME::SALOME_Exception& S_ex )
573   {
574     QtCatchCorbaException( S_ex );
575     resetSelInput();
576   }
577   catch( ... )
578   {
579     resetSelInput();
580   }
581
582   updateWgState();
583   displayPreview();
584 }
585
586 //=======================================================================
587 // name    : SMESHGUI_MeshPatternDlg::resetSelInput
588 // Purpose : Reset fields corresponding to the current selection input
589 //=======================================================================
590 void SMESHGUI_MeshPatternDlg::resetSelInput()
591 {
592   if ( mySelInput == Mesh )
593   {
594     myMesh = SMESH::SMESH_Mesh::_nil();
595     myMeshShape = GEOM::GEOM_Object::_nil();
596   }
597
598   else
599     myGeomObj[ mySelInput ] = GEOM::GEOM_Object::_nil();
600
601   mySelEdit[ mySelInput ]->setText( "" );
602 }
603
604 //=======================================================================
605 // name    : SMESHGUI_MeshPatternDlg::onDeactivate
606 // Purpose : SLOT called when dialog must be deativated
607 //=======================================================================
608 void SMESHGUI_MeshPatternDlg::onDeactivate()
609 {
610   mySelection->ClearFilters();
611   //if ( myReverseChk->isChecked() )
612   //  erasePreview();
613   disconnect( mySelection, 0, this, 0 );
614   setEnabled( false );
615 }
616
617 //=======================================================================
618 // name    : SMESHGUI_MeshPatternDlg::enterEvent
619 // Purpose : Event filter
620 //=======================================================================
621 void SMESHGUI_MeshPatternDlg::enterEvent( QEvent* )
622 {
623   if ( myIsCreateDlgOpen )
624     return;
625     
626   if ( myReverseChk->isChecked() )
627     displayPreview();
628   SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog() ;
629   setEnabled( true );
630   activateSelection();
631   connect( mySelection, SIGNAL( currentSelectionChanged() ), SLOT( onSelectionDone() ) );
632   onTextChanged( mySelEdit[Ids]->text() );
633 }
634
635
636 //=================================================================================
637 // function : closeEvent()
638 // purpose  :
639 //=================================================================================
640 void SMESHGUI_MeshPatternDlg::closeEvent( QCloseEvent* e )
641 {
642   onClose() ;
643 }
644
645 //=======================================================================
646 // name    : SMESHGUI_MeshPatternDlg::onSelInputChanged
647 // Purpose : SLOT. Called when -> button clicked.
648 //           Change current selection input field
649 //=======================================================================
650 void SMESHGUI_MeshPatternDlg::onSelInputChanged()
651 {
652   const QObject* aSender = sender();
653   for ( int i = Mesh; i <= Ids; i++ )
654     if ( aSender == mySelBtn[ i ] )
655       mySelInput = i;
656
657   activateSelection();
658   onSelectionDone();
659 }
660
661 //=======================================================================
662 // name    : SMESHGUI_MeshPatternDlg::prepareFilters
663 // Purpose : Prepare filters for dialog
664 //=======================================================================
665
666 QStringList SMESHGUI_MeshPatternDlg::prepareFilters() const
667 {
668   static QStringList aList;
669   if ( aList.isEmpty() )
670   {
671     aList.append( tr( "PATTERN_FILT" ) );
672     //aList.append( tr( "ALL_FILES_FILTER" ) );
673   }
674
675   return aList;
676 }
677
678 //================================================================
679
680 // Function : SMESHGUI_MeshPatternDlg::autoExtension
681 // Purpose  : Append extension to the file name
682 //================================================================
683 QString SMESHGUI_MeshPatternDlg::autoExtension( const QString& theFileName ) const
684 {
685   QString anExt = theFileName.section( '.', -1 );
686   return anExt != "smp" && anExt != "SMP" ? theFileName + ".smp" : theFileName;
687 }
688
689 //=======================================================================
690 // name    : SMESHGUI_MeshPatternDlg::onOpen
691 // Purpose : SLOT. Called when "Open" button clicked.
692 //           Displays file open dialog
693 //=======================================================================
694 void SMESHGUI_MeshPatternDlg::onOpen()
695 {
696   QAD_FileDlg* aDlg = new QAD_FileDlg( this, true );
697   aDlg->setCaption( tr( "LOAD_PATTERN" ) );
698   aDlg->setMode( QFileDialogP::ExistingFile );
699   aDlg->setFilters( prepareFilters() );
700   if ( myName->text() != "" )
701     aDlg->setSelection( myName->text() + ".smp" );
702   QPushButton* anOkBtn = ( QPushButton* )aDlg->child( "OK", "QPushButton" );
703   if ( anOkBtn != 0 )
704     anOkBtn->setText( tr( "SMESH_BUT_OK" ) );
705
706   if ( aDlg->exec() != Accepted )
707     return;
708
709   QString fName = aDlg->selectedFile();
710   if ( fName.isEmpty() )
711     return;
712
713   if ( QFileInfo( fName ).extension().isEmpty() )
714     fName = autoExtension( fName );
715
716   fName = QDir::convertSeparators( fName );
717   
718   QString prev = QDir::convertSeparators( myName->text() );
719   if ( prev == fName )
720     return;
721
722   // Read string from file
723   QFile aFile( fName );
724   if ( !aFile.open( IO_ReadOnly ) )
725   {
726     QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
727       tr( "SMESH_ERROR" ), tr( "ERROR_OF_OPENING" ), QMessageBox::Ok );
728     return;
729   }
730   
731   QByteArray aDataArray = aFile.readAll();
732   const char* aData = aDataArray.data();
733   if ( aData == 0 )
734   {
735     QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
736       tr( "SMESH_ERROR" ), tr( "ERROR_OF_READING" ), QMessageBox::Ok );
737     return;
738   }
739   
740   if ( loadFromFile( aData ) )
741     myName->setText( QFileInfo( fName ).baseName() );
742     
743   updateWgState();
744   displayPreview();
745 }
746
747 //=======================================================================
748 // name    : SMESHGUI_MeshPatternDlg::onCloseCreationDlg
749 // Purpose : SLOT. Called when "Pattern creation" dialog closed with "Close"
750 //=======================================================================
751 void SMESHGUI_MeshPatternDlg::onCloseCreationDlg()
752 {
753   setEnabled( true );
754   myIsCreateDlgOpen = false;
755 }
756
757
758 //=======================================================================
759 // name    : SMESHGUI_MeshPatternDlg::onOkCreationDlg
760 // Purpose : SLOT. Called when "Pattern creation" dialog closed with OK
761 //           or SAVE buttons. Initialize myPattern field. Redisplay preview
762 //=======================================================================
763 void SMESHGUI_MeshPatternDlg::onOkCreationDlg()
764 {
765   myPattern = SMESH::SMESH_Pattern::_duplicate( myCreationDlg->GetPattern() );
766   myName->setText( myCreationDlg->GetPatternName() );
767   displayPreview();
768   setEnabled( true );
769   myIsCreateDlgOpen = false;
770 }
771
772
773 //=======================================================================
774 // name    : SMESHGUI_MeshPatternDlg::onNew
775 // Purpose : SLOT. Called when "New..." button clicked. Create new pattern
776 //=======================================================================
777 void SMESHGUI_MeshPatternDlg::onNew()
778 {
779   setEnabled( false );
780   myIsCreateDlgOpen = true;
781   if ( myCreationDlg == 0 )
782   {
783     myCreationDlg = new SMESHGUI_CreatePatternDlg( this, mySelection, myType );
784     connect( myCreationDlg, SIGNAL( NewPattern() ), SLOT( onOkCreationDlg() ) );
785     connect( myCreationDlg, SIGNAL( Close() ), SLOT( onCloseCreationDlg() ) );
786   }
787   else
788     myCreationDlg->Init( mySelection, myType );
789
790   myCreationDlg->SetMesh( myMesh );
791   myCreationDlg->show();
792 }
793
794 //=======================================================================
795 // name    : SMESHGUI_MeshPatternDlg::onReverse
796 // Purpose : SLOT. Called when state of "Reverse order..." checkbox chaged
797 //           Calculate new points of the mesh to be created. Redisplay preview
798 //=======================================================================
799 void SMESHGUI_MeshPatternDlg::onReverse( bool )
800 {
801   displayPreview();
802 }
803
804 //=======================================================================
805
806 // name    : SMESHGUI_MeshPatternDlg::onPreview
807 // Purpose : SLOT. Called when state of "Preview" checkbox changed
808 //           Display/Erase preview
809 //=======================================================================
810 void SMESHGUI_MeshPatternDlg::onPreview( bool )
811 {
812   displayPreview();
813 }
814
815 //=======================================================================
816 // name    : SMESHGUI_MeshPatternDlg::displayPreview
817 // Purpose : Display preview
818 //=======================================================================
819 void SMESHGUI_MeshPatternDlg::displayPreview()
820 {
821   try
822   {
823     // Redisplay preview in dialog
824
825     SMESH::point_array_var pnts = myPattern->GetPoints();
826     SMESH::long_array_var keyPoints = myPattern->GetKeyPoints();
827     SMESH::array_of_long_array_var elemPoints = myPattern->GetElementPoints(false);
828
829     if ( pnts->length()       == 0 ||
830          keyPoints->length()  == 0 ||
831          elemPoints->length() == 0 )
832     {
833       erasePreview();
834       return;
835     }
836
837     else
838     {
839       PointVector aPoints( pnts->length() );
840       QValueVector<int> aKeyPoints( keyPoints->length() );
841       ConnectivityVector anElemPoints( elemPoints->length() );
842
843       for ( int i = 0, n = pnts->length(); i < n; i++ )
844         aPoints[ i ] = pnts[ i ];
845
846       for ( int i2 = 0, n2 = keyPoints->length(); i2 < n2; i2++ )
847         aKeyPoints[ i2 ] = keyPoints[ i2 ];
848
849       for ( int i3 = 0, n3 = elemPoints->length(); i3 < n3; i3++ )
850       {
851         QValueVector<int> aVec( elemPoints[ i3 ].length() );
852         for ( int i4 = 0, n4 = elemPoints[ i3 ].length(); i4 < n4; i4++ )
853           aVec[ i4 ] = elemPoints[ i3 ][ i4 ];
854
855         anElemPoints[ i3 ] = aVec;
856       }
857
858       myPicture2d->SetPoints( aPoints, aKeyPoints, anElemPoints );
859     }
860
861
862     // Redisplay preview in 3D viewer
863
864     if ( myPreviewActor != 0 )
865     {
866       if ( VTKViewer_ViewFrame* vf = SMESH::GetCurrentVtkView() )
867       {
868         vf->RemoveActor(myPreviewActor);
869         vf->Repaint();
870       }
871       myPreviewActor->Delete();
872       myPreviewActor = 0;
873     }
874
875     if ( !myPreviewChk->isChecked() || !isValid( false ) )
876       return;
877
878     vtkUnstructuredGrid* aGrid = getGrid();
879     if ( aGrid == 0 )
880       return;
881
882     // Create and display actor
883     vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
884     aMapper->SetInput( aGrid );
885
886     myPreviewActor = SALOME_Actor::New();
887     myPreviewActor->PickableOff();
888     myPreviewActor->SetMapper( aMapper );
889
890     vtkProperty* aProp = vtkProperty::New();
891     aProp->SetRepresentationToWireframe();
892     aProp->SetColor( 250, 0, 250 );
893     if ( SMESH::FindActorByObject( myMesh ) )
894       aProp->SetLineWidth( SMESH::GetFloat( "SMESH:SettingsWidth", 1 ) +1 );
895     else
896       aProp->SetLineWidth( 1 );
897     myPreviewActor->SetProperty( aProp );
898
899     myPreviewActor->SetRepresentation( 3 );
900
901     SMESH::GetCurrentVtkView()->AddActor( myPreviewActor );
902     SMESH::GetCurrentVtkView()->Repaint();
903
904     aProp->Delete();
905     aGrid->Delete();
906   }
907   catch( const SALOME::SALOME_Exception& S_ex )
908   {
909     QtCatchCorbaException( S_ex );
910     erasePreview();
911   }
912   catch( ... )
913   {
914     erasePreview();
915   }
916 }
917
918 //=======================================================================
919 // name    : SMESHGUI_MeshPatternDlg::erasePreview
920 // Purpose : Erase preview
921 //=======================================================================
922 void SMESHGUI_MeshPatternDlg::erasePreview()
923 {
924   // Erase preview in 2D viewer
925   myPicture2d->SetPoints( PointVector(), QValueVector<int>(), ConnectivityVector() );
926
927   // Erase preview in 3D viewer
928   if ( myPreviewActor == 0 )
929     return;
930
931
932   if ( VTKViewer_ViewFrame* vf = SMESH::GetCurrentVtkView() )
933   {
934     vf->RemoveActor(myPreviewActor);
935     vf->Repaint();
936   }
937   myPreviewActor->Delete();
938   myPreviewActor = 0;
939 }
940
941 //=======================================================================
942 // name    : SMESHGUI_MeshPatternDlg::updateWgState
943 // Purpose : Enable/disable selection widgets
944 //=======================================================================
945 void SMESHGUI_MeshPatternDlg::updateWgState()
946 {
947   if ( myMesh->_is_nil() )
948   {
949     for ( int i = Object; i <= Ids; i++ )
950     {
951       mySelBtn [ i ]->setEnabled( false );
952       mySelEdit[ i ]->setEnabled( false );
953       mySelEdit[ i ]->setText( "" );
954     }
955     myNode1->setEnabled( false );
956     myNode2->setEnabled( false );
957     myNode1->setRange( 0, 0 );
958     myNode2->setRange( 0, 0 );
959   }
960   else
961   {
962     mySelBtn [ Object ]->setEnabled( true );
963     mySelEdit[ Object ]->setEnabled( true );
964     mySelBtn [ Ids ]   ->setEnabled( true );
965     mySelEdit[ Ids ]   ->setEnabled( true );
966     
967     if ( myGeomObj[ Object ]->_is_nil() )
968     {
969       for ( int i = Vertex1; i <= Vertex2; i++ )
970       {
971         mySelBtn [ i ]->setEnabled( false );
972         mySelEdit[ i ]->setEnabled( false );
973         mySelEdit[ i ]->setText( "" );
974       }
975     }
976     else
977     {
978       for ( int i = Object; i <= Vertex2; i++ )
979       {
980         mySelBtn [ i ]->setEnabled( true );
981         mySelEdit[ i ]->setEnabled( true );
982       }
983     }
984
985     QValueList<int> ids;
986     if ( !CORBA::is_nil( myPattern ) && getIds( ids ) ) {
987       SMESH::long_array_var keyPoints = myPattern->GetKeyPoints();
988       if ( keyPoints->length() ) {
989         myNode1->setEnabled( true );
990         myNode2->setEnabled( true );
991         myNode1->setRange( 1, keyPoints->length() );
992         myNode2->setRange( 1, keyPoints->length() );
993         return;
994       }
995     }
996
997     myNode1->setEnabled( false );
998     myNode2->setEnabled( false );
999     myNode1->setRange( 0, 0 );
1000     myNode2->setRange( 0, 0 );
1001   }
1002 }
1003
1004 //=======================================================================
1005 // name    : SMESHGUI_MeshPatternDlg::activateSelection
1006 // Purpose : Activate selection in accordance with current selection input
1007 //=======================================================================
1008 void SMESHGUI_MeshPatternDlg::activateSelection()
1009 {
1010   mySelection->ClearFilters();
1011   if ( mySelInput == Ids ) {
1012     SMESH_Actor* anActor = SMESH::FindActorByObject( myMesh );
1013     if ( anActor )
1014       SMESH::SetPickable(anActor);
1015
1016     if ( myType == Type_2d )
1017       QAD_Application::getDesktop()->SetSelectionMode( FaceSelection, true );
1018     else
1019       QAD_Application::getDesktop()->SetSelectionMode( CellSelection, true );
1020   }
1021   else {
1022     SMESH::SetPickable();
1023   QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
1024   }
1025   
1026   if ( mySelInput == Object && !myMeshShape->_is_nil() )
1027   {
1028     if ( myType == Type_2d )
1029     {
1030       if ( myNbPoints > 0 )
1031         mySelection->AddFilter( new SMESH_NumberFilter( 
1032
1033           "GEOM", TopAbs_VERTEX, myNbPoints, TopAbs_FACE, myMeshShape ) );
1034       else
1035         mySelection->AddFilter( new SMESH_NumberFilter(
1036           "GEOM", TopAbs_SHAPE, myNbPoints, TopAbs_FACE, myMeshShape ) );
1037     }
1038     else
1039     {
1040       TColStd_MapOfInteger aTypes;
1041       aTypes.Add( TopAbs_SHELL );
1042       aTypes.Add( TopAbs_SOLID );
1043       mySelection->AddFilter( new SMESH_NumberFilter(
1044         "GEOM", TopAbs_FACE, 6, aTypes, myMeshShape, true ) );
1045     }
1046   }
1047   else if ( ( mySelInput == Vertex1 || mySelInput == Vertex2 ) && !myGeomObj[ Object ]->_is_nil()  )
1048   {
1049     mySelection->AddFilter( new SMESH_NumberFilter(
1050       "GEOM", TopAbs_SHAPE, 1, TopAbs_VERTEX, myGeomObj[ Object ] ) );
1051   }
1052 }
1053
1054 //=======================================================================
1055 // name    : SMESHGUI_MeshPatternDlg::loadFromFile
1056 // Purpose : Load pattern from file
1057 //=======================================================================
1058 bool SMESHGUI_MeshPatternDlg::loadFromFile( const QString& theName )
1059 {
1060   try
1061   {
1062     SMESH::SMESH_Pattern_var aPattern = SMESH::GetPattern();
1063
1064     if ( !aPattern->LoadFromFile( theName.latin1() ) ||
1065          myType == Type_2d && !aPattern->Is2D())
1066     {
1067       SMESH::SMESH_Pattern::ErrorCode aCode = aPattern->GetErrorCode();
1068       QString aMess;
1069       if      ( aCode == SMESH::SMESH_Pattern::ERR_READ_NB_POINTS      ) aMess = tr( "ERR_READ_NB_POINTS" );
1070       else if ( aCode == SMESH::SMESH_Pattern::ERR_READ_POINT_COORDS   ) aMess = tr( "ERR_READ_POINT_COORDS" );
1071       else if ( aCode == SMESH::SMESH_Pattern::ERR_READ_TOO_FEW_POINTS ) aMess = tr( "ERR_READ_TOO_FEW_POINTS" );
1072       else if ( aCode == SMESH::SMESH_Pattern::ERR_READ_3D_COORD       ) aMess = tr( "ERR_READ_3D_COORD" );
1073       else if ( aCode == SMESH::SMESH_Pattern::ERR_READ_NO_KEYPOINT    ) aMess = tr( "ERR_READ_NO_KEYPOINT" );
1074       else if ( aCode == SMESH::SMESH_Pattern::ERR_READ_BAD_INDEX      ) aMess = tr( "ERR_READ_BAD_INDEX" );
1075       else if ( aCode == SMESH::SMESH_Pattern::ERR_READ_ELEM_POINTS    ) aMess = tr( "ERR_READ_ELEM_POINTS" );
1076       else if ( aCode == SMESH::SMESH_Pattern::ERR_READ_NO_ELEMS       ) aMess = tr( "ERR_READ_NO_ELEMS" );
1077       else if ( aCode == SMESH::SMESH_Pattern::ERR_READ_BAD_KEY_POINT  ) aMess = tr( "ERR_READ_BAD_KEY_POINT" );
1078       else                                                               aMess = tr( "ERROR_OF_LOADING" );
1079
1080       QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
1081         tr( "SMESH_ERROR" ), aMess, QMessageBox::Ok );
1082       return false;
1083     }
1084     else
1085     {
1086       myPattern = aPattern;
1087       return true;
1088     }
1089   }
1090   catch( const SALOME::SALOME_Exception& S_ex )
1091   {
1092     QtCatchCorbaException( S_ex );
1093     QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
1094         tr( "SMESH_ERROR" ), tr( "ERROR_OF_LOADING" ), QMessageBox::Ok );
1095       return false;
1096   }
1097 }
1098
1099 //=======================================================================
1100 // name    : SMESHGUI_MeshPatternDlg::onTypeChanged
1101
1102 // Purpose : SLOT. Called when pattern type changed.
1103 //           Change dialog's look and feel
1104 //=======================================================================
1105 void SMESHGUI_MeshPatternDlg::onTypeChanged( int theType )
1106 {
1107   if ( myType == theType )
1108     return;
1109
1110   myType = theType;
1111
1112   myNbPoints = -1;
1113   myGeomObj[ Object  ] = GEOM::GEOM_Object::_nil();
1114   myGeomObj[ Vertex1 ] = GEOM::GEOM_Object::_nil();
1115   myGeomObj[ Vertex2 ] = GEOM::GEOM_Object::_nil();
1116   myPattern = SMESH::GetPattern();
1117
1118   myName->setText( "" );
1119   mySelEdit[ Object  ]->setText( "" );
1120   mySelEdit[ Vertex1 ]->setText( "" );
1121   mySelEdit[ Vertex2 ]->setText( "" );
1122   mySelEdit[ Ids ]    ->setText( "" );
1123
1124   myCreatePolygonsChk->show();
1125   myCreatePolyedrsChk->show();
1126
1127   if ( theType == Type_2d )
1128   {
1129     // Geom widgets
1130     mySelLbl [ Vertex2 ]->hide();
1131     mySelBtn [ Vertex2 ]->hide();
1132     mySelEdit[ Vertex2 ]->hide();
1133     myReverseChk->show();
1134     myPicture2d->show();
1135     myPicture3d->hide();
1136     mySelLbl[ Object  ]->setText( tr( "FACE" ) );
1137     mySelLbl[ Vertex1 ]->setText( tr( "VERTEX" ) );
1138     // Refine widgets
1139     mySelLbl[ Ids ]->setText( tr( "MESH_FACES" ) );
1140     myNode2Lbl->hide();
1141     myNode2   ->hide();
1142   }
1143   else
1144   {
1145     // Geom widgets
1146     mySelLbl [ Vertex2 ]->show();
1147     mySelBtn [ Vertex2 ]->show();
1148     mySelEdit[ Vertex2 ]->show();
1149     myReverseChk->hide();
1150     myPicture2d->hide();
1151     myPicture3d->show();
1152     mySelLbl[ Object  ]->setText( tr( "3D_BLOCK" ) );
1153     mySelLbl[ Vertex1 ]->setText( tr( "VERTEX1" ) );
1154     mySelLbl[ Vertex2 ]->setText( tr( "VERTEX2" ) );
1155     // Refine widgets
1156     mySelLbl[ Ids ]->setText( tr( "MESH_VOLUMES" ) );
1157     myNode2Lbl->show();
1158     myNode2   ->show();
1159   }
1160
1161   mySelInput = Mesh;
1162   activateSelection();
1163   updateWgState();
1164   displayPreview();
1165 }
1166
1167 //=======================================================================
1168 // name    : SMESHGUI_MeshPatternDlg::getGrid
1169 // Purpose : Get unstructured grid for pattern
1170 //=======================================================================
1171 vtkUnstructuredGrid* SMESHGUI_MeshPatternDlg::getGrid()
1172 {
1173   try
1174   {
1175     // Get points from pattern
1176     SMESH::point_array_var pnts;
1177     QValueList<int> ids;
1178     if ( isRefine() && getIds( ids ) ) {
1179       SMESH::long_array_var varIds = new SMESH::long_array();
1180       varIds->length( ids.count() );
1181       int i = 0;
1182       for ( QValueList<int>::iterator it = ids.begin(); it != ids.end(); ++it )
1183         varIds[i++] = *it;
1184       pnts = myType == Type_2d
1185         ? myPattern->ApplyToMeshFaces  ( myMesh, varIds, getNode( false ), myReverseChk->isChecked() )
1186         : myPattern->ApplyToHexahedrons( myMesh, varIds, getNode( false ), getNode( true ) );
1187     }
1188     else {
1189       pnts = myType == Type_2d
1190         ? myPattern->ApplyToFace   ( myGeomObj[ Object ], myGeomObj[ Vertex1 ], myReverseChk->isChecked() )
1191       : myPattern->ApplyTo3DBlock( myGeomObj[ Object ], myGeomObj[ Vertex1 ], myGeomObj[ Vertex2 ] );
1192     }
1193
1194     SMESH::array_of_long_array_var elemPoints = myPattern->GetElementPoints(true);
1195
1196     if ( pnts->length() == 0 || elemPoints->length() == 0 )
1197       return 0;
1198
1199     
1200
1201     // to do : to be removed /////////////////////////////////////////////
1202
1203 #ifdef DEB_SLN
1204     for ( int i1 = 0, n1 = pnts->length(); i1 < n1; i1++ )
1205       printf( "%d: %g %g %g\n", i1, pnts[ i1 ].x, pnts[ i1 ].y, pnts[ i1 ].z );
1206
1207     printf( "\nELEMENTS : \n" );
1208     for ( int i2 = 0, n2 = elemPoints->length(); i2 < n2; i2++ )
1209     {
1210
1211       printf( "%d: ", i2 );
1212       for ( int i3 = 0, n3 = elemPoints[ i2 ].length(); i3 < n3; i3++ )
1213         printf( "%d ", elemPoints[ i2 ][ i3 ] );
1214
1215       printf( "\n" );
1216
1217     }
1218 #endif
1219     //////////////////////////////////////////////////////////////////////
1220
1221     // Calculate number of points used for cell
1222     vtkIdType aNbCells = elemPoints->length();
1223     vtkIdType aCellsSize = 0;
1224     for ( int i = 0, n = elemPoints->length(); i < n; i++ )
1225       aCellsSize += elemPoints[ i ].length();
1226
1227     // Create unstructured grid and other  usefull arrays
1228     vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
1229
1230     vtkCellArray* aConnectivity = vtkCellArray::New();
1231     aConnectivity->Allocate( aCellsSize, 0 );
1232
1233     vtkPoints* aPoints = vtkPoints::New();
1234     aPoints->SetNumberOfPoints( pnts->length() );
1235
1236     vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1237     aCellTypesArray->SetNumberOfComponents( 1 );
1238     aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
1239
1240     vtkIdList *anIdList = vtkIdList::New();
1241
1242     // Fill array of points
1243     for ( int p = 0, nbPnt = pnts->length(); p < nbPnt; p++ )
1244       aPoints->SetPoint( p, pnts[ p ].x, pnts[ p ].y, pnts[ p ].z );
1245
1246     for ( int e = 0, nbElem = elemPoints->length(); e < nbElem; e++ )
1247     {
1248       int nbPoints = elemPoints[ e ].length();
1249       anIdList->SetNumberOfIds( nbPoints );
1250       for ( int i = 0; i < nbPoints; i++ )
1251         anIdList->SetId( i, elemPoints[ e ][ i ] );
1252
1253       aConnectivity->InsertNextCell( anIdList );
1254
1255       if      ( nbPoints == 3 ) aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1256       else if ( nbPoints == 5 ) aCellTypesArray->InsertNextValue( VTK_PYRAMID );
1257       else if ( nbPoints == 6 ) aCellTypesArray->InsertNextValue( VTK_WEDGE );
1258       else if ( nbPoints == 8 ) aCellTypesArray->InsertNextValue( VTK_HEXAHEDRON );
1259       else if ( nbPoints == 4 && myType == Type_2d ) aCellTypesArray->InsertNextValue( VTK_QUAD );
1260       else if ( nbPoints == 4 && myType == Type_3d ) aCellTypesArray->InsertNextValue( VTK_TETRA );
1261       else aCellTypesArray->InsertNextValue( VTK_EMPTY_CELL );
1262     }
1263
1264     vtkIntArray* aCellLocationsArray = vtkIntArray::New();
1265     aCellLocationsArray->SetNumberOfComponents( 1 );
1266     aCellLocationsArray->SetNumberOfTuples( aNbCells );
1267
1268     aConnectivity->InitTraversal();
1269     for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
1270       aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
1271
1272     aGrid->SetPoints( aPoints );
1273     aGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
1274
1275     aConnectivity->Delete();
1276     aPoints->Delete();
1277     aCellTypesArray->Delete();
1278     anIdList->Delete();
1279     aCellLocationsArray->Delete();
1280
1281     return aGrid;
1282   }
1283   catch( ... )
1284   {
1285     return 0;
1286   }
1287 }
1288
1289 //=======================================================================
1290 // name    : onModeToggled
1291 // Purpose : 
1292 //=======================================================================
1293 void SMESHGUI_MeshPatternDlg::onModeToggled( bool on )
1294 {
1295   on ? myRefineGrp->show() : myRefineGrp->hide();
1296   on ? myGeomGrp->hide()   : myGeomGrp->show();
1297
1298   displayPreview();
1299 }
1300
1301 //=======================================================================
1302 // name    : isRefine
1303 // Purpose : 
1304 //=======================================================================
1305 bool SMESHGUI_MeshPatternDlg::isRefine() const
1306 {
1307   return myRefine->isChecked();
1308 }
1309
1310 //=======================================================================
1311 //function : onTextChanged
1312 //purpose  : 
1313 //=======================================================================
1314 void SMESHGUI_MeshPatternDlg::onTextChanged(const QString& theNewText)
1315 {
1316   if ( myBusy || !isRefine() )
1317     return;
1318
1319   myBusy = true;
1320
1321   if ( mySelInput != Ids ) {
1322     mySelInput = Ids;
1323     activateSelection();
1324   }
1325
1326   // hilight entered elements/nodes
1327   SMDS_Mesh* aMesh = 0;
1328   SMESH_Actor* anActor = SMESH::FindActorByObject( myMesh );
1329   if ( anActor )
1330     aMesh = anActor->GetObject()->GetMesh();
1331
1332   if ( aMesh ) {
1333     mySelection->ClearIObjects();
1334     mySelection->AddIObject( anActor->getIO() );
1335
1336     QStringList aListId = QStringList::split( " ", theNewText, false);
1337
1338     for ( int i = 0; i < aListId.count(); i++ ) {
1339       const SMDS_MeshElement * e = aMesh->FindElement( aListId[ i ].toInt() );
1340       if ( e && e->GetType() == ( myType == Type_2d ? SMDSAbs_Face : SMDSAbs_Volume ) ) {
1341         if ( !mySelection->IsIndexSelected( anActor->getIO(), e->GetID() ) )
1342           mySelection->AddOrRemoveIndex( anActor->getIO(), e->GetID(), true );
1343       }
1344     }
1345   }
1346
1347   myBusy = false;
1348 }
1349
1350 //=======================================================================
1351 //function : onNodeChanged
1352 //purpose  : 
1353 //=======================================================================
1354 void SMESHGUI_MeshPatternDlg::onNodeChanged( int value )
1355 {
1356   if ( myType == Type_3d ) {
1357     QSpinBox* first = (QSpinBox*)sender();
1358     QSpinBox* second = first == myNode1 ? myNode2 : myNode1;
1359     int secondVal = second->value();
1360     if ( secondVal == value ) {
1361       secondVal = value == second->maxValue() ? second->minValue() : value + 1;
1362       bool blocked = second->signalsBlocked();
1363       second->blockSignals( true );
1364       second->setValue( secondVal );
1365       second->blockSignals( blocked );
1366     }
1367   }
1368
1369   displayPreview();
1370 }
1371
1372 //=======================================================================
1373 //function : getIds
1374 //purpose  : 
1375 //=======================================================================
1376 bool SMESHGUI_MeshPatternDlg::getIds( QValueList<int>& ids ) const
1377 {
1378   ids.clear();
1379   QStringList strIds = QStringList::split( " ", mySelEdit[Ids]->text() );
1380   bool isOk;
1381   int val;
1382   for ( QStringList::iterator it = strIds.begin(); it != strIds.end(); ++it ) {
1383     val = (*it).toInt( &isOk );
1384     if ( isOk )
1385       ids.append( val );
1386   }
1387
1388   return ids.count();
1389 }
1390
1391 //=======================================================================
1392 //function : getNode1
1393 //purpose  : 
1394 //=======================================================================
1395 int SMESHGUI_MeshPatternDlg::getNode( bool second ) const
1396 {
1397   return second ? myNode2->value() - 1 : myNode1->value() - 1;
1398 }