Salome HOME
Size Map feature integration.
[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 <QtxDoubleSpinBox.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   if (that->GeomToolSelected == NULL or that->GeomToolSelected->getMyStudy() != aStudy) {
265     MESSAGE("GeomToolSelected is created");
266     that->GeomToolSelected = new GeomSelectionTools(aStudy);
267   }
268   else
269     MESSAGE("GeomToolSelected already exists");
270   return that->GeomToolSelected;
271 }
272
273 namespace {
274   inline bool isDouble( const QString& theText, const bool emptyOK=false ) {
275     QString str = theText.trimmed();
276     bool isOk = true;
277     if ( !str.isEmpty() )
278       str.toDouble(&isOk);
279     else
280       isOk = emptyOK;
281     return isOk;
282   }
283 }
284
285
286 bool BLSURFPluginGUI_HypothesisCreator::checkParams() const
287 {
288   MESSAGE("BLSURFPluginGUI_HypothesisCreator::checkParams"); 
289   bool ok = true;
290   if ( !isDouble( myPhySize->text(), false )) {
291     if ( myPhySize->text().isEmpty() )
292       myPhySize->setText(tr("OBLIGATORY_VALUE"));
293     myPhySize->selectAll();
294     ok = false;
295   }
296   if ( !isDouble( myPhyMin->text(), true )) {
297     myPhyMin->selectAll();
298     ok = false;
299   }
300   if ( !isDouble( myPhyMax->text(), true )) {
301     myPhyMax->selectAll();
302     ok = false;
303   }
304   if ( !isDouble( myGeoMin->text(), true )) {
305     myGeoMin->selectAll();
306     ok = false;
307   }
308   if ( !isDouble( myGeoMin->text(), true )) {
309     myGeoMin->selectAll();
310     ok = false;
311   }
312   if ( ok )
313   {
314     myOptionTable->setFocus();
315     QApplication::instance()->processEvents();
316
317     BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
318       BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis() );
319
320     int row = 0, nbRows = myOptionTable->rowCount();
321     for ( ; row < nbRows; ++row )
322     {
323       QString name  = myOptionTable->item( row, OPTION_NAME_COLUMN )->text();
324       QString value = myOptionTable->item( row, OPTION_VALUE_COLUMN )->text().trimmed();
325       if ( !value.isEmpty() ) {
326         try {
327           h->SetOptionValue( name.toLatin1().constData(), value.toLatin1().constData() );
328         }
329         catch ( const SALOME::SALOME_Exception& ex )
330         {
331           SUIT_MessageBox::critical( dlg(),
332                                      tr("SMESH_ERROR"),
333                                      ex.details.text.in() );
334           ok = false;
335         }
336       }
337     }
338     h->SetOptionValues( myOptions ); // restore values
339   }
340
341   // SizeMap
342   if ( ok )
343   {
344     mySizeMapTable->setFocus();
345     QApplication::instance()->processEvents();
346
347     BLSURFPlugin::BLSURFPlugin_Hypothesis_var h = BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis() );
348     BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
349
350     int row = 0, nbRows = mySizeMapTable->rowCount();
351     for ( ; row < nbRows; ++row )
352     {
353       QString entry   = mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->text();
354       QString sizeMap = mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->text().trimmed();
355       if ( !sizeMap.isEmpty() ) {
356         if (that->sizeMapValidationFromRow(row))
357         {
358           try {
359             const char* e = entry.toLatin1().constData();
360             const char* s = that->mySMPMap[entry].toLatin1().constData();
361             h->SetSizeMapEntry( e, s );
362           }
363           catch ( const SALOME::SALOME_Exception& ex )
364           {
365             SUIT_MessageBox::critical( dlg(),
366                                        tr("SMESH_ERROR"),
367                                        ex.details.text.in() );
368             ok = false;
369           }
370         }
371         else {
372           ok = false;
373         }
374       }
375     }
376   }
377
378   return ok;
379 }
380
381 QFrame* BLSURFPluginGUI_HypothesisCreator::buildFrame()
382 {
383   MESSAGE("BLSURFPluginGUI_HypothesisCreator::buildFrame");
384   QFrame* fr = new QFrame( 0 );
385   QVBoxLayout* lay = new QVBoxLayout( fr );
386   lay->setMargin( 5 );
387   lay->setSpacing( 0 );
388
389   // tab
390   QTabWidget* tab = new QTabWidget( fr );
391   tab->setTabShape( QTabWidget::Rounded );
392   tab->setTabPosition( QTabWidget::North );
393   lay->addWidget( tab );
394
395   // basic parameters
396   myStdGroup = new QWidget();
397   QGridLayout* aStdLayout = new QGridLayout( myStdGroup );
398   aStdLayout->setSpacing( 6 );
399   aStdLayout->setMargin( 11 );
400
401   int row = 0;
402   myName = 0;
403   if( isCreation() ) {
404     aStdLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), myStdGroup ), row, 0, 1, 1 );
405     myName = new QLineEdit( myStdGroup );
406     aStdLayout->addWidget( myName, row++, 1, 1, 1 );
407   }
408
409   aStdLayout->addWidget( new QLabel( tr( "BLSURF_PHY_MESH" ), myStdGroup ), row, 0, 1, 1 );
410   myPhysicalMesh = new QComboBox( myStdGroup );
411   aStdLayout->addWidget( myPhysicalMesh, row++, 1, 1, 1 );
412   QStringList physicalTypes;
413   physicalTypes << tr( "BLSURF_DEFAULT_USER" ) << tr( "BLSURF_CUSTOM_USER" ) << tr( "BLSURF_SIZE_MAP");
414   myPhysicalMesh->addItems( physicalTypes );
415
416   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYDEF" ), myStdGroup), row, 0, 1, 1 );
417   myPhySize = new QLineEdit( myStdGroup );
418   aStdLayout->addWidget( myPhySize, row++, 1, 1, 1 );
419
420 #ifdef WITH_SIZE_BOUNDARIES
421   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYMIN" ), myStdGroup ), row, 0, 1, 1 );
422   myPhyMin = new QLineEdit( myStdGroup );
423   aStdLayout->addWidget( myPhyMin, row++, 1, 1, 1 );
424
425   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYMAX" ), myStdGroup ), row, 0, 1, 1 );
426   myPhyMax = new QLineEdit( myStdGroup );
427   aStdLayout->addWidget( myPhyMax, row++, 1, 1, 1 );
428 #endif
429
430   aStdLayout->addWidget( new QLabel( tr( "BLSURF_GEOM_MESH" ), myStdGroup ), row, 0, 1, 1 );
431   myGeometricMesh = new QComboBox( myStdGroup );
432   aStdLayout->addWidget( myGeometricMesh, row++, 1, 1, 1 );
433   QStringList types;
434   types << tr( "BLSURF_DEFAULT_GEOM" ) << tr( "BLSURF_CUSTOM_GEOM" );
435   myGeometricMesh->addItems( types );
436
437   aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_S" ), myStdGroup ), row, 0, 1, 1 );
438   myAngleMeshS = new QtxDoubleSpinBox( myStdGroup );
439   aStdLayout->addWidget( myAngleMeshS, row++, 1, 1, 1 );
440   myAngleMeshS->setMinimum( 0 );
441   myAngleMeshS->setMaximum( 16 );
442   myAngleMeshS->setSingleStep( 0.5 );
443   
444   aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_C" ), myStdGroup ), row, 0, 1, 1 );
445   myAngleMeshC = new QtxDoubleSpinBox( myStdGroup );
446   aStdLayout->addWidget( myAngleMeshC, row++, 1, 1, 1 );
447   myAngleMeshC->setMinimum( 0 );
448   myAngleMeshC->setMaximum( 16 );
449   myAngleMeshC->setSingleStep( 0.5 );
450   
451   aStdLayout->addWidget( new QLabel( tr( "BLSURF_GRADATION" ), myStdGroup ), row, 0, 1, 1 );
452   myGradation = new QtxDoubleSpinBox( myStdGroup );
453   aStdLayout->addWidget( myGradation, row++, 1, 1, 1 );
454   myGradation->setMinimum( 1.1 );
455   myGradation->setMaximum( 2.5 );
456   myGradation->setSingleStep( 0.1 );
457
458 #ifdef WITH_SIZE_BOUNDARIES
459   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HGEOMIN" ), myStdGroup ), row, 0, 1, 1 );
460   myGeoMin = new QLineEdit( myStdGroup );
461   aStdLayout->addWidget( myGeoMin, row++, 1, 1, 1 );
462
463   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HGEOMAX" ), myStdGroup ), row, 0, 1, 1 );
464   myGeoMax = new QLineEdit( myStdGroup );
465   aStdLayout->addWidget( myGeoMax, row++, 1, 1, 1 );
466 #endif
467
468   myAllowQuadrangles = new QCheckBox( tr( "BLSURF_ALLOW_QUADRANGLES" ), myStdGroup );
469   aStdLayout->addWidget( myAllowQuadrangles, row++, 0, 1, 2 );
470
471   myDecimesh = new QCheckBox( tr( "BLSURF_DECIMESH" ), myStdGroup );
472   aStdLayout->addWidget( myDecimesh, row++, 0, 1, 2 );
473   
474   // advanced parameters
475   myAdvGroup = new QWidget();
476   QGridLayout* anAdvLayout = new QGridLayout( myAdvGroup );
477   anAdvLayout->setSpacing( 6 );
478   anAdvLayout->setMargin( 11 );
479
480   anAdvLayout->addWidget( new QLabel( tr( "BLSURF_TOPOLOGY" ), myAdvGroup ), 0, 0, 1, 1 );
481   myTopology = new QComboBox( myAdvGroup );
482   anAdvLayout->addWidget( myTopology, 0, 1, 1, 1 );
483   QStringList topologyTypes;
484   topologyTypes << tr( "BLSURF_TOPOLOGY_CAD" ) << tr( "BLSURF_TOPOLOGY_PROCESS" ) << tr( "BLSURF_TOPOLOGY_PROCESS2" );
485   myTopology->addItems( topologyTypes );
486
487   anAdvLayout->addWidget( new QLabel( tr( "BLSURF_VERBOSITY" ), myAdvGroup ), 1, 0, 1, 1 );
488   myVerbosity = new QSpinBox( myAdvGroup );
489   anAdvLayout->addWidget( myVerbosity, 1, 1, 1, 1 );
490   myVerbosity->setMinimum( 0 );
491   myVerbosity->setMaximum( 100 );
492   myVerbosity->setSingleStep( 5 );
493
494   myOptionTable = new QTableWidget( 0, NB_COLUMNS, myAdvGroup );
495   anAdvLayout->addWidget( myOptionTable, 2, 0, 3, 2 );
496   QStringList headers;
497   headers << tr( "OPTION_ID_COLUMN" ) << tr( "OPTION_NAME_COLUMN" ) << tr( "OPTION_VALUE_COLUMN" );
498   myOptionTable->setHorizontalHeaderLabels( headers );
499   myOptionTable->horizontalHeader()->hideSection( OPTION_ID_COLUMN );
500   //myOptionTable->setColumnReadOnly( OPTION_NAME_COLUMN, TRUE );//////
501   //myOptionTable->setColumnReadOnly( OPTION_VALUE_COLUMN, FALSE );/////
502   myOptionTable->verticalHeader()->hide();
503   //myOptionTable->setSelectionBehavior( QAbstractItemView::SelectRows );
504
505   QPushButton* addBtn = new QPushButton( tr( "ADD_OPTION"),  myAdvGroup );
506   anAdvLayout->addWidget( addBtn, 2, 2, 1, 1 );
507   addBtn->setMenu( new QMenu() );
508
509   QPushButton* rmBtn = new QPushButton( tr( "REMOVE_OPTION"), myAdvGroup );
510   anAdvLayout->addWidget( rmBtn, 3, 2, 1, 1 );
511
512   anAdvLayout->setRowStretch( 4, 5 );
513   anAdvLayout->setColumnStretch( 1, 5 );
514
515   // Size Maps parameters
516   
517   mySmpGroup = new QWidget();
518   QGridLayout* anSmpLayout = new QGridLayout(mySmpGroup);
519
520   mySizeMapTable = new QTableWidget( 0, SMP_NB_COLUMNS, mySmpGroup );
521   anSmpLayout->addWidget(mySizeMapTable, 1, 0, 8, 1);
522   QStringList sizeMapHeaders;
523   sizeMapHeaders << tr( "SMP_ENTRY_COLUMN" )<< tr( "SMP_NAME_COLUMN" ) << tr( "SMP_SIZEMAP_COLUMN" ); 
524   mySizeMapTable->setHorizontalHeaderLabels(sizeMapHeaders);
525   mySizeMapTable->horizontalHeader()->hideSection( SMP_ENTRY_COLUMN );
526   mySizeMapTable->resizeColumnToContents(SMP_NAME_COLUMN);
527   mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
528   mySizeMapTable->setAlternatingRowColors(true);
529   mySizeMapTable->verticalHeader()->hide();
530
531 /*
532   addAttractorButton = new QPushButton(tr("BLSURF_SM_ATTRACTOR"),mySmpGroup);
533   anSmpLayout->addWidget(addAttractorButton, SMP_ATTRACTOR_BTN, 1, 1, 1);
534
535   QFrame *line = new QFrame(mySmpGroup);
536   line->setFrameShape(QFrame::HLine);
537   line->setFrameShadow(QFrame::Sunken);
538   anSmpLayout->addWidget(line, SMP_SEPARATOR1, 1, 1, 1);
539 */
540   addSurfaceButton = new QPushButton(tr("BLSURF_SM_SURFACE"),mySmpGroup);
541   anSmpLayout->addWidget(addSurfaceButton, SMP_SURFACE_BTN, 1, 1, 1);
542
543   addEdgeButton = new QPushButton(tr("BLSURF_SM_EDGE"),mySmpGroup);
544   anSmpLayout->addWidget(addEdgeButton, SMP_EDGE_BTN, 1, 1, 1);
545
546   addPointButton = new QPushButton(tr("BLSURF_SM_POINT"),mySmpGroup);
547   anSmpLayout->addWidget(addPointButton, SMP_POINT_BTN, 1, 1, 1);
548
549   QFrame *line2 = new QFrame(mySmpGroup);
550   line2->setFrameShape(QFrame::HLine);
551   line2->setFrameShadow(QFrame::Sunken);
552   anSmpLayout->addWidget(line2, SMP_SEPARATOR2, 1, 1, 1);
553
554   removeButton = new QPushButton(tr("BLSURF_SM_REMOVE"),mySmpGroup);
555   anSmpLayout->addWidget(removeButton, SMP_REMOVE_BTN, 1, 1, 1);
556   
557
558   // ---
559   tab->insertTab( STD_TAB, myStdGroup, tr( "SMESH_ARGUMENTS" ) );
560   tab->insertTab( ADV_TAB, myAdvGroup, tr( "BLSURF_ADV_ARGS" ) );
561   tab->insertTab( SMP_TAB, mySmpGroup, tr( "BLSURF_SIZE_MAP" ) );
562
563   tab->setCurrentIndex( STD_TAB );
564
565   // ---
566   connect( myGeometricMesh, SIGNAL( activated( int ) ), this, SLOT( onGeometricMeshChanged() ) );
567   connect( myPhysicalMesh,  SIGNAL( activated( int ) ), this, SLOT( onPhysicalMeshChanged() ) );
568   connect( addBtn->menu(),  SIGNAL( aboutToShow() ),    this, SLOT( onAddOption() ) );
569   connect( addBtn->menu(),  SIGNAL( triggered( QAction* ) ), this, SLOT( onOptionChosenInPopup( QAction* ) ) );
570   connect( rmBtn,           SIGNAL( clicked()),         this, SLOT( onDeleteOption() ) );
571   
572   connect(addSurfaceButton, SIGNAL(clicked()), this, SLOT(onAddMapOnSurface()));
573   connect(addEdgeButton, SIGNAL(clicked()), this, SLOT(onAddMapOnEdge()));
574   connect(addPointButton, SIGNAL(clicked()), this, SLOT(onAddMapOnPoint()));
575   connect(removeButton, SIGNAL(clicked()), this, SLOT(onRemoveMap()));
576   connect(mySizeMapTable, SIGNAL(cellChanged ( int, int  )),this,SLOT (onSetSizeMap(int,int )));
577
578   return fr;
579 }
580
581 void BLSURFPluginGUI_HypothesisCreator::retrieveParams() const
582 {
583   MESSAGE("BLSURFPluginGUI_HypothesisCreator::retrieveParams");
584   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
585
586   BlsurfHypothesisData data;
587   that->readParamsFromHypo( data );
588
589   if ( myName ) {
590     myName->setText( data.myName );
591     QFontMetrics metrics( myName->font() );
592     myName->setMinimumWidth( metrics.width( data.myName )+5 );
593   }
594   myTopology->setCurrentIndex( data.myTopology );
595   myPhysicalMesh->setCurrentIndex( data.myPhysicalMesh );
596   myPhySize->setText( data.myPhySize );
597 #ifdef WITH_SIZE_BOUNDARIES
598   myPhyMin->setText( data.myPhyMin );
599   myPhyMax->setText( data.myPhyMax );
600   myGeoMin->setText( data.myGeoMin );
601   myGeoMax->setText( data.myGeoMax );
602 #endif
603   myGeometricMesh->setCurrentIndex( data.myGeometricMesh );
604   myAngleMeshS->setValue( data.myAngleMeshS );
605   myAngleMeshC->setValue( data.myAngleMeshC );
606   myGradation->setValue( data.myGradation );
607   myAllowQuadrangles->setChecked( data.myAllowQuadrangles );
608   myDecimesh->setChecked( data.myDecimesh );
609   myVerbosity->setValue( data.myVerbosity );
610   
611   if ( myOptions.operator->() ) {
612     printf("retrieveParams():myOptions->length()=%d\n",myOptions->length());
613     for ( int i = 0, nb = myOptions->length(); i < nb; ++i ) {
614       QString option = that->myOptions[i].in();
615       QStringList name_value = option.split( ":", QString::KeepEmptyParts );
616       if ( name_value.count() > 1 ) {
617         QString idStr = QString("%1").arg( i );
618         int row = myOptionTable->rowCount();
619         myOptionTable->setRowCount( row+1 );
620         myOptionTable->setItem( row, OPTION_ID_COLUMN, new QTableWidgetItem( idStr ) );
621         myOptionTable->item( row, OPTION_ID_COLUMN )->setFlags( 0 );
622         myOptionTable->setItem( row, OPTION_NAME_COLUMN, new QTableWidgetItem( name_value[0] ) );
623         myOptionTable->item( row, OPTION_NAME_COLUMN )->setFlags( 0 );
624         myOptionTable->setItem( row, OPTION_VALUE_COLUMN, new QTableWidgetItem( name_value[1] ) );
625         myOptionTable->item( row, OPTION_VALUE_COLUMN )->setFlags( Qt::ItemIsSelectable | 
626                                                                    Qt::ItemIsEditable   | 
627                                                                    Qt::ItemIsEnabled );
628       }
629     } 
630   }
631   myOptionTable->resizeColumnToContents( OPTION_NAME_COLUMN );
632
633   printf("retrieveParams():that->mySMPMap.size()=%d\n",that->mySMPMap.size());
634   QMapIterator<QString, QString> i(that->mySMPMap);
635   GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool();
636   while (i.hasNext()) {
637     i.next();
638     const QString entry = i.key();
639     string shapeName = myGeomToolSelected->getNameFromEntry(entry.toStdString());
640     const QString sizeMap = i.value();
641     int row = mySizeMapTable->rowCount();
642     mySizeMapTable->setRowCount( row+1 );
643     mySizeMapTable->setItem( row, SMP_ENTRY_COLUMN, new QTableWidgetItem( entry ) );
644     mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->setFlags( 0 );
645     mySizeMapTable->setItem( row, SMP_NAME_COLUMN, new QTableWidgetItem( QString::fromStdString(shapeName) ) );
646     mySizeMapTable->item( row, SMP_NAME_COLUMN )->setFlags( 0 );
647     mySizeMapTable->setItem( row, SMP_SIZEMAP_COLUMN, new QTableWidgetItem( sizeMap ) );
648     mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->setFlags( Qt::ItemIsSelectable |
649                                                                Qt::ItemIsEditable   |
650                                                                Qt::ItemIsEnabled );
651     }
652   
653   mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN );
654   mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
655
656   // update widgets
657   that->onPhysicalMeshChanged();
658   that->onGeometricMeshChanged();
659 }
660
661 QString BLSURFPluginGUI_HypothesisCreator::storeParams() const
662 {
663   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
664
665   BlsurfHypothesisData data;
666   QString guiHyp = that->readParamsFromWidgets( data );
667   that->storeParamsToHypo( data );
668
669   return guiHyp;
670 }
671
672 bool BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo( BlsurfHypothesisData& h_data ) const
673 {
674   MESSAGE("BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo");
675   BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
676     BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis() );
677
678   HypothesisData* data = SMESH::GetHypothesisData( hypType() );
679   h_data.myName = isCreation() && data ? hypName() : "";
680
681   h_data.myTopology         = (int) h->GetTopology();
682   h_data.myPhysicalMesh     = (int) h->GetPhysicalMesh();
683   h_data.myPhySize          = QString::number( h->GetPhySize() );
684   h_data.myGeometricMesh    = (int) h->GetGeometricMesh();
685   h_data.myAngleMeshS       = h->GetAngleMeshS();
686   h_data.myAngleMeshC       = h->GetAngleMeshC();
687   h_data.myGradation        = h->GetGradation();
688   h_data.myAllowQuadrangles = h->GetQuadAllowed();
689   h_data.myDecimesh         = h->GetDecimesh();
690   h_data.myVerbosity        = h->GetVerbosity();
691
692 #ifdef WITH_SIZE_BOUNDARIES
693   double PhyMin = h->GetPhyMin();
694   double PhyMax = h->GetPhyMax();
695   double GeoMin = h->GetGeoMin();
696   double GeoMax = h->GetGeoMax();
697   if ( PhyMin > 0 )
698   h_data.myPhyMin = PhyMin > 0 ? QString::number( h->GetPhyMin() ) : QString("");
699   h_data.myPhyMax = PhyMax > 0 ? QString::number( h->GetPhyMax() ) : QString("");
700   h_data.myGeoMin = GeoMin > 0 ? QString::number( h->GetGeoMin() ) : QString("");
701   h_data.myGeoMax = GeoMax > 0 ? QString::number( h->GetGeoMax() ) : QString("");
702 #endif
703
704   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
705   that->myOptions = h->GetOptionValues();
706
707   that->mySMPMap.clear();
708
709   // classic size maps
710   BLSURFPlugin::string_array_var mySizeMaps = h->GetSizeMapEntries();
711   MESSAGE("mySizeMaps->length() = " << mySizeMaps->length());
712   QString fullSizeMaps;
713   QStringList fullSizeMapList;
714   GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool();
715   for ( int i = 0;i<mySizeMaps->length(); ++i ) {
716     fullSizeMaps =  mySizeMaps[i].in();
717     MESSAGE("fullSizeMaps: " << fullSizeMaps.toStdString());
718     fullSizeMapList = fullSizeMaps.split( "|", QString::KeepEmptyParts );
719     if ( fullSizeMapList.count() > 1 ) {
720       string fullSizeMap = fullSizeMapList[1].toStdString();
721       int pos = fullSizeMap.find("return")+7;
722       QString sizeMap = QString::fromStdString(fullSizeMap.substr(pos, fullSizeMap.size()-pos));
723       that->mySMPMap[fullSizeMapList[0]] = sizeMap;
724       MESSAGE("mySMPMap[" << fullSizeMapList[0].toStdString() << "] = " << sizeMap.toStdString());
725       that->mySMPShapeTypeMap[fullSizeMapList[0]] = myGeomToolSelected->entryToShape(fullSizeMapList[0].toStdString()).ShapeType();
726       MESSAGE("mySMPShapeTypeMap[" << fullSizeMapList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[fullSizeMapList[0]]);
727     }
728   }
729
730   // custom size maps
731 /*
732   BLSURFPlugin::string_array_var myCustomSizeMaps = h->GetCustomSizeMapEntries();
733   MESSAGE("myCustomSizeMaps->length() = " << myCustomSizeMaps->length());
734
735   for ( int i = 0;i<myCustomSizeMaps->length(); ++i ) {
736     QString fullCustomSizeMaps =  myCustomSizeMaps[i].in();
737     QStringList fullCustomSizeMapList = fullCustomSizeMaps.split( "|", QString::KeepEmptyParts );
738     if ( fullCustomSizeMapList.count() > 1 ) {
739       that->mySMPMap[fullCustomSizeMapList[0]] = fullCustomSizeMapList[1];
740       that->mySMPShapeTypeMap[fullCustomSizeMapList[0]] = GeomToolSelected->entryToShape(fullCustomSizeMapList[0].toStdString()).ShapeType();
741       MESSAGE("mySMPMap[" << fullCustomSizeMapList[0].toStdString() << "] = " << fullCustomSizeMapList[1].toStdString());
742       MESSAGE("mySMPShapeTypeMap[" << fullCustomSizeMapList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[fullCustomSizeMapList[0]]);
743     }
744   }
745 */
746   // attractor
747   BLSURFPlugin::string_array_var allMyAttractors = h->GetAttractorEntries();
748   MESSAGE("myAttractors->length() = " << allMyAttractors->length());
749
750   for ( int i = 0;i<allMyAttractors->length(); ++i ) {
751     QString myAttractors =  allMyAttractors[i].in();
752     QStringList myAttractorList = myAttractors.split( "|", QString::KeepEmptyParts );
753     if ( myAttractorList.count() > 1 ) {
754       that->mySMPMap[myAttractorList[0]] = myAttractorList[1];
755       that->mySMPShapeTypeMap[myAttractorList[0]] = myGeomToolSelected->entryToShape(myAttractorList[0].toStdString()).ShapeType();
756       MESSAGE("mySMPMap[" << myAttractorList[0].toStdString() << "] = " << myAttractorList[1].toStdString());
757       MESSAGE("mySMPShapeTypeMap[" << myAttractorList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[myAttractorList[0]]);
758     }
759   }
760
761   return true;
762 }
763
764 bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesisData& h_data ) const
765 {
766   MESSAGE("BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo");
767   BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
768     BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( hypothesis() );
769
770   bool ok = true;
771   try
772   {
773     if( isCreation() )
774       SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().constData() );
775
776     if ( h->GetTopology() != h_data.myTopology ) // avoid duplication of DumpPython commands
777       h->SetTopology( (int) h_data.myTopology );
778     if ( h->GetPhysicalMesh() != h_data.myPhysicalMesh )
779       h->SetPhysicalMesh( (int) h_data.myPhysicalMesh );
780     if ( h->GetGeometricMesh() != (int) h_data.myGeometricMesh )
781       h->SetGeometricMesh( (int) h_data.myGeometricMesh );
782     if ( h->GetGradation() !=  h_data.myGradation )
783       h->SetGradation( h_data.myGradation );
784     if ( h->GetQuadAllowed() != h_data.myAllowQuadrangles )
785       h->SetQuadAllowed( h_data.myAllowQuadrangles );
786     if ( h->GetDecimesh() != h_data.myDecimesh )
787       h->SetDecimesh( h_data.myDecimesh );
788     if ( h->GetVerbosity() != h_data.myVerbosity )
789       h->SetVerbosity( h_data.myVerbosity );
790
791     if( ((int) h_data.myPhysicalMesh == PhysicalUserDefined)||((int) h_data.myPhysicalMesh == SizeMap) ) {
792       if ( h->GetPhySize() != h_data.myPhySize.toDouble() )
793         h->SetPhySize( h_data.myPhySize.toDouble() );
794     }
795     if( (int) h_data.myGeometricMesh == UserDefined ) {
796       if ( h->GetAngleMeshS() != h_data.myAngleMeshS )
797         h->SetAngleMeshS( h_data.myAngleMeshS );
798       if ( h->GetAngleMeshC() != h_data.myAngleMeshC )
799         h->SetAngleMeshC( h_data.myAngleMeshC );
800     }
801 #ifdef WITH_SIZE_BOUNDARIES
802     if ( !isDouble( h_data.myPhyMin ))
803       h->SetPhyMin( -1 );
804     else if ( h->GetPhyMin() != h_data.myPhyMin.toDouble() )
805       h->SetPhyMin( h_data.myPhyMin.toDouble() );
806     if ( !isDouble( h_data.myPhyMax ))
807       h->SetPhyMax( -1 );
808     else if ( h->GetPhyMax() != h_data.myPhyMax.toDouble() )
809       h->SetPhyMax( h_data.myPhyMax.toDouble() );
810     if ( !isDouble( h_data.myGeoMin ))
811       h->SetGeoMin( -1 );
812     else if ( h->GetGeoMin() != h_data.myGeoMin.toDouble() )
813       h->SetGeoMin( h_data.myGeoMin.toDouble() );
814     if ( !isDouble( h_data.myGeoMax ))
815       h->SetGeoMax( -1 );
816     else if ( h->GetGeoMax() != h_data.myGeoMax.toDouble() )
817       h->SetGeoMax( h_data.myGeoMax.toDouble() );
818 #endif
819
820     //printf("storeParamsToHypo():myOptions->length()=%d\n",myOptions->length());
821     h->SetOptionValues( myOptions ); // is set in checkParams()
822
823     BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
824     QMapIterator<QString,QString> i(that->mySMPMap);
825     // Iterate over each size map
826     while (i.hasNext()) {
827       i.next();
828       const QString entry = i.key();
829       const QString sizeMap = i.value();
830
831       if (sizeMap == "__TO_DELETE__") {
832         MESSAGE("Delete entry " << entry.toStdString() << " from engine");
833         h->UnsetEntry(entry.toLatin1().constData());
834       }
835       else if (sizeMap.startsWith("ATTRACTOR")) {
836         MESSAGE("SetAttractorEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString());
837         h->SetAttractorEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData() );
838       }
839       else if (sizeMap.startsWith("def")) {
840         MESSAGE("SetCustomSizeMapEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString());
841 //        h->SetCustomSizeMapEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData() );
842       }
843       else {
844         QString fullSizeMap;
845         fullSizeMap = QString("");
846         if (that->mySMPShapeTypeMap[entry]  == TopAbs_FACE)
847           fullSizeMap = QString("def f(u,v): return ") + sizeMap;
848         else if (that->mySMPShapeTypeMap[entry]  == TopAbs_EDGE)
849           fullSizeMap = QString("def f(t): return ") + sizeMap;
850         else if (that->mySMPShapeTypeMap[entry] == TopAbs_VERTEX)
851           fullSizeMap = QString("def f(): return ") + sizeMap;
852
853         MESSAGE("SetSizeMapEntry("<<entry.toStdString()<<") = " <<fullSizeMap.toStdString());
854         h->SetSizeMapEntry( entry.toLatin1().constData(), fullSizeMap.toLatin1().constData() );
855       }
856     }
857   }
858   catch(const SALOME::SALOME_Exception& ex)
859   {
860     SalomeApp_Tools::QtCatchCorbaException(ex);
861     ok = false;
862   }
863   return ok;
864 }
865
866 QString BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets( BlsurfHypothesisData& h_data ) const
867 {
868   MESSAGE("BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets");
869   h_data.myName             = myName ? myName->text() : "";
870   h_data.myTopology         = myTopology->currentIndex();
871   h_data.myPhysicalMesh     = myPhysicalMesh->currentIndex();
872   h_data.myPhySize          = myPhySize->text();
873 #ifdef WITH_SIZE_BOUNDARIES
874   h_data.myPhyMin           = myPhyMin->text();
875   h_data.myPhyMax           = myPhyMax->text();
876   h_data.myGeoMin           = myGeoMin->text();
877   h_data.myGeoMax           = myGeoMax->text();
878 #endif
879   h_data.myGeometricMesh    = myGeometricMesh->currentIndex();
880   h_data.myAngleMeshS       = myAngleMeshS->value();
881   h_data.myAngleMeshC       = myAngleMeshC->value();
882   h_data.myGradation        = myGradation->value();
883   h_data.myAllowQuadrangles = myAllowQuadrangles->isChecked();
884   h_data.myDecimesh         = myDecimesh->isChecked();
885   h_data.myVerbosity        = myVerbosity->value();
886
887   QString guiHyp;
888   guiHyp += tr("BLSURF_TOPOLOGY") + " = " + QString::number( h_data.myTopology ) + "; ";
889   guiHyp += tr("BLSURF_PHY_MESH") + " = " + QString::number( h_data.myPhysicalMesh ) + "; ";
890   guiHyp += tr("BLSURF_HPHYDEF") + " = " + h_data.myPhySize + "; ";
891   guiHyp += tr("BLSURF_GEOM_MESH") + " = " + QString::number( h_data.myGeometricMesh ) + "; ";
892   guiHyp += tr("BLSURF_ANGLE_MESH_S") + " = " + QString::number( h_data.myAngleMeshS ) + "; ";
893   guiHyp += tr("BLSURF_GRADATION") + " = " + QString::number( h_data.myGradation ) + "; ";
894   guiHyp += tr("BLSURF_ALLOW_QUADRANGLES") + " = " + QString(h_data.myAllowQuadrangles ? "yes" : "no") + "; ";
895   guiHyp += tr("BLSURF_DECIMESH") + " = " + QString(h_data.myDecimesh ? "yes" : "no") + "; ";
896 #ifdef WITH_SIZE_BOUNDARIES
897   if ( isDouble( h_data.myPhyMin )) guiHyp += "hphymin = " + h_data.myPhyMin + "; ";
898   if ( isDouble( h_data.myPhyMax )) guiHyp += "hphymax = " + h_data.myPhyMax + "; ";
899   if ( isDouble( h_data.myGeoMin )) guiHyp += "hgeomin = " + h_data.myGeoMin + "; ";
900   if ( isDouble( h_data.myGeoMax )) guiHyp += "hgeomax = " + h_data.myGeoMax + "; ";
901 #endif
902
903   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
904   int row = 0, nbRows = myOptionTable->rowCount();
905   for ( ; row < nbRows; ++row )
906   {
907     int id = myOptionTable->item( row, OPTION_ID_COLUMN )->text().toInt();
908     if ( id >= 0 && id < myOptions->length() )
909     {
910       QString name  = myOptionTable->item( row, OPTION_NAME_COLUMN )->text();
911       QString value = myOptionTable->item( row, OPTION_VALUE_COLUMN )->text().trimmed();
912       if ( value.isNull() )
913         value = "";
914       that->myOptions[ id ] = ( name + ":" + value).toLatin1().constData();
915       if ( value != "" )
916         guiHyp += name + " = " + value + "; ";
917     }
918   }
919   
920   // SizeMap
921   row = 0, nbRows = mySizeMapTable->rowCount();
922   for ( ; row < nbRows; ++row )
923   {
924       QString entry   = mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->text();
925       if ( that->mySMPMap.contains(entry) )
926         guiHyp += entry + " = " + that->mySMPMap[entry] + "; ";
927   }
928   
929   MESSAGE("guiHyp : " << guiHyp.toLatin1().data());
930
931   return guiHyp;
932 }
933
934 void BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged() {
935   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged");
936   bool isCustom = ((myPhysicalMesh->currentIndex() == PhysicalUserDefined) || (myPhysicalMesh->currentIndex() == SizeMap)) ;
937   myPhySize->setEnabled(isCustom);
938   myPhyMax->setEnabled(isCustom);
939   myPhyMin->setEnabled(isCustom);
940
941   if ( !isCustom ) {
942     QString aPhySize = "";
943     switch( myPhysicalMesh->currentIndex() ) {
944       case DefaultSize:
945       default:
946         aPhySize = "10";
947         break;
948       }
949     myPhySize->setText( aPhySize );
950     if ( !isDouble( myPhyMin->text(), true ))
951       myPhyMin->setText("");
952     if ( !isDouble( myPhyMax->text(), true ))
953       myPhyMax->setText("");
954     if ( myGeometricMesh->currentIndex() == DefaultGeom ) {
955       myGeometricMesh->setCurrentIndex( UserDefined );
956       onGeometricMeshChanged();
957     }
958   }
959 }
960
961 void BLSURFPluginGUI_HypothesisCreator::onGeometricMeshChanged() {
962   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onGeometricMeshChanged");
963   bool isCustom = (myGeometricMesh->currentIndex() == UserDefined);
964   myAngleMeshS->setEnabled(isCustom);
965   myAngleMeshC->setEnabled(isCustom);
966   myGradation->setEnabled(isCustom);
967   myGeoMax->setEnabled(isCustom);
968   myGeoMin->setEnabled(isCustom);
969
970   if ( ! isCustom ) {
971     double aAngleMeshS, aGradation;
972     switch( myGeometricMesh->currentIndex() ) {
973       case DefaultGeom:
974       default:
975         aAngleMeshS = 8;
976         aGradation = 1.1;
977         break;
978       }
979     myAngleMeshS->setValue( aAngleMeshS );
980     myAngleMeshC->setValue( aAngleMeshS );
981     myGradation->setValue( aGradation );
982     if ( !isDouble( myGeoMin->text(), true ))
983       myGeoMin->setText("");
984     if ( !isDouble( myGeoMax->text(), true ))
985       myGeoMax->setText("");
986     //  hphy_flag = 0 and hgeo_flag = 0 is not allowed (spec)
987     if ( myPhysicalMesh->currentIndex() == DefaultSize ) {
988       myPhysicalMesh->setCurrentIndex( PhysicalUserDefined );
989       onPhysicalMeshChanged();
990     }
991   }
992 }
993
994 void BLSURFPluginGUI_HypothesisCreator::onAddOption()
995 {
996   QMenu* menu = (QMenu*)sender();
997   // fill popup with option names
998   menu->clear();
999   if ( myOptions.operator->() ) {
1000     for ( int i = 0, nb = myOptions->length(); i < nb; ++i ) {
1001       QString name_value = myOptions[i].in();
1002       QString name = name_value.split( ":", QString::KeepEmptyParts )[0];
1003       menu->addAction( name );
1004     }
1005   }
1006 }
1007
1008 void BLSURFPluginGUI_HypothesisCreator::onOptionChosenInPopup( QAction* a )
1009 {
1010   myOptionTable->setFocus();
1011   QMenu* menu = (QMenu*)( a->parent() );
1012   
1013   int idx = menu->actions().indexOf( a );
1014   QString idStr = QString("%1").arg( idx );
1015   QString option = myOptions[idx].in();
1016   QString optionName = option.split( ":", QString::KeepEmptyParts )[0];
1017
1018   // look for a row with optionName
1019   int row = 0, nbRows = myOptionTable->rowCount();
1020   for ( ; row < nbRows; ++row )
1021     if ( myOptionTable->item( row, OPTION_ID_COLUMN )->text() == idStr )
1022       break;
1023   // add a row if not found
1024   if ( row == nbRows ) {
1025     myOptionTable->setRowCount( row+1 );
1026     myOptionTable->setItem( row, OPTION_ID_COLUMN, new QTableWidgetItem( idStr ) );
1027     myOptionTable->item( row, OPTION_ID_COLUMN )->setFlags( 0 );
1028     myOptionTable->setItem( row, OPTION_NAME_COLUMN, new QTableWidgetItem( optionName ) );
1029     myOptionTable->item( row, OPTION_NAME_COLUMN )->setFlags( 0 );
1030     myOptionTable->setItem( row, OPTION_VALUE_COLUMN, new QTableWidgetItem( "" ) );
1031     myOptionTable->item( row, OPTION_VALUE_COLUMN )->setFlags( Qt::ItemIsSelectable | 
1032                                                                Qt::ItemIsEditable   | 
1033                                                                Qt::ItemIsEnabled );
1034     myOptionTable->resizeColumnToContents( OPTION_NAME_COLUMN );
1035   }
1036   myOptionTable->clearSelection();
1037   myOptionTable->scrollToItem( myOptionTable->item( row, OPTION_VALUE_COLUMN ) );
1038   //myOptionTable->item( row, OPTION_VALUE_COLUMN )->setSelected( true );
1039   myOptionTable->setCurrentCell( row, OPTION_VALUE_COLUMN );
1040   //myOptionTable->openPersistentEditor( myOptionTable->item( row, OPTION_VALUE_COLUMN ) );
1041 }
1042     
1043 void BLSURFPluginGUI_HypothesisCreator::onDeleteOption()
1044 {
1045   // clear option values and remember selected row
1046   QList<int> selectedRows;
1047   QList<QTableWidgetItem*> selected = myOptionTable->selectedItems(); 
1048   QTableWidgetItem* item;
1049   foreach( item, selected ) {
1050     int row = item->row();
1051     if ( !selectedRows.contains( row ) ) {
1052       selectedRows.append( row );
1053       int id = myOptionTable->item( row, OPTION_ID_COLUMN )->text().toInt();
1054       if ( id >= 0 && id < myOptions->length() )
1055         myOptions[ id ] = myOptionTable->item( row, OPTION_NAME_COLUMN )->text().toLatin1().constData();
1056     }
1057   }
1058   qSort( selectedRows );
1059   QListIterator<int> it( selectedRows );
1060   it.toBack();
1061   while ( it.hasPrevious() )
1062     myOptionTable->removeRow( it.previous() );
1063 }
1064
1065 // **********************
1066 // *** BEGIN SIZE MAP ***
1067 // **********************
1068
1069
1070 void BLSURFPluginGUI_HypothesisCreator::onRemoveMap()
1071 {
1072   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onRemoveMap()");
1073   QList<int> selectedRows;
1074   QList<QTableWidgetItem*> selected = mySizeMapTable->selectedItems();
1075   QTableWidgetItem* item;
1076   int row;
1077   foreach( item, selected ) {
1078     row = item->row();
1079     if ( !selectedRows.contains( row ) ) 
1080       selectedRows.append( row );
1081   }
1082
1083   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1084
1085   qSort( selectedRows );
1086   QListIterator<int> it( selectedRows );
1087   it.toBack();
1088   while ( it.hasPrevious() ) {
1089       row = it.previous();
1090       QString entry = mySizeMapTable->item(row,SMP_ENTRY_COLUMN)->text();
1091       if (that->mySMPMap.contains(entry))
1092         that->mySMPMap[entry] = "__TO_DELETE__";
1093       if (that->mySMPShapeTypeMap.contains(entry))
1094         that->mySMPShapeTypeMap.remove(entry);
1095       mySizeMapTable->removeRow(row );
1096   }
1097   mySizeMapTable->resizeColumnToContents(SMP_NAME_COLUMN);
1098   mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
1099 }
1100
1101 void BLSURFPluginGUI_HypothesisCreator::onSetSizeMap(int row,int col)
1102 {
1103   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onSetSizeMap("<< row << "," << col << ")");
1104   if (col == SMP_SIZEMAP_COLUMN) {
1105     BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1106     QString entry   = that->mySizeMapTable->item(row, SMP_ENTRY_COLUMN)->text();
1107     QString sizeMap = that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->text().trimmed();
1108     MESSAGE("entry: " << entry.toStdString() << ", sizeMap: " << sizeMap.toStdString());
1109     if (not that->mySMPShapeTypeMap.contains(entry))
1110       return;
1111     if (that->mySMPMap.contains(entry))
1112       if (that->mySMPMap[entry] == sizeMap)
1113         return;
1114     QColor* bgColor = new QColor("white");
1115     QColor* fgColor = new QColor("black");
1116     if (not sizeMap.isEmpty()) {
1117       that->mySMPMap[entry] = sizeMap;
1118       if (not sizeMapValidationFromRow(row)) {
1119         bgColor->setRgb(255,0,0);
1120         fgColor->setRgb(255,255,255);
1121       }
1122     }
1123     else {
1124       MESSAGE("Size map empty: reverse to precedent value" );
1125       that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setText(that->mySMPMap[entry]);
1126     }
1127     that->mySizeMapTable->item(row, SMP_NAME_COLUMN)->setBackground(QBrush(*bgColor));
1128     that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setBackground(QBrush(*bgColor));
1129     that->mySizeMapTable->item(row, SMP_NAME_COLUMN)->setForeground(QBrush(*fgColor));
1130     that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setForeground(QBrush(*fgColor));
1131     mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
1132   }
1133 }
1134
1135 void BLSURFPluginGUI_HypothesisCreator::onAddMapOnSurface()
1136 {
1137  insertElementType(TopAbs_FACE);
1138 }
1139
1140 void BLSURFPluginGUI_HypothesisCreator::onAddMapOnEdge()
1141 {
1142  insertElementType(TopAbs_EDGE);
1143 }
1144
1145 void BLSURFPluginGUI_HypothesisCreator::onAddMapOnPoint()
1146 {
1147  insertElementType(TopAbs_VERTEX);
1148 }
1149
1150 void BLSURFPluginGUI_HypothesisCreator::insertElementType(TopAbs_ShapeEnum typeShapeAsked)
1151 {
1152   MESSAGE("BLSURFPluginGUI_HypothesisCreator::insertElementType()");
1153
1154   BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
1155     BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis());
1156
1157   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1158
1159   TopoDS_Shape S;
1160   string entry, shapeName;
1161 //  LightApp_SelectionMgr* aSel = GeomToolSelected->selectionMgr();
1162
1163   SALOME_ListIO ListSelectedObjects;
1164   aSel->selectedObjects(ListSelectedObjects, NULL, false );
1165   if (!ListSelectedObjects.IsEmpty())
1166   {
1167     SALOME_ListIteratorOfListIO Object_It(ListSelectedObjects);
1168     GeomSelectionTools* myGeomToolSelected = getGeomSelectionTool();
1169     for (; Object_It.More(); Object_It.Next()) 
1170     {
1171       Handle(SALOME_InteractiveObject) anObject = Object_It.Value();
1172       entry     = myGeomToolSelected->getEntryOfObject(anObject);
1173       shapeName = anObject->getName();
1174       S         = myGeomToolSelected->entryToShape(entry);
1175       if ((! S.IsNull()) && (S.ShapeType() == typeShapeAsked)) 
1176       { 
1177         mySizeMapTable->setFocus();
1178         QString shapeEntry;
1179         shapeEntry = QString::fromStdString(entry);
1180         double phySize = h->GetPhySize();
1181         std::ostringstream oss;
1182         oss << phySize;
1183         QString sizeMap;
1184         sizeMap  = QString::fromStdString(oss.str());
1185         if (that->mySMPMap.contains(shapeEntry)) {
1186           if (that->mySMPMap[shapeEntry] != "__TO_DELETE__") {
1187             MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")");
1188             break;
1189           }
1190         }
1191         that->mySMPMap[shapeEntry] = sizeMap;
1192         that->mySMPShapeTypeMap[shapeEntry] = typeShapeAsked; 
1193         int row = mySizeMapTable->rowCount() ;
1194         mySizeMapTable->setRowCount( row+1 );
1195         mySizeMapTable->setItem( row, SMP_ENTRY_COLUMN, new QTableWidgetItem( shapeEntry ) );
1196         mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->setFlags( 0 );
1197         mySizeMapTable->setItem( row, SMP_NAME_COLUMN, new QTableWidgetItem( QString::fromStdString(shapeName) ) );
1198         mySizeMapTable->item( row, SMP_NAME_COLUMN )->setFlags( 0 );
1199         mySizeMapTable->setItem( row, SMP_SIZEMAP_COLUMN, new QTableWidgetItem( sizeMap ) );
1200         mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->setFlags( Qt::ItemIsSelectable |Qt::ItemIsEditable   |Qt::ItemIsEnabled );
1201         mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN );
1202         mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
1203         mySizeMapTable->clearSelection();
1204         mySizeMapTable->scrollToItem( mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN ) );
1205
1206         if ( myPhysicalMesh->currentIndex() != SizeMap ) {
1207           myPhysicalMesh->setCurrentIndex( SizeMap );
1208           onPhysicalMeshChanged();
1209         }
1210       }
1211     }
1212   }
1213 }
1214
1215 bool BLSURFPluginGUI_HypothesisCreator::sizeMapsValidation()
1216 {
1217   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapsValidation()");
1218   int row = 0, nbRows = mySizeMapTable->rowCount();
1219   for ( ; row < nbRows; ++row )
1220     if (not sizeMapValidationFromRow(row))
1221       return false;
1222   return true;
1223 }
1224
1225 bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow(int myRow, bool displayError)
1226 {
1227   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow()");
1228   QString myEntry   = mySizeMapTable->item( myRow, SMP_ENTRY_COLUMN )->text();
1229   bool res = sizeMapValidationFromEntry(myEntry,displayError);
1230   mySizeMapTable->setFocus();
1231   return res; 
1232 }
1233
1234 bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry(QString myEntry, bool displayError)
1235 {
1236   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry()");
1237
1238   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1239      
1240   if (not that->mySMPMap.contains(myEntry)) {
1241     MESSAGE("Geometry with entry "<<myEntry.toStdString()<<" was not found.");
1242     return false;
1243   }
1244   if (not that->mySMPShapeTypeMap.contains(myEntry)) {
1245     MESSAGE("Shape type with entry "<<myEntry.toStdString()<<" was not found.");
1246     return false;
1247   }
1248
1249   string expr;
1250
1251   if (that->mySMPMap[myEntry].startsWith("def")) {
1252     MESSAGE("custom function" );
1253     expr = that->mySMPMap[myEntry].toStdString();
1254   }
1255   else if (that->mySMPMap[myEntry].startsWith("ATTRACTOR")) {
1256     MESSAGE("Attractor" );
1257 //    if ((that->mySMPMap[myEntry].count(QRegExp("ATTRACTOR([0-9])")) != 1))
1258     if ((that->mySMPMap[myEntry].count('(') != 1) or 
1259         (that->mySMPMap[myEntry].count(')') != 1) or
1260         (that->mySMPMap[myEntry].count(';') != 4) or
1261         (that->mySMPMap[myEntry].size() == 15)){
1262       if (displayError)
1263         SUIT_MessageBox::warning( dlg(),"Definition of attractor : Error" ,"An attractor is defined with the following pattern: ATTRACTOR(xa;ya;za;a;b)" );
1264       return false;
1265     }
1266     return true;
1267   }
1268   else {
1269     // case size map is empty
1270     if (that->mySMPMap[myEntry].isEmpty()) {
1271       if (displayError)
1272         SUIT_MessageBox::warning( dlg(),"Definition of size map : Error" , "Size map can't be empty");
1273       return false;
1274     }
1275
1276     if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_FACE)
1277       expr = "def f(u,v) : return " + that->mySMPMap[myEntry].toStdString();
1278     else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_EDGE)
1279       expr = "def f(t) : return " + that->mySMPMap[myEntry].toStdString();
1280     else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_VERTEX)
1281       expr = "def f() : return " + that->mySMPMap[myEntry].toStdString();
1282   }
1283   //assert(Py_IsInitialized());
1284   if (not Py_IsInitialized())
1285     throw ("Erreur: Python interpreter is not initialized");
1286   PyGILState_STATE gstate;
1287   gstate = PyGILState_Ensure();
1288  
1289   PyObject * obj = NULL;   
1290   PyObject* new_stderr = NULL;   
1291   string  err_description="";
1292   obj= PyRun_String(expr.c_str(), Py_file_input, main_dict, NULL);
1293   if (obj == NULL){
1294     fflush(stderr);
1295     err_description="";
1296     new_stderr=newPyStdOut(err_description);
1297     PySys_SetObject("stderr", new_stderr);
1298     PyErr_Print();
1299     PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
1300     Py_DECREF(new_stderr);
1301     if (displayError)
1302       SUIT_MessageBox::warning( dlg(),"Definition of Python Function : Error" ,err_description.c_str() );
1303     PyGILState_Release(gstate);
1304     return false;
1305   }
1306   Py_DECREF(obj);
1307    
1308   PyObject * func = NULL;
1309   func = PyObject_GetAttrString(main_mod, "f");
1310   if ( func == NULL){
1311     fflush(stderr);                                                                            
1312     err_description="";                                                                        
1313     new_stderr=newPyStdOut(err_description);                                         
1314     PySys_SetObject("stderr", new_stderr);                                                     
1315     PyErr_Print();                                                                             
1316     PySys_SetObject("stderr", PySys_GetObject("__stderr__"));                                  
1317     Py_DECREF(new_stderr);
1318     if (displayError)
1319       SUIT_MessageBox::warning( dlg(),"Python Error" ,err_description.c_str() );
1320     PyGILState_Release(gstate);
1321     return false;
1322   }
1323
1324   PyGILState_Release(gstate);
1325
1326   MESSAGE("SizeMap expression "<<expr<<" is valid");
1327
1328   return true;
1329 }
1330
1331 /*
1332 void BLSURFPluginGUI_HypothesisCreator::OnEditMapFunction(QModelIndex* index) {
1333   int myRow = index->row();
1334   int myColumn = index->column();
1335   
1336   if (myColumn == 2){
1337      if (!myEditor) {
1338          myEditor = new BLSURFPluginGUI_MapFunctionEditor(sizeMapModel->item(myRow,0)->text());
1339          connect(myEditor, SIGNAL(FunctionEntered(QString)), this, SLOT(FunctionLightValidation(QString)));
1340      }
1341      myEditor->exec();
1342 //      myEditor->show();
1343 //      myEditor->raise();
1344 //      myEditor->activateWindow();
1345      
1346
1347 //     BLSURFPluginGUI_MapFunctionEditor* myEditor = new BLSURFPluginGUI_MapFunctionEditor(sizeMapModel->item(myRow,0)->text());
1348 //     myEditor->exec();
1349      QString myFunction = myEditor->GetFunctionText();
1350      // FIN RECUPERATION FONCTION
1351      
1352      if (! myFunction.isEmpty()) {
1353      
1354      // MAJ DE LA MAP
1355      
1356      BLSURFPlugin::BLSURFPlugin_Hypothesis_var h = 
1357        BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis());
1358
1359 //     h->SetSizeMapEntry(sizeMapModel->item(myRow,1)->text().toLatin1().constData(),
1360 //                        item->text().toLatin1().constData());
1361      h->SetSizeMapEntry(sizeMapModel->item(myRow,1)->text().toLatin1().constData(),
1362                         myFunction.toLatin1().constData());
1363      // FIN MAJ DE LA MAP
1364      }
1365   }
1366 }*/
1367  
1368 QString BLSURFPluginGUI_HypothesisCreator::caption() const
1369 {
1370   return tr( "BLSURF_TITLE" );
1371 }
1372
1373 QPixmap BLSURFPluginGUI_HypothesisCreator::icon() const
1374 {
1375   return SUIT_Session::session()->resourceMgr()->loadPixmap( "BLSURFPlugin", tr( "ICON_DLG_BLSURF_PARAMETERS") );
1376 }
1377
1378 QString BLSURFPluginGUI_HypothesisCreator::type() const
1379 {
1380   return tr( "BLSURF_HYPOTHESIS" );
1381 }
1382
1383 QString BLSURFPluginGUI_HypothesisCreator::helpPage() const
1384 {
1385   return "blsurf_hypo_page.html";
1386 }
1387
1388 LightApp_SelectionMgr* BLSURFPluginGUI_HypothesisCreator::selectionMgr()
1389 {
1390
1391   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
1392   if( anApp )
1393     return dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
1394   else
1395     return 0;
1396 }