Salome HOME
1daca3f9029f6ad6c56e59bb41a0f960bfd564f5
[plugins/blsurfplugin.git] / src / GUI / BLSURFPluginGUI_HypothesisCreator.cxx
1         //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // ---
20 // File    : BLSURFPluginGUI_HypothesisCreator.cxx
21 // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA)
22 //           & Aurelien ALLEAUME (DISTENE)
23 //           Size maps developement: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE)
24 // ---
25 //
26 #include "BLSURFPluginGUI_HypothesisCreator.h"
27
28 #include <SMESHGUI_Utils.h>
29 #include <SMESHGUI_HypothesesUtils.h>
30 #include <SMESHGUI_Dialog.h>
31
32 #include <SUIT_Session.h>
33 #include <SUIT_MessageBox.h>
34 #include <SUIT_ResourceMgr.h>
35 #include <SalomeApp_Tools.h>
36 #include <SalomeApp_DoubleSpinBox.h>
37
38 #include <QComboBox>
39 #include <QLabel>
40 #include <QGroupBox>
41 #include <QFrame>
42 #include <QVBoxLayout>
43 #include <QGridLayout>
44 #include <QLineEdit>
45 #include <QCheckBox>
46 #include <QTabWidget>
47 #include <QSpinBox>
48 #include <QPushButton>
49 #include <QMenu>
50 #include <QTableWidget>
51 #include <QHeaderView>
52 #include <QApplication>
53 #include <QRadioButton>
54
55 #include <LightApp_SelectionMgr.h>
56 #include <SalomeApp_Application.h>
57 #include <SALOME_ListIO.hxx>
58 #include <SALOME_ListIteratorOfListIO.hxx>
59
60 #include <GEOM_Client.hxx>
61 #include <TopoDS_Shape.hxx>
62 #include <SMESH_Gen_i.hxx>
63 #include <boost/shared_ptr.hpp>
64 #include <structmember.h>
65
66 // #include <GeomSelectionTools.h>
67 #define WITH_SIZE_BOUNDARIES
68
69 enum Topology {
70     FromCAD,
71     Process,
72     Process2
73   } ;
74
75 enum PhysicalMesh
76   {
77     DefaultSize = 0,
78     PhysicalUserDefined,
79     SizeMap
80   };
81
82 enum GeometricMesh
83   {
84     DefaultGeom = 0,
85     UserDefined
86   };
87
88 enum {
89   STD_TAB = 0,
90   ADV_TAB,
91   SMP_TAB,
92   OPTION_ID_COLUMN = 0,
93   OPTION_NAME_COLUMN,
94   OPTION_VALUE_COLUMN,
95   NB_COLUMNS,
96   SMP_ENTRY_COLUMN = 0,
97   SMP_NAME_COLUMN,
98   SMP_SIZEMAP_COLUMN,
99   SMP_NB_COLUMNS
100 };
101
102 enum {
103   SMP_BTNS = 0,
104 //   SMP_ATTRACTOR_BTN,
105 //   SMP_SEPARATOR1,
106   SMP_POINT_BTN,
107   SMP_EDGE_BTN,
108   SMP_SURFACE_BTN,
109   SMP_SEPARATOR2,
110   SMP_REMOVE_BTN,
111 };
112
113 /**************************************************
114  Begin initialization Python structures and objects
115 ***************************************************/
116
117 typedef struct {
118   PyObject_HEAD
119   int softspace;
120   std::string *out;
121   } PyStdOut;
122
123 static void
124 PyStdOut_dealloc(PyStdOut *self)
125 {
126   PyObject_Del(self);
127 }
128
129 static PyObject *
130 PyStdOut_write(PyStdOut *self, PyObject *args)
131 {
132   char *c;
133   int l;
134   if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
135     return NULL;
136
137   //std::cerr << c ;
138   *(self->out)=*(self->out)+c;
139
140   Py_INCREF(Py_None);
141   return Py_None;
142 }
143
144 static PyMethodDef PyStdOut_methods[] = {
145   {"write",  (PyCFunction)PyStdOut_write,  METH_VARARGS,
146     PyDoc_STR("write(string) -> None")},
147   {NULL,    NULL}   /* sentinel */
148 };
149
150 static PyMemberDef PyStdOut_memberlist[] = {
151   {"softspace", T_INT,  offsetof(PyStdOut, softspace), 0,
152    "flag indicating that a space needs to be printed; used by print"},
153   {NULL} /* Sentinel */
154 };
155
156 static PyTypeObject PyStdOut_Type = {
157   /* The ob_type field must be initialized in the module init function
158    * to be portable to Windows without using C++. */
159   PyObject_HEAD_INIT(NULL)
160   0,                            /*ob_size*/
161   "PyOut",                      /*tp_name*/
162   sizeof(PyStdOut),             /*tp_basicsize*/
163   0,                            /*tp_itemsize*/
164   /* methods */
165   (destructor)PyStdOut_dealloc, /*tp_dealloc*/
166   0,                            /*tp_print*/
167   0,                            /*tp_getattr*/
168   0,                            /*tp_setattr*/
169   0,                            /*tp_compare*/
170   0,                            /*tp_repr*/
171   0,                            /*tp_as_number*/
172   0,                            /*tp_as_sequence*/
173   0,                            /*tp_as_mapping*/
174   0,                            /*tp_hash*/
175   0,                            /*tp_call*/
176   0,                            /*tp_str*/
177   PyObject_GenericGetAttr,      /*tp_getattro*/
178   /* softspace is writable:  we must supply tp_setattro */
179   PyObject_GenericSetAttr,      /* tp_setattro */
180   0,                            /*tp_as_buffer*/
181   Py_TPFLAGS_DEFAULT,           /*tp_flags*/
182   0,                            /*tp_doc*/
183   0,                            /*tp_traverse*/
184   0,                            /*tp_clear*/
185   0,                            /*tp_richcompare*/
186   0,                            /*tp_weaklistoffset*/
187   0,                            /*tp_iter*/
188   0,                            /*tp_iternext*/
189   PyStdOut_methods,             /*tp_methods*/
190   PyStdOut_memberlist,          /*tp_members*/
191   0,                            /*tp_getset*/
192   0,                            /*tp_base*/
193   0,                            /*tp_dict*/
194   0,                            /*tp_descr_get*/
195   0,                            /*tp_descr_set*/
196   0,                            /*tp_dictoffset*/
197   0,                            /*tp_init*/
198   0,                            /*tp_alloc*/
199   0,                            /*tp_new*/
200   0,                            /*tp_free*/
201   0,                            /*tp_is_gc*/
202 };
203
204 PyObject * newPyStdOut( std::string& out )
205 {
206   PyStdOut *self;
207   self = PyObject_New(PyStdOut, &PyStdOut_Type);
208   if (self == NULL)
209     return NULL;
210   self->softspace = 0;
211   self->out=&out;
212   return (PyObject*)self;
213 }
214
215 /*************************************************
216 End initialization Python structures and objects
217 **************************************************/
218
219 /**
220  * \brief {BLSURFPluginGUI_HypothesisCreator constructor}
221  * @param theHypType Name of the hypothesis type (here BLSURF_Parameters)
222  *
223  * */
224 BLSURFPluginGUI_HypothesisCreator::BLSURFPluginGUI_HypothesisCreator( const QString& theHypType )
225   : SMESHGUI_GenericHypothesisCreator( theHypType )
226 {
227   MESSAGE("BLSURFPluginGUI_HypothesisCreator::BLSURFPluginGUI_HypothesisCreator");
228   this->mySMPMap.clear();
229
230   GeomToolSelected = NULL;
231   GeomToolSelected = getGeomSelectionTool();
232
233   aSel = GeomToolSelected->selectionMgr();
234
235   /* Initialize the Python interpreter */
236   if (not Py_IsInitialized())
237     throw ("Error: Python interpreter is not initialized");
238   PyGILState_STATE gstate;
239   gstate = PyGILState_Ensure();
240
241   main_mod = NULL;
242   main_mod = PyImport_AddModule("__main__");
243
244   main_dict = NULL;
245   main_dict = PyModule_GetDict(main_mod);
246
247   PyRun_SimpleString("from math import *");
248   PyGILState_Release(gstate);
249
250 }
251
252 BLSURFPluginGUI_HypothesisCreator::~BLSURFPluginGUI_HypothesisCreator()
253 {
254 }
255
256 /**
257  * \brief {Get or create the geom selection tool for active study}
258  * */
259 GeomSelectionTools* BLSURFPluginGUI_HypothesisCreator::getGeomSelectionTool()
260 {
261   MESSAGE("BLSURFPluginGUI_HypothesisCreator::getGeomSelectionTool");
262   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
263   _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
264   MESSAGE("aStudy->StudyId(): " << aStudy->StudyId());
265   if (that->GeomToolSelected == NULL or that->GeomToolSelected->getMyStudy() != aStudy) {
266     MESSAGE("GeomToolSelected is created");
267     that->GeomToolSelected = new GeomSelectionTools(aStudy);
268   }
269   else
270     MESSAGE("GeomToolSelected already exists");
271   MESSAGE("that->GeomToolSelected->getMyStudy()->StudyId(): " << that->GeomToolSelected->getMyStudy()->StudyId());
272   return that->GeomToolSelected;
273 }
274
275 namespace {
276   inline bool isDouble( const QString& theText, const bool emptyOK=false ) {
277     QString str = theText.trimmed();
278     bool isOk = true;
279     if ( !str.isEmpty() )
280       str.toDouble(&isOk);
281     else
282       isOk = emptyOK;
283     return isOk;
284   }
285 }
286
287
288 bool BLSURFPluginGUI_HypothesisCreator::checkParams() const
289 {
290   MESSAGE("BLSURFPluginGUI_HypothesisCreator::checkParams");
291   bool ok = true;
292   if ( !isDouble( myPhySize->text(), false )) {
293     if ( myPhySize->text().isEmpty() )
294       myPhySize->setText(tr("OBLIGATORY_VALUE"));
295     myPhySize->selectAll();
296     ok = false;
297   }
298   if ( !isDouble( myPhyMin->text(), true )) {
299     myPhyMin->selectAll();
300     ok = false;
301   }
302   if ( !isDouble( myPhyMax->text(), true )) {
303     myPhyMax->selectAll();
304     ok = false;
305   }
306   if ( !isDouble( myGeoMin->text(), true )) {
307     myGeoMin->selectAll();
308     ok = false;
309   }
310   if ( !isDouble( myGeoMin->text(), true )) {
311     myGeoMin->selectAll();
312     ok = false;
313   }
314   if ( ok )
315   {
316     myOptionTable->setFocus();
317     QApplication::instance()->processEvents();
318
319     BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
320       BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis() );
321
322     int row = 0, nbRows = myOptionTable->rowCount();
323     for ( ; row < nbRows; ++row )
324     {
325       QString name  = myOptionTable->item( row, OPTION_NAME_COLUMN )->text();
326       QString value = myOptionTable->item( row, OPTION_VALUE_COLUMN )->text().trimmed();
327       if ( !value.isEmpty() ) {
328         try {
329           h->SetOptionValue( name.toLatin1().constData(), value.toLatin1().constData() );
330         }
331         catch ( const SALOME::SALOME_Exception& ex )
332         {
333           SUIT_MessageBox::critical( dlg(),
334                                      tr("SMESH_ERROR"),
335                                      ex.details.text.in() );
336           ok = false;
337         }
338       }
339     }
340     h->SetOptionValues( myOptions ); // restore values
341   }
342
343   // SizeMap
344   if ( ok )
345   {
346     mySizeMapTable->setFocus();
347     QApplication::instance()->processEvents();
348
349     BLSURFPlugin::BLSURFPlugin_Hypothesis_var h = BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis() );
350     BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
351
352     int row = 0, nbRows = mySizeMapTable->rowCount();
353     for ( ; row < nbRows; ++row )
354     {
355       QString entry   = mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->text();
356       QString sizeMap = mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->text().trimmed();
357       if ( !sizeMap.isEmpty() ) {
358         if (that->sizeMapValidationFromRow(row))
359         {
360           try {
361             const char* e = entry.toLatin1().constData();
362             const char* s = that->mySMPMap[entry].toLatin1().constData();
363             h->SetSizeMapEntry( e, s );
364           }
365           catch ( const SALOME::SALOME_Exception& ex )
366           {
367             SUIT_MessageBox::critical( dlg(),
368                                        tr("SMESH_ERROR"),
369                                        ex.details.text.in() );
370             ok = false;
371           }
372         }
373         else {
374           ok = false;
375         }
376       }
377     }
378   }
379
380   return ok;
381 }
382
383 QFrame* BLSURFPluginGUI_HypothesisCreator::buildFrame()
384 {
385   MESSAGE("BLSURFPluginGUI_HypothesisCreator::buildFrame");
386   QFrame* fr = new QFrame( 0 );
387   QVBoxLayout* lay = new QVBoxLayout( fr );
388   lay->setMargin( 5 );
389   lay->setSpacing( 0 );
390
391   // tab
392   QTabWidget* tab = new QTabWidget( fr );
393   tab->setTabShape( QTabWidget::Rounded );
394   tab->setTabPosition( QTabWidget::North );
395   lay->addWidget( tab );
396
397   // basic parameters
398   myStdGroup = new QWidget();
399   QGridLayout* aStdLayout = new QGridLayout( myStdGroup );
400   aStdLayout->setSpacing( 6 );
401   aStdLayout->setMargin( 11 );
402
403   int row = 0;
404   myName = 0;
405   if( isCreation() ) {
406     aStdLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), myStdGroup ), row, 0, 1, 1 );
407     myName = new QLineEdit( myStdGroup );
408     aStdLayout->addWidget( myName, row++, 1, 1, 1 );
409   }
410
411   aStdLayout->addWidget( new QLabel( tr( "BLSURF_GRADATION" ), myStdGroup ), row, 0, 1, 1 );
412   myGradation = new SalomeApp_DoubleSpinBox( myStdGroup );
413   aStdLayout->addWidget( myGradation, row++, 1, 1, 1 );
414   myGradation->setMinimum( 1.1 );
415   myGradation->setMaximum( 2.5 );
416   myGradation->setSingleStep( 0.1 );
417
418   aStdLayout->addWidget( new QLabel( tr( "BLSURF_PHY_MESH" ), myStdGroup ), row, 0, 1, 1 );
419   myPhysicalMesh = new QComboBox( myStdGroup );
420   aStdLayout->addWidget( myPhysicalMesh, row++, 1, 1, 1 );
421   QStringList physicalTypes;
422   physicalTypes << tr( "BLSURF_DEFAULT_USER" ) << tr( "BLSURF_CUSTOM_USER" ) << tr( "BLSURF_SIZE_MAP");
423   myPhysicalMesh->addItems( physicalTypes );
424
425   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYDEF" ), myStdGroup), row, 0, 1, 1 );
426   myPhySize = new QLineEdit( myStdGroup );
427   aStdLayout->addWidget( myPhySize, row++, 1, 1, 1 );
428
429 #ifdef WITH_SIZE_BOUNDARIES
430   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYMIN" ), myStdGroup ), row, 0, 1, 1 );
431   myPhyMin = new QLineEdit( myStdGroup );
432   aStdLayout->addWidget( myPhyMin, row++, 1, 1, 1 );
433
434   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYMAX" ), myStdGroup ), row, 0, 1, 1 );
435   myPhyMax = new QLineEdit( myStdGroup );
436   aStdLayout->addWidget( myPhyMax, row++, 1, 1, 1 );
437 #endif
438
439   aStdLayout->addWidget( new QLabel( tr( "BLSURF_GEOM_MESH" ), myStdGroup ), row, 0, 1, 1 );
440   myGeometricMesh = new QComboBox( myStdGroup );
441   aStdLayout->addWidget( myGeometricMesh, row++, 1, 1, 1 );
442   QStringList types;
443   types << tr( "BLSURF_DEFAULT_GEOM" ) << tr( "BLSURF_CUSTOM_GEOM" );
444   myGeometricMesh->addItems( types );
445
446   aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_S" ), myStdGroup ), row, 0, 1, 1 );
447   myAngleMeshS = new SalomeApp_DoubleSpinBox( myStdGroup );
448   aStdLayout->addWidget( myAngleMeshS, row++, 1, 1, 1 );
449   myAngleMeshS->setMinimum( 0 );
450   myAngleMeshS->setMaximum( 16 );
451   myAngleMeshS->setSingleStep( 0.5 );
452
453   aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_C" ), myStdGroup ), row, 0, 1, 1 );
454   myAngleMeshC = new SalomeApp_DoubleSpinBox( myStdGroup );
455   aStdLayout->addWidget( myAngleMeshC, row++, 1, 1, 1 );
456   myAngleMeshC->setMinimum( 0 );
457   myAngleMeshC->setMaximum( 16 );
458   myAngleMeshC->setSingleStep( 0.5 );
459
460 #ifdef WITH_SIZE_BOUNDARIES
461   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HGEOMIN" ), myStdGroup ), row, 0, 1, 1 );
462   myGeoMin = new QLineEdit( myStdGroup );
463   aStdLayout->addWidget( myGeoMin, row++, 1, 1, 1 );
464
465   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HGEOMAX" ), myStdGroup ), row, 0, 1, 1 );
466   myGeoMax = new QLineEdit( myStdGroup );
467   aStdLayout->addWidget( myGeoMax, row++, 1, 1, 1 );
468 #endif
469
470   myAllowQuadrangles = new QCheckBox( tr( "BLSURF_ALLOW_QUADRANGLES" ), myStdGroup );
471   aStdLayout->addWidget( myAllowQuadrangles, row++, 0, 1, 2 );
472
473   myDecimesh = new QCheckBox( tr( "BLSURF_DECIMESH" ), myStdGroup );
474   aStdLayout->addWidget( myDecimesh, row++, 0, 1, 2 );
475
476   // advanced parameters
477   myAdvGroup = new QWidget();
478   QGridLayout* anAdvLayout = new QGridLayout( myAdvGroup );
479   anAdvLayout->setSpacing( 6 );
480   anAdvLayout->setMargin( 11 );
481
482   anAdvLayout->addWidget( new QLabel( tr( "BLSURF_TOPOLOGY" ), myAdvGroup ), 0, 0, 1, 1 );
483   myTopology = new QComboBox( myAdvGroup );
484   anAdvLayout->addWidget( myTopology, 0, 1, 1, 1 );
485   QStringList topologyTypes;
486   topologyTypes << tr( "BLSURF_TOPOLOGY_CAD" ) << tr( "BLSURF_TOPOLOGY_PROCESS" ) << tr( "BLSURF_TOPOLOGY_PROCESS2" );
487   myTopology->addItems( topologyTypes );
488
489   anAdvLayout->addWidget( new QLabel( tr( "BLSURF_VERBOSITY" ), myAdvGroup ), 1, 0, 1, 1 );
490   myVerbosity = new QSpinBox( myAdvGroup );
491   anAdvLayout->addWidget( myVerbosity, 1, 1, 1, 1 );
492   myVerbosity->setMinimum( 0 );
493   myVerbosity->setMaximum( 100 );
494   myVerbosity->setSingleStep( 5 );
495
496   myOptionTable = new QTableWidget( 0, NB_COLUMNS, myAdvGroup );
497   anAdvLayout->addWidget( myOptionTable, 2, 0, 3, 2 );
498   QStringList headers;
499   headers << tr( "OPTION_ID_COLUMN" ) << tr( "OPTION_NAME_COLUMN" ) << tr( "OPTION_VALUE_COLUMN" );
500   myOptionTable->setHorizontalHeaderLabels( headers );
501   myOptionTable->horizontalHeader()->hideSection( OPTION_ID_COLUMN );
502   //myOptionTable->setColumnReadOnly( OPTION_NAME_COLUMN, TRUE );//////
503   //myOptionTable->setColumnReadOnly( OPTION_VALUE_COLUMN, FALSE );/////
504   myOptionTable->verticalHeader()->hide();
505   //myOptionTable->setSelectionBehavior( QAbstractItemView::SelectRows );
506
507   QPushButton* addBtn = new QPushButton( tr( "ADD_OPTION"),  myAdvGroup );
508   anAdvLayout->addWidget( addBtn, 2, 2, 1, 1 );
509   addBtn->setMenu( new QMenu() );
510
511   QPushButton* rmBtn = new QPushButton( tr( "REMOVE_OPTION"), myAdvGroup );
512   anAdvLayout->addWidget( rmBtn, 3, 2, 1, 1 );
513
514   anAdvLayout->setRowStretch( 4, 5 );
515   anAdvLayout->setColumnStretch( 1, 5 );
516
517   // Size Maps parameters
518
519   mySmpGroup = new QWidget();
520   QGridLayout* anSmpLayout = new QGridLayout(mySmpGroup);
521
522   mySizeMapTable = new QTableWidget( 0, SMP_NB_COLUMNS, mySmpGroup );
523   anSmpLayout->addWidget(mySizeMapTable, 1, 0, 8, 1);
524   QStringList sizeMapHeaders;
525   sizeMapHeaders << tr( "SMP_ENTRY_COLUMN" )<< tr( "SMP_NAME_COLUMN" ) << tr( "SMP_SIZEMAP_COLUMN" );
526   mySizeMapTable->setHorizontalHeaderLabels(sizeMapHeaders);
527   mySizeMapTable->horizontalHeader()->hideSection( SMP_ENTRY_COLUMN );
528   mySizeMapTable->resizeColumnToContents(SMP_NAME_COLUMN);
529   mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
530   mySizeMapTable->setAlternatingRowColors(true);
531   mySizeMapTable->verticalHeader()->hide();
532
533 /*
534   addAttractorButton = new QPushButton(tr("BLSURF_SM_ATTRACTOR"),mySmpGroup);
535   anSmpLayout->addWidget(addAttractorButton, SMP_ATTRACTOR_BTN, 1, 1, 1);
536
537   QFrame *line = new QFrame(mySmpGroup);
538   line->setFrameShape(QFrame::HLine);
539   line->setFrameShadow(QFrame::Sunken);
540   anSmpLayout->addWidget(line, SMP_SEPARATOR1, 1, 1, 1);
541 */
542   addSurfaceButton = new QPushButton(tr("BLSURF_SM_SURFACE"),mySmpGroup);
543   anSmpLayout->addWidget(addSurfaceButton, SMP_SURFACE_BTN, 1, 1, 1);
544
545   addEdgeButton = new QPushButton(tr("BLSURF_SM_EDGE"),mySmpGroup);
546   anSmpLayout->addWidget(addEdgeButton, SMP_EDGE_BTN, 1, 1, 1);
547
548   addPointButton = new QPushButton(tr("BLSURF_SM_POINT"),mySmpGroup);
549   anSmpLayout->addWidget(addPointButton, SMP_POINT_BTN, 1, 1, 1);
550
551   QFrame *line2 = new QFrame(mySmpGroup);
552   line2->setFrameShape(QFrame::HLine);
553   line2->setFrameShadow(QFrame::Sunken);
554   anSmpLayout->addWidget(line2, SMP_SEPARATOR2, 1, 1, 1);
555
556   removeButton = new QPushButton(tr("BLSURF_SM_REMOVE"),mySmpGroup);
557   anSmpLayout->addWidget(removeButton, SMP_REMOVE_BTN, 1, 1, 1);
558
559
560   // ---
561   tab->insertTab( STD_TAB, myStdGroup, tr( "SMESH_ARGUMENTS" ) );
562   tab->insertTab( ADV_TAB, myAdvGroup, tr( "BLSURF_ADV_ARGS" ) );
563   tab->insertTab( SMP_TAB, mySmpGroup, tr( "BLSURF_SIZE_MAP" ) );
564
565   tab->setCurrentIndex( STD_TAB );
566
567   // ---
568   connect( myGeometricMesh, SIGNAL( activated( int ) ), this, SLOT( onGeometricMeshChanged() ) );
569   connect( myPhysicalMesh,  SIGNAL( activated( int ) ), this, SLOT( onPhysicalMeshChanged() ) );
570   connect( addBtn->menu(),  SIGNAL( aboutToShow() ),    this, SLOT( onAddOption() ) );
571   connect( addBtn->menu(),  SIGNAL( triggered( QAction* ) ), this, SLOT( onOptionChosenInPopup( QAction* ) ) );
572   connect( rmBtn,           SIGNAL( clicked()),         this, SLOT( onDeleteOption() ) );
573
574   connect(addSurfaceButton, SIGNAL(clicked()), this, SLOT(onAddMapOnSurface()));
575   connect(addEdgeButton, SIGNAL(clicked()), this, SLOT(onAddMapOnEdge()));
576   connect(addPointButton, SIGNAL(clicked()), this, SLOT(onAddMapOnPoint()));
577   connect(removeButton, SIGNAL(clicked()), this, SLOT(onRemoveMap()));
578   connect(mySizeMapTable, SIGNAL(cellChanged ( int, int  )),this,SLOT (onSetSizeMap(int,int )));
579
580   return fr;
581 }
582
583 void BLSURFPluginGUI_HypothesisCreator::retrieveParams() const
584 {
585   MESSAGE("BLSURFPluginGUI_HypothesisCreator::retrieveParams");
586   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
587
588   BlsurfHypothesisData data;
589   that->readParamsFromHypo( data );
590
591   if ( myName ) {
592     myName->setText( data.myName );
593     QFontMetrics metrics( myName->font() );
594     myName->setMinimumWidth( metrics.width( data.myName )+5 );
595   }
596   myTopology->setCurrentIndex( data.myTopology );
597   myPhysicalMesh->setCurrentIndex( data.myPhysicalMesh );
598   myPhySize->setText( data.myPhySize );
599 #ifdef WITH_SIZE_BOUNDARIES
600   myPhyMin->setText( data.myPhyMin );
601   myPhyMax->setText( data.myPhyMax );
602   myGeoMin->setText( data.myGeoMin );
603   myGeoMax->setText( data.myGeoMax );
604 #endif
605   myGeometricMesh->setCurrentIndex( data.myGeometricMesh );
606   myAngleMeshS->setValue( data.myAngleMeshS );
607   myAngleMeshC->setValue( data.myAngleMeshC );
608   myGradation->setValue( data.myGradation );
609   myAllowQuadrangles->setChecked( data.myAllowQuadrangles );
610   myDecimesh->setChecked( data.myDecimesh );
611   myVerbosity->setValue( data.myVerbosity );
612
613   if ( myOptions.operator->() ) {
614     printf("retrieveParams():myOptions->length()=%d\n",myOptions->length());
615     for ( int i = 0, nb = myOptions->length(); i < nb; ++i ) {
616       QString option = that->myOptions[i].in();
617       QStringList name_value = option.split( ":", QString::KeepEmptyParts );
618       if ( name_value.count() > 1 ) {
619         QString idStr = QString("%1").arg( i );
620         int row = myOptionTable->rowCount();
621         myOptionTable->setRowCount( row+1 );
622         myOptionTable->setItem( row, OPTION_ID_COLUMN, new QTableWidgetItem( idStr ) );
623         myOptionTable->item( row, OPTION_ID_COLUMN )->setFlags( 0 );
624         myOptionTable->setItem( row, OPTION_NAME_COLUMN, new QTableWidgetItem( name_value[0] ) );
625         myOptionTable->item( row, OPTION_NAME_COLUMN )->setFlags( 0 );
626         myOptionTable->setItem( row, OPTION_VALUE_COLUMN, new QTableWidgetItem( name_value[1] ) );
627         myOptionTable->item( row, OPTION_VALUE_COLUMN )->setFlags( Qt::ItemIsSelectable |
628                                                                    Qt::ItemIsEditable   |
629                                                                    Qt::ItemIsEnabled );
630       }
631     }
632   }
633   myOptionTable->resizeColumnToContents( OPTION_NAME_COLUMN );
634
635   printf("retrieveParams():that->mySMPMap.size()=%d\n",that->mySMPMap.size());
636   QMapIterator<QString, QString> i(that->mySMPMap);
637   GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool();
638   while (i.hasNext()) {
639     i.next();
640     const QString entry = i.key();
641     string shapeName = myGeomToolSelected->getNameFromEntry(entry.toStdString());
642     const QString sizeMap = i.value();
643     int row = mySizeMapTable->rowCount();
644     mySizeMapTable->setRowCount( row+1 );
645     mySizeMapTable->setItem( row, SMP_ENTRY_COLUMN, new QTableWidgetItem( entry ) );
646     mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->setFlags( 0 );
647     mySizeMapTable->setItem( row, SMP_NAME_COLUMN, new QTableWidgetItem( QString::fromStdString(shapeName) ) );
648     mySizeMapTable->item( row, SMP_NAME_COLUMN )->setFlags( 0 );
649     mySizeMapTable->setItem( row, SMP_SIZEMAP_COLUMN, new QTableWidgetItem( sizeMap ) );
650     mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->setFlags( Qt::ItemIsSelectable |
651                                                                Qt::ItemIsEditable   |
652                                                                Qt::ItemIsEnabled );
653     }
654
655   mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN );
656   mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
657
658   // update widgets
659   that->onPhysicalMeshChanged();
660   that->onGeometricMeshChanged();
661 }
662
663 QString BLSURFPluginGUI_HypothesisCreator::storeParams() const
664 {
665   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
666
667   BlsurfHypothesisData data;
668   QString guiHyp = that->readParamsFromWidgets( data );
669   that->storeParamsToHypo( data );
670
671   return guiHyp;
672 }
673
674 bool BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo( BlsurfHypothesisData& h_data ) const
675 {
676   MESSAGE("BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo");
677   BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
678     BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis() );
679
680   HypothesisData* data = SMESH::GetHypothesisData( hypType() );
681   h_data.myName = isCreation() && data ? hypName() : "";
682
683   h_data.myTopology         = (int) h->GetTopology();
684   h_data.myPhysicalMesh     = (int) h->GetPhysicalMesh();
685   h_data.myPhySize          = QString::number( h->GetPhySize() );
686   h_data.myGeometricMesh    = (int) h->GetGeometricMesh();
687   h_data.myAngleMeshS       = h->GetAngleMeshS();
688   h_data.myAngleMeshC       = h->GetAngleMeshC();
689   h_data.myGradation        = h->GetGradation();
690   h_data.myAllowQuadrangles = h->GetQuadAllowed();
691   h_data.myDecimesh         = h->GetDecimesh();
692   h_data.myVerbosity        = h->GetVerbosity();
693
694 #ifdef WITH_SIZE_BOUNDARIES
695   double PhyMin = h->GetPhyMin();
696   double PhyMax = h->GetPhyMax();
697   double GeoMin = h->GetGeoMin();
698   double GeoMax = h->GetGeoMax();
699   if ( PhyMin > 0 )
700   h_data.myPhyMin = PhyMin > 0 ? QString::number( h->GetPhyMin() ) : QString("");
701   h_data.myPhyMax = PhyMax > 0 ? QString::number( h->GetPhyMax() ) : QString("");
702   h_data.myGeoMin = GeoMin > 0 ? QString::number( h->GetGeoMin() ) : QString("");
703   h_data.myGeoMax = GeoMax > 0 ? QString::number( h->GetGeoMax() ) : QString("");
704 #endif
705
706   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
707   that->myOptions = h->GetOptionValues();
708
709   that->mySMPMap.clear();
710
711   // classic size maps
712   BLSURFPlugin::string_array_var mySizeMaps = h->GetSizeMapEntries();
713   MESSAGE("mySizeMaps->length() = " << mySizeMaps->length());
714   QString fullSizeMaps;
715   QStringList fullSizeMapList;
716   GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool();
717   for ( int i = 0;i<mySizeMaps->length(); ++i ) {
718     fullSizeMaps =  mySizeMaps[i].in();
719     MESSAGE("fullSizeMaps: " << fullSizeMaps.toStdString());
720     fullSizeMapList = fullSizeMaps.split( "|", QString::KeepEmptyParts );
721     if ( fullSizeMapList.count() > 1 ) {
722       string fullSizeMap = fullSizeMapList[1].toStdString();
723       int pos = fullSizeMap.find("return")+7;
724       MESSAGE("pos:" << pos);
725       QString sizeMap;
726       try {
727         sizeMap = QString::fromStdString(fullSizeMap.substr(pos, fullSizeMap.size()-pos));
728       }
729       catch (...) {
730         continue;
731       }
732       that->mySMPMap[fullSizeMapList[0]] = sizeMap;
733       MESSAGE("mySMPMap[" << fullSizeMapList[0].toStdString() << "] = " << sizeMap.toStdString());
734       that->mySMPShapeTypeMap[fullSizeMapList[0]] = myGeomToolSelected->entryToShapeType(fullSizeMapList[0].toStdString());
735       MESSAGE("mySMPShapeTypeMap[" << fullSizeMapList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[fullSizeMapList[0]]);
736     }
737   }
738
739   // custom size maps
740 /*
741   BLSURFPlugin::string_array_var myCustomSizeMaps = h->GetCustomSizeMapEntries();
742   MESSAGE("myCustomSizeMaps->length() = " << myCustomSizeMaps->length());
743
744   for ( int i = 0;i<myCustomSizeMaps->length(); ++i ) {
745     QString fullCustomSizeMaps =  myCustomSizeMaps[i].in();
746     QStringList fullCustomSizeMapList = fullCustomSizeMaps.split( "|", QString::KeepEmptyParts );
747     if ( fullCustomSizeMapList.count() > 1 ) {
748       that->mySMPMap[fullCustomSizeMapList[0]] = fullCustomSizeMapList[1];
749       that->mySMPShapeTypeMap[fullCustomSizeMapList[0]] = GeomToolSelected->entryToShapeType(fullCustomSizeMapList[0].toStdString());
750       MESSAGE("mySMPMap[" << fullCustomSizeMapList[0].toStdString() << "] = " << fullCustomSizeMapList[1].toStdString());
751       MESSAGE("mySMPShapeTypeMap[" << fullCustomSizeMapList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[fullCustomSizeMapList[0]]);
752     }
753   }
754 */
755   // attractor
756   BLSURFPlugin::string_array_var allMyAttractors = h->GetAttractorEntries();
757   MESSAGE("myAttractors->length() = " << allMyAttractors->length());
758
759   for ( int i = 0;i<allMyAttractors->length(); ++i ) {
760     QString myAttractors =  allMyAttractors[i].in();
761     QStringList myAttractorList = myAttractors.split( "|", QString::KeepEmptyParts );
762     if ( myAttractorList.count() > 1 ) {
763       that->mySMPMap[myAttractorList[0]] = myAttractorList[1];
764       that->mySMPShapeTypeMap[myAttractorList[0]] = myGeomToolSelected->entryToShapeType(myAttractorList[0].toStdString());
765       MESSAGE("mySMPMap[" << myAttractorList[0].toStdString() << "] = " << myAttractorList[1].toStdString());
766       MESSAGE("mySMPShapeTypeMap[" << myAttractorList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[myAttractorList[0]]);
767     }
768   }
769
770   return true;
771 }
772
773 bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesisData& h_data ) const
774 {
775   MESSAGE("BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo");
776   BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
777     BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( hypothesis() );
778
779   bool ok = true;
780   try
781   {
782     if( isCreation() )
783       SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().constData() );
784
785     if ( h->GetTopology() != h_data.myTopology ) // avoid duplication of DumpPython commands
786       h->SetTopology( (int) h_data.myTopology );
787     if ( h->GetPhysicalMesh() != h_data.myPhysicalMesh )
788       h->SetPhysicalMesh( (int) h_data.myPhysicalMesh );
789     if ( h->GetGeometricMesh() != (int) h_data.myGeometricMesh )
790       h->SetGeometricMesh( (int) h_data.myGeometricMesh );
791     if ( h->GetGradation() !=  h_data.myGradation )
792       h->SetGradation( h_data.myGradation );
793     if ( h->GetQuadAllowed() != h_data.myAllowQuadrangles )
794       h->SetQuadAllowed( h_data.myAllowQuadrangles );
795     if ( h->GetDecimesh() != h_data.myDecimesh )
796       h->SetDecimesh( h_data.myDecimesh );
797     if ( h->GetVerbosity() != h_data.myVerbosity )
798       h->SetVerbosity( h_data.myVerbosity );
799
800     if( ((int) h_data.myPhysicalMesh == PhysicalUserDefined)||((int) h_data.myPhysicalMesh == SizeMap) ) {
801       if ( h->GetPhySize() != h_data.myPhySize.toDouble() )
802         h->SetPhySize( h_data.myPhySize.toDouble() );
803     }
804     if( (int) h_data.myGeometricMesh == UserDefined ) {
805       if ( h->GetAngleMeshS() != h_data.myAngleMeshS )
806         h->SetAngleMeshS( h_data.myAngleMeshS );
807       if ( h->GetAngleMeshC() != h_data.myAngleMeshC )
808         h->SetAngleMeshC( h_data.myAngleMeshC );
809     }
810 #ifdef WITH_SIZE_BOUNDARIES
811     if ( !isDouble( h_data.myPhyMin ))
812       h->SetPhyMin( -1 );
813     else if ( h->GetPhyMin() != h_data.myPhyMin.toDouble() )
814       h->SetPhyMin( h_data.myPhyMin.toDouble() );
815     if ( !isDouble( h_data.myPhyMax ))
816       h->SetPhyMax( -1 );
817     else if ( h->GetPhyMax() != h_data.myPhyMax.toDouble() )
818       h->SetPhyMax( h_data.myPhyMax.toDouble() );
819     if ( !isDouble( h_data.myGeoMin ))
820       h->SetGeoMin( -1 );
821     else if ( h->GetGeoMin() != h_data.myGeoMin.toDouble() )
822       h->SetGeoMin( h_data.myGeoMin.toDouble() );
823     if ( !isDouble( h_data.myGeoMax ))
824       h->SetGeoMax( -1 );
825     else if ( h->GetGeoMax() != h_data.myGeoMax.toDouble() )
826       h->SetGeoMax( h_data.myGeoMax.toDouble() );
827 #endif
828
829     //printf("storeParamsToHypo():myOptions->length()=%d\n",myOptions->length());
830     h->SetOptionValues( myOptions ); // is set in checkParams()
831
832     BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
833     QMapIterator<QString,QString> i(that->mySMPMap);
834     // Iterate over each size map
835     while (i.hasNext()) {
836       i.next();
837       const QString entry = i.key();
838       const QString sizeMap = i.value();
839
840       if (sizeMap == "__TO_DELETE__") {
841         MESSAGE("Delete entry " << entry.toStdString() << " from engine");
842         h->UnsetEntry(entry.toLatin1().constData());
843       }
844       else if (sizeMap.startsWith("ATTRACTOR")) {
845         MESSAGE("SetAttractorEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString());
846         h->SetAttractorEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData() );
847       }
848       else if (sizeMap.startsWith("def")) {
849         MESSAGE("SetCustomSizeMapEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString());
850 //        h->SetCustomSizeMapEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData() );
851       }
852       else {
853         QString fullSizeMap;
854         fullSizeMap = QString("");
855         if (that->mySMPShapeTypeMap[entry]  == TopAbs_FACE)
856           fullSizeMap = QString("def f(u,v): return ") + sizeMap;
857         else if (that->mySMPShapeTypeMap[entry]  == TopAbs_EDGE)
858           fullSizeMap = QString("def f(t): return ") + sizeMap;
859         else if (that->mySMPShapeTypeMap[entry] == TopAbs_VERTEX)
860           fullSizeMap = QString("def f(): return ") + sizeMap;
861
862         MESSAGE("SetSizeMapEntry("<<entry.toStdString()<<") = " <<fullSizeMap.toStdString());
863         h->SetSizeMapEntry( entry.toLatin1().constData(), fullSizeMap.toLatin1().constData() );
864       }
865     }
866   }
867   catch(const SALOME::SALOME_Exception& ex)
868   {
869     SalomeApp_Tools::QtCatchCorbaException(ex);
870     ok = false;
871   }
872   return ok;
873 }
874
875 QString BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets( BlsurfHypothesisData& h_data ) const
876 {
877   MESSAGE("BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets");
878   h_data.myName             = myName ? myName->text() : "";
879   h_data.myTopology         = myTopology->currentIndex();
880   h_data.myPhysicalMesh     = myPhysicalMesh->currentIndex();
881   h_data.myPhySize          = myPhySize->text();
882 #ifdef WITH_SIZE_BOUNDARIES
883   h_data.myPhyMin           = myPhyMin->text();
884   h_data.myPhyMax           = myPhyMax->text();
885   h_data.myGeoMin           = myGeoMin->text();
886   h_data.myGeoMax           = myGeoMax->text();
887 #endif
888   h_data.myGeometricMesh    = myGeometricMesh->currentIndex();
889   h_data.myAngleMeshS       = myAngleMeshS->value();
890   h_data.myAngleMeshC       = myAngleMeshC->value();
891   h_data.myGradation        = myGradation->value();
892   h_data.myAllowQuadrangles = myAllowQuadrangles->isChecked();
893   h_data.myDecimesh         = myDecimesh->isChecked();
894   h_data.myVerbosity        = myVerbosity->value();
895
896   QString guiHyp;
897   guiHyp += tr("BLSURF_TOPOLOGY") + " = " + QString::number( h_data.myTopology ) + "; ";
898   guiHyp += tr("BLSURF_PHY_MESH") + " = " + QString::number( h_data.myPhysicalMesh ) + "; ";
899   guiHyp += tr("BLSURF_HPHYDEF") + " = " + h_data.myPhySize + "; ";
900   guiHyp += tr("BLSURF_GEOM_MESH") + " = " + QString::number( h_data.myGeometricMesh ) + "; ";
901   guiHyp += tr("BLSURF_ANGLE_MESH_S") + " = " + QString::number( h_data.myAngleMeshS ) + "; ";
902   guiHyp += tr("BLSURF_GRADATION") + " = " + QString::number( h_data.myGradation ) + "; ";
903   guiHyp += tr("BLSURF_ALLOW_QUADRANGLES") + " = " + QString(h_data.myAllowQuadrangles ? "yes" : "no") + "; ";
904   guiHyp += tr("BLSURF_DECIMESH") + " = " + QString(h_data.myDecimesh ? "yes" : "no") + "; ";
905 #ifdef WITH_SIZE_BOUNDARIES
906   if ( isDouble( h_data.myPhyMin )) guiHyp += "hphymin = " + h_data.myPhyMin + "; ";
907   if ( isDouble( h_data.myPhyMax )) guiHyp += "hphymax = " + h_data.myPhyMax + "; ";
908   if ( isDouble( h_data.myGeoMin )) guiHyp += "hgeomin = " + h_data.myGeoMin + "; ";
909   if ( isDouble( h_data.myGeoMax )) guiHyp += "hgeomax = " + h_data.myGeoMax + "; ";
910 #endif
911
912   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
913   int row = 0, nbRows = myOptionTable->rowCount();
914   for ( ; row < nbRows; ++row )
915   {
916     int id = myOptionTable->item( row, OPTION_ID_COLUMN )->text().toInt();
917     if ( id >= 0 && id < myOptions->length() )
918     {
919       QString name  = myOptionTable->item( row, OPTION_NAME_COLUMN )->text();
920       QString value = myOptionTable->item( row, OPTION_VALUE_COLUMN )->text().trimmed();
921       if ( value.isNull() )
922         value = "";
923       that->myOptions[ id ] = ( name + ":" + value).toLatin1().constData();
924       if ( value != "" )
925         guiHyp += name + " = " + value + "; ";
926     }
927   }
928
929   // SizeMap
930   row = 0, nbRows = mySizeMapTable->rowCount();
931   for ( ; row < nbRows; ++row )
932   {
933       QString entry   = mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->text();
934       if ( that->mySMPMap.contains(entry) )
935         guiHyp += entry + " = " + that->mySMPMap[entry] + "; ";
936   }
937
938   MESSAGE("guiHyp : " << guiHyp.toLatin1().data());
939
940   return guiHyp;
941 }
942
943 void BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged() {
944   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged");
945   bool isPhysicalUserDefined = (myPhysicalMesh->currentIndex() == PhysicalUserDefined);
946   bool isSizeMap = (myPhysicalMesh->currentIndex() == SizeMap);
947   bool isCustom = (isPhysicalUserDefined || isSizeMap) ;
948   bool geomIsCustom = (myGeometricMesh->currentIndex() == UserDefined);
949   
950   myGradation->setEnabled(not isPhysicalUserDefined || geomIsCustom);
951   myPhySize->setEnabled(isCustom);
952   myPhyMax->setEnabled(isCustom);
953   myPhyMin->setEnabled(isCustom);
954
955   if ( !isSizeMap) {
956     double gradation;
957     switch( myPhysicalMesh->currentIndex() ) {
958       case DefaultSize:
959       default:
960         gradation = 1.1;
961         break;
962     }
963     myGradation->setValue( gradation );
964   }
965       
966   if ( !isCustom ) {
967     QString aPhySize = "";
968     switch( myPhysicalMesh->currentIndex() ) {
969       case DefaultSize:
970       default:
971         aPhySize = "10";
972         break;
973       }
974     myPhySize->setText( aPhySize );
975     if ( !isDouble( myPhyMin->text(), true ))
976       myPhyMin->setText("");
977     if ( !isDouble( myPhyMax->text(), true ))
978       myPhyMax->setText("");
979     if ( myGeometricMesh->currentIndex() == DefaultGeom ) {
980       myGeometricMesh->setCurrentIndex( UserDefined );
981       onGeometricMeshChanged();
982     }
983   }
984 }
985
986 void BLSURFPluginGUI_HypothesisCreator::onGeometricMeshChanged() {
987   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onGeometricMeshChanged");
988   bool isCustom = (myGeometricMesh->currentIndex() == UserDefined);
989   bool phyIsSizemap = (myPhysicalMesh->currentIndex() == SizeMap);
990   
991   myAngleMeshS->setEnabled(isCustom);
992   myAngleMeshC->setEnabled(isCustom);
993   myGradation->setEnabled(isCustom || phyIsSizemap);
994   myGeoMax->setEnabled(isCustom);
995   myGeoMin->setEnabled(isCustom);
996
997   if ( ! isCustom ) {
998     double aAngleMeshS;
999     switch( myGeometricMesh->currentIndex() ) {
1000       case DefaultGeom:
1001       default:
1002         aAngleMeshS = 8;
1003         break;
1004       }
1005     myAngleMeshS->setValue( aAngleMeshS );
1006     myAngleMeshC->setValue( aAngleMeshS );
1007     if ( !isDouble( myGeoMin->text(), true ))
1008       myGeoMin->setText("");
1009     if ( !isDouble( myGeoMax->text(), true ))
1010       myGeoMax->setText("");
1011     //  hphy_flag = 0 and hgeo_flag = 0 is not allowed (spec)
1012     if ( myPhysicalMesh->currentIndex() == DefaultSize ) {
1013       myPhysicalMesh->setCurrentIndex( PhysicalUserDefined );
1014       onPhysicalMeshChanged();
1015     }
1016   }
1017 }
1018
1019 void BLSURFPluginGUI_HypothesisCreator::onAddOption()
1020 {
1021   QMenu* menu = (QMenu*)sender();
1022   // fill popup with option names
1023   menu->clear();
1024   if ( myOptions.operator->() ) {
1025     for ( int i = 0, nb = myOptions->length(); i < nb; ++i ) {
1026       QString name_value = myOptions[i].in();
1027       QString name = name_value.split( ":", QString::KeepEmptyParts )[0];
1028       menu->addAction( name );
1029     }
1030   }
1031 }
1032
1033 void BLSURFPluginGUI_HypothesisCreator::onOptionChosenInPopup( QAction* a )
1034 {
1035   myOptionTable->setFocus();
1036   QMenu* menu = (QMenu*)( a->parent() );
1037
1038   int idx = menu->actions().indexOf( a );
1039   QString idStr = QString("%1").arg( idx );
1040   QString option = myOptions[idx].in();
1041   QString optionName = option.split( ":", QString::KeepEmptyParts )[0];
1042
1043   // look for a row with optionName
1044   int row = 0, nbRows = myOptionTable->rowCount();
1045   for ( ; row < nbRows; ++row )
1046     if ( myOptionTable->item( row, OPTION_ID_COLUMN )->text() == idStr )
1047       break;
1048   // add a row if not found
1049   if ( row == nbRows ) {
1050     myOptionTable->setRowCount( row+1 );
1051     myOptionTable->setItem( row, OPTION_ID_COLUMN, new QTableWidgetItem( idStr ) );
1052     myOptionTable->item( row, OPTION_ID_COLUMN )->setFlags( 0 );
1053     myOptionTable->setItem( row, OPTION_NAME_COLUMN, new QTableWidgetItem( optionName ) );
1054     myOptionTable->item( row, OPTION_NAME_COLUMN )->setFlags( 0 );
1055     myOptionTable->setItem( row, OPTION_VALUE_COLUMN, new QTableWidgetItem( "" ) );
1056     myOptionTable->item( row, OPTION_VALUE_COLUMN )->setFlags( Qt::ItemIsSelectable |
1057                                                                Qt::ItemIsEditable   |
1058                                                                Qt::ItemIsEnabled );
1059     myOptionTable->resizeColumnToContents( OPTION_NAME_COLUMN );
1060   }
1061   myOptionTable->clearSelection();
1062   myOptionTable->scrollToItem( myOptionTable->item( row, OPTION_VALUE_COLUMN ) );
1063   //myOptionTable->item( row, OPTION_VALUE_COLUMN )->setSelected( true );
1064   myOptionTable->setCurrentCell( row, OPTION_VALUE_COLUMN );
1065   //myOptionTable->openPersistentEditor( myOptionTable->item( row, OPTION_VALUE_COLUMN ) );
1066 }
1067
1068 void BLSURFPluginGUI_HypothesisCreator::onDeleteOption()
1069 {
1070   // clear option values and remember selected row
1071   QList<int> selectedRows;
1072   QList<QTableWidgetItem*> selected = myOptionTable->selectedItems();
1073   QTableWidgetItem* item;
1074   foreach( item, selected ) {
1075     int row = item->row();
1076     if ( !selectedRows.contains( row ) ) {
1077       selectedRows.append( row );
1078       int id = myOptionTable->item( row, OPTION_ID_COLUMN )->text().toInt();
1079       if ( id >= 0 && id < myOptions->length() )
1080         myOptions[ id ] = myOptionTable->item( row, OPTION_NAME_COLUMN )->text().toLatin1().constData();
1081     }
1082   }
1083   qSort( selectedRows );
1084   QListIterator<int> it( selectedRows );
1085   it.toBack();
1086   while ( it.hasPrevious() )
1087     myOptionTable->removeRow( it.previous() );
1088 }
1089
1090 // **********************
1091 // *** BEGIN SIZE MAP ***
1092 // **********************
1093
1094
1095 void BLSURFPluginGUI_HypothesisCreator::onRemoveMap()
1096 {
1097   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onRemoveMap()");
1098   QList<int> selectedRows;
1099   QList<QTableWidgetItem*> selected = mySizeMapTable->selectedItems();
1100   QTableWidgetItem* item;
1101   int row;
1102   foreach( item, selected ) {
1103     row = item->row();
1104     if ( !selectedRows.contains( row ) )
1105       selectedRows.append( row );
1106   }
1107
1108   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1109
1110   qSort( selectedRows );
1111   QListIterator<int> it( selectedRows );
1112   it.toBack();
1113   while ( it.hasPrevious() ) {
1114       row = it.previous();
1115       QString entry = mySizeMapTable->item(row,SMP_ENTRY_COLUMN)->text();
1116       if (that->mySMPMap.contains(entry))
1117         that->mySMPMap[entry] = "__TO_DELETE__";
1118       if (that->mySMPShapeTypeMap.contains(entry))
1119         that->mySMPShapeTypeMap.remove(entry);
1120       mySizeMapTable->removeRow(row );
1121   }
1122   mySizeMapTable->resizeColumnToContents(SMP_NAME_COLUMN);
1123   mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
1124 }
1125
1126 void BLSURFPluginGUI_HypothesisCreator::onSetSizeMap(int row,int col)
1127 {
1128   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onSetSizeMap("<< row << "," << col << ")");
1129   if (col == SMP_SIZEMAP_COLUMN) {
1130     BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1131     QString entry   = that->mySizeMapTable->item(row, SMP_ENTRY_COLUMN)->text();
1132     QString sizeMap = that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->text().trimmed();
1133     MESSAGE("entry: " << entry.toStdString() << ", sizeMap: " << sizeMap.toStdString());
1134     if (not that->mySMPShapeTypeMap.contains(entry))
1135       return;
1136     if (that->mySMPMap.contains(entry))
1137       if (that->mySMPMap[entry] == sizeMap)
1138         return;
1139     QColor* bgColor = new QColor("white");
1140     QColor* fgColor = new QColor("black");
1141     if (not sizeMap.isEmpty()) {
1142       that->mySMPMap[entry] = sizeMap;
1143       if (not sizeMapValidationFromRow(row)) {
1144         bgColor->setRgb(255,0,0);
1145         fgColor->setRgb(255,255,255);
1146       }
1147     }
1148     else {
1149       MESSAGE("Size map empty: reverse to precedent value" );
1150       that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setText(that->mySMPMap[entry]);
1151     }
1152     that->mySizeMapTable->item(row, SMP_NAME_COLUMN)->setBackground(QBrush(*bgColor));
1153     that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setBackground(QBrush(*bgColor));
1154     that->mySizeMapTable->item(row, SMP_NAME_COLUMN)->setForeground(QBrush(*fgColor));
1155     that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setForeground(QBrush(*fgColor));
1156     mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
1157   }
1158 }
1159
1160 void BLSURFPluginGUI_HypothesisCreator::onAddMapOnSurface()
1161 {
1162  insertElementType(TopAbs_FACE);
1163 }
1164
1165 void BLSURFPluginGUI_HypothesisCreator::onAddMapOnEdge()
1166 {
1167  insertElementType(TopAbs_EDGE);
1168 }
1169
1170 void BLSURFPluginGUI_HypothesisCreator::onAddMapOnPoint()
1171 {
1172  insertElementType(TopAbs_VERTEX);
1173 }
1174
1175 void BLSURFPluginGUI_HypothesisCreator::insertElementType(TopAbs_ShapeEnum typeShapeAsked)
1176 {
1177   MESSAGE("BLSURFPluginGUI_HypothesisCreator::insertElementType()");
1178
1179   BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
1180     BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis());
1181
1182   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1183
1184   TopAbs_ShapeEnum shapeType;
1185   string entry, shapeName;
1186   GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool();
1187
1188   LightApp_SelectionMgr* mySel = myGeomToolSelected->selectionMgr();
1189
1190   SALOME_ListIO ListSelectedObjects;
1191   mySel->selectedObjects(ListSelectedObjects, NULL, false );
1192   if (!ListSelectedObjects.IsEmpty())
1193   {
1194     SALOME_ListIteratorOfListIO Object_It(ListSelectedObjects);
1195     for (; Object_It.More(); Object_It.Next())
1196     {
1197       Handle(SALOME_InteractiveObject) anObject = Object_It.Value();
1198       entry     = myGeomToolSelected->getEntryOfObject(anObject);
1199       shapeName = anObject->getName();
1200       shapeType         = myGeomToolSelected->entryToShapeType(entry);
1201       MESSAGE("Object Name = " << shapeName << "& Type is " << anObject->getComponentDataType() << " & ShapeType is " << shapeType);
1202       if (shapeType == typeShapeAsked)
1203       {
1204         mySizeMapTable->setFocus();
1205         QString shapeEntry;
1206         shapeEntry = QString::fromStdString(entry);
1207         double phySize = h->GetPhySize();
1208         std::ostringstream oss;
1209         oss << phySize;
1210         QString sizeMap;
1211         sizeMap  = QString::fromStdString(oss.str());
1212         if (that->mySMPMap.contains(shapeEntry)) {
1213           if (that->mySMPMap[shapeEntry] != "__TO_DELETE__") {
1214             MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")");
1215             break;
1216           }
1217         }
1218         that->mySMPMap[shapeEntry] = sizeMap;
1219         that->mySMPShapeTypeMap[shapeEntry] = typeShapeAsked;
1220         int row = mySizeMapTable->rowCount() ;
1221         mySizeMapTable->setRowCount( row+1 );
1222         mySizeMapTable->setItem( row, SMP_ENTRY_COLUMN, new QTableWidgetItem( shapeEntry ) );
1223         mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->setFlags( 0 );
1224         mySizeMapTable->setItem( row, SMP_NAME_COLUMN, new QTableWidgetItem( QString::fromStdString(shapeName) ) );
1225         mySizeMapTable->item( row, SMP_NAME_COLUMN )->setFlags( 0 );
1226         mySizeMapTable->setItem( row, SMP_SIZEMAP_COLUMN, new QTableWidgetItem( sizeMap ) );
1227         mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->setFlags( Qt::ItemIsSelectable |Qt::ItemIsEditable   |Qt::ItemIsEnabled );
1228         mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN );
1229         mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
1230         mySizeMapTable->clearSelection();
1231         mySizeMapTable->scrollToItem( mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN ) );
1232
1233         if ( myPhysicalMesh->currentIndex() != SizeMap ) {
1234           myPhysicalMesh->setCurrentIndex( SizeMap );
1235           onPhysicalMeshChanged();
1236         }
1237       }
1238     }
1239   }
1240 }
1241
1242 bool BLSURFPluginGUI_HypothesisCreator::sizeMapsValidation()
1243 {
1244   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapsValidation()");
1245   int row = 0, nbRows = mySizeMapTable->rowCount();
1246   for ( ; row < nbRows; ++row )
1247     if (not sizeMapValidationFromRow(row))
1248       return false;
1249   return true;
1250 }
1251
1252 bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow(int myRow, bool displayError)
1253 {
1254   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow()");
1255   QString myEntry   = mySizeMapTable->item( myRow, SMP_ENTRY_COLUMN )->text();
1256   bool res = sizeMapValidationFromEntry(myEntry,displayError);
1257   mySizeMapTable->setFocus();
1258   return res;
1259 }
1260
1261 bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry(QString myEntry, bool displayError)
1262 {
1263   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry()");
1264
1265   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1266
1267   if (not that->mySMPMap.contains(myEntry)) {
1268     MESSAGE("Geometry with entry "<<myEntry.toStdString()<<" was not found.");
1269     return false;
1270   }
1271   if (not that->mySMPShapeTypeMap.contains(myEntry)) {
1272     MESSAGE("Shape type with entry "<<myEntry.toStdString()<<" was not found.");
1273     return false;
1274   }
1275
1276   string expr;
1277
1278   if (that->mySMPMap[myEntry].startsWith("def")) {
1279     MESSAGE("custom function" );
1280     expr = that->mySMPMap[myEntry].toStdString();
1281   }
1282   else if (that->mySMPMap[myEntry].startsWith("ATTRACTOR")) {
1283     MESSAGE("Attractor" );
1284     if ((that->mySMPMap[myEntry].count(QRegExp("^ATTRACTOR\\((?:(-?0(\\.\\d*)*|-?[1-9]+\\d*(\\.\\d*)*|-?\\.(\\d)+);){5}(True|False)\\)$")) != 1)) {
1285 //     if ((that->mySMPMap[myEntry].count('(') != 1) or
1286 //         (that->mySMPMap[myEntry].count(')') != 1) or
1287 //         (that->mySMPMap[myEntry].count(';') != 4) or
1288 //         (that->mySMPMap[myEntry].size() == 15)){
1289       if (displayError)
1290         SUIT_MessageBox::warning( dlg(),"Definition of attractor : Error" ,"An attractor is defined with the following pattern: ATTRACTOR(xa;ya;za;a;b;True|False)" );
1291       return false;
1292     }
1293     return true;
1294   }
1295   else {
1296     // case size map is empty
1297     if (that->mySMPMap[myEntry].isEmpty()) {
1298       if (displayError)
1299         SUIT_MessageBox::warning( dlg(),"Definition of size map : Error" , "Size map can't be empty");
1300       return false;
1301     }
1302
1303     if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_FACE)
1304       expr = "def f(u,v) : return " + that->mySMPMap[myEntry].toStdString();
1305     else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_EDGE)
1306       expr = "def f(t) : return " + that->mySMPMap[myEntry].toStdString();
1307     else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_VERTEX)
1308       expr = "def f() : return " + that->mySMPMap[myEntry].toStdString();
1309   }
1310   //assert(Py_IsInitialized());
1311   if (not Py_IsInitialized())
1312     throw ("Erreur: Python interpreter is not initialized");
1313   PyGILState_STATE gstate;
1314   gstate = PyGILState_Ensure();
1315
1316   PyObject * obj = NULL;
1317   PyObject* new_stderr = NULL;
1318   string  err_description="";
1319   obj= PyRun_String(expr.c_str(), Py_file_input, main_dict, NULL);
1320   if (obj == NULL){
1321     fflush(stderr);
1322     err_description="";
1323     new_stderr=newPyStdOut(err_description);
1324     PySys_SetObject("stderr", new_stderr);
1325     PyErr_Print();
1326     PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
1327     Py_DECREF(new_stderr);
1328     if (displayError)
1329       SUIT_MessageBox::warning( dlg(),"Definition of Python Function : Error" ,err_description.c_str() );
1330     PyGILState_Release(gstate);
1331     return false;
1332   }
1333   Py_DECREF(obj);
1334
1335   PyObject * func = NULL;
1336   func = PyObject_GetAttrString(main_mod, "f");
1337   if ( func == NULL){
1338     fflush(stderr);
1339     err_description="";
1340     new_stderr=newPyStdOut(err_description);
1341     PySys_SetObject("stderr", new_stderr);
1342     PyErr_Print();
1343     PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
1344     Py_DECREF(new_stderr);
1345     if (displayError)
1346       SUIT_MessageBox::warning( dlg(),"Python Error" ,err_description.c_str() );
1347     PyGILState_Release(gstate);
1348     return false;
1349   }
1350
1351   PyGILState_Release(gstate);
1352
1353   MESSAGE("SizeMap expression "<<expr<<" is valid");
1354
1355   return true;
1356 }
1357
1358 /*
1359 void BLSURFPluginGUI_HypothesisCreator::OnEditMapFunction(QModelIndex* index) {
1360   int myRow = index->row();
1361   int myColumn = index->column();
1362
1363   if (myColumn == 2){
1364      if (!myEditor) {
1365          myEditor = new BLSURFPluginGUI_MapFunctionEditor(sizeMapModel->item(myRow,0)->text());
1366          connect(myEditor, SIGNAL(FunctionEntered(QString)), this, SLOT(FunctionLightValidation(QString)));
1367      }
1368      myEditor->exec();
1369 //      myEditor->show();
1370 //      myEditor->raise();
1371 //      myEditor->activateWindow();
1372
1373
1374 //     BLSURFPluginGUI_MapFunctionEditor* myEditor = new BLSURFPluginGUI_MapFunctionEditor(sizeMapModel->item(myRow,0)->text());
1375 //     myEditor->exec();
1376      QString myFunction = myEditor->GetFunctionText();
1377      // FIN RECUPERATION FONCTION
1378
1379      if (! myFunction.isEmpty()) {
1380
1381      // MAJ DE LA MAP
1382
1383      BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
1384        BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis());
1385
1386 //     h->SetSizeMapEntry(sizeMapModel->item(myRow,1)->text().toLatin1().constData(),
1387 //                        item->text().toLatin1().constData());
1388      h->SetSizeMapEntry(sizeMapModel->item(myRow,1)->text().toLatin1().constData(),
1389                         myFunction.toLatin1().constData());
1390      // FIN MAJ DE LA MAP
1391      }
1392   }
1393 }*/
1394
1395 QString BLSURFPluginGUI_HypothesisCreator::caption() const
1396 {
1397   return tr( "BLSURF_TITLE" );
1398 }
1399
1400 QPixmap BLSURFPluginGUI_HypothesisCreator::icon() const
1401 {
1402   return SUIT_Session::session()->resourceMgr()->loadPixmap( "BLSURFPlugin", tr( "ICON_DLG_BLSURF_PARAMETERS") );
1403 }
1404
1405 QString BLSURFPluginGUI_HypothesisCreator::type() const
1406 {
1407   return tr( "BLSURF_HYPOTHESIS" );
1408 }
1409
1410 QString BLSURFPluginGUI_HypothesisCreator::helpPage() const
1411 {
1412   return "blsurf_hypo_page.html";
1413 }
1414
1415 LightApp_SelectionMgr* BLSURFPluginGUI_HypothesisCreator::selectionMgr()
1416 {
1417
1418   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
1419   if( anApp )
1420     return dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
1421   else
1422     return 0;
1423 }
1424