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