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