Salome HOME
Fixes:
[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   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_PHY_MESH" ), myStdGroup ), row, 0, 1, 1 );
412   myPhysicalMesh = new QComboBox( myStdGroup );
413   aStdLayout->addWidget( myPhysicalMesh, row++, 1, 1, 1 );
414   QStringList physicalTypes;
415   physicalTypes << tr( "BLSURF_DEFAULT_USER" ) << tr( "BLSURF_CUSTOM_USER" ) << tr( "BLSURF_SIZE_MAP");
416   myPhysicalMesh->addItems( physicalTypes );
417
418   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYDEF" ), myStdGroup), row, 0, 1, 1 );
419   myPhySize = new QLineEdit( myStdGroup );
420   aStdLayout->addWidget( myPhySize, row++, 1, 1, 1 );
421
422 #ifdef WITH_SIZE_BOUNDARIES
423   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYMIN" ), myStdGroup ), row, 0, 1, 1 );
424   myPhyMin = new QLineEdit( myStdGroup );
425   aStdLayout->addWidget( myPhyMin, row++, 1, 1, 1 );
426
427   aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYMAX" ), myStdGroup ), row, 0, 1, 1 );
428   myPhyMax = new QLineEdit( myStdGroup );
429   aStdLayout->addWidget( myPhyMax, row++, 1, 1, 1 );
430 #endif
431
432   aStdLayout->addWidget( new QLabel( tr( "BLSURF_GEOM_MESH" ), myStdGroup ), row, 0, 1, 1 );
433   myGeometricMesh = new QComboBox( myStdGroup );
434   aStdLayout->addWidget( myGeometricMesh, row++, 1, 1, 1 );
435   QStringList types;
436   types << tr( "BLSURF_DEFAULT_GEOM" ) << tr( "BLSURF_CUSTOM_GEOM" );
437   myGeometricMesh->addItems( types );
438
439   aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_S" ), myStdGroup ), row, 0, 1, 1 );
440   myAngleMeshS = new QtxDoubleSpinBox( myStdGroup );
441   aStdLayout->addWidget( myAngleMeshS, row++, 1, 1, 1 );
442   myAngleMeshS->setMinimum( 0 );
443   myAngleMeshS->setMaximum( 16 );
444   myAngleMeshS->setSingleStep( 0.5 );
445
446   aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_C" ), myStdGroup ), row, 0, 1, 1 );
447   myAngleMeshC = new QtxDoubleSpinBox( myStdGroup );
448   aStdLayout->addWidget( myAngleMeshC, row++, 1, 1, 1 );
449   myAngleMeshC->setMinimum( 0 );
450   myAngleMeshC->setMaximum( 16 );
451   myAngleMeshC->setSingleStep( 0.5 );
452
453   aStdLayout->addWidget( new QLabel( tr( "BLSURF_GRADATION" ), myStdGroup ), row, 0, 1, 1 );
454   myGradation = new QtxDoubleSpinBox( myStdGroup );
455   aStdLayout->addWidget( myGradation, row++, 1, 1, 1 );
456   myGradation->setMinimum( 1.1 );
457   myGradation->setMaximum( 2.5 );
458   myGradation->setSingleStep( 0.1 );
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       QString sizeMap = QString::fromStdString(fullSizeMap.substr(pos, fullSizeMap.size()-pos));
725       that->mySMPMap[fullSizeMapList[0]] = sizeMap;
726       MESSAGE("mySMPMap[" << fullSizeMapList[0].toStdString() << "] = " << sizeMap.toStdString());
727       that->mySMPShapeTypeMap[fullSizeMapList[0]] = myGeomToolSelected->entryToShape(fullSizeMapList[0].toStdString()).ShapeType();
728       MESSAGE("mySMPShapeTypeMap[" << fullSizeMapList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[fullSizeMapList[0]]);
729     }
730   }
731
732   // custom size maps
733 /*
734   BLSURFPlugin::string_array_var myCustomSizeMaps = h->GetCustomSizeMapEntries();
735   MESSAGE("myCustomSizeMaps->length() = " << myCustomSizeMaps->length());
736
737   for ( int i = 0;i<myCustomSizeMaps->length(); ++i ) {
738     QString fullCustomSizeMaps =  myCustomSizeMaps[i].in();
739     QStringList fullCustomSizeMapList = fullCustomSizeMaps.split( "|", QString::KeepEmptyParts );
740     if ( fullCustomSizeMapList.count() > 1 ) {
741       that->mySMPMap[fullCustomSizeMapList[0]] = fullCustomSizeMapList[1];
742       that->mySMPShapeTypeMap[fullCustomSizeMapList[0]] = GeomToolSelected->entryToShape(fullCustomSizeMapList[0].toStdString()).ShapeType();
743       MESSAGE("mySMPMap[" << fullCustomSizeMapList[0].toStdString() << "] = " << fullCustomSizeMapList[1].toStdString());
744       MESSAGE("mySMPShapeTypeMap[" << fullCustomSizeMapList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[fullCustomSizeMapList[0]]);
745     }
746   }
747 */
748   // attractor
749   BLSURFPlugin::string_array_var allMyAttractors = h->GetAttractorEntries();
750   MESSAGE("myAttractors->length() = " << allMyAttractors->length());
751
752   for ( int i = 0;i<allMyAttractors->length(); ++i ) {
753     QString myAttractors =  allMyAttractors[i].in();
754     QStringList myAttractorList = myAttractors.split( "|", QString::KeepEmptyParts );
755     if ( myAttractorList.count() > 1 ) {
756       that->mySMPMap[myAttractorList[0]] = myAttractorList[1];
757       that->mySMPShapeTypeMap[myAttractorList[0]] = myGeomToolSelected->entryToShape(myAttractorList[0].toStdString()).ShapeType();
758       MESSAGE("mySMPMap[" << myAttractorList[0].toStdString() << "] = " << myAttractorList[1].toStdString());
759       MESSAGE("mySMPShapeTypeMap[" << myAttractorList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[myAttractorList[0]]);
760     }
761   }
762
763   return true;
764 }
765
766 bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesisData& h_data ) const
767 {
768   MESSAGE("BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo");
769   BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
770     BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( hypothesis() );
771
772   bool ok = true;
773   try
774   {
775     if( isCreation() )
776       SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().constData() );
777
778     if ( h->GetTopology() != h_data.myTopology ) // avoid duplication of DumpPython commands
779       h->SetTopology( (int) h_data.myTopology );
780     if ( h->GetPhysicalMesh() != h_data.myPhysicalMesh )
781       h->SetPhysicalMesh( (int) h_data.myPhysicalMesh );
782     if ( h->GetGeometricMesh() != (int) h_data.myGeometricMesh )
783       h->SetGeometricMesh( (int) h_data.myGeometricMesh );
784     if ( h->GetGradation() !=  h_data.myGradation )
785       h->SetGradation( h_data.myGradation );
786     if ( h->GetQuadAllowed() != h_data.myAllowQuadrangles )
787       h->SetQuadAllowed( h_data.myAllowQuadrangles );
788     if ( h->GetDecimesh() != h_data.myDecimesh )
789       h->SetDecimesh( h_data.myDecimesh );
790     if ( h->GetVerbosity() != h_data.myVerbosity )
791       h->SetVerbosity( h_data.myVerbosity );
792
793     if( ((int) h_data.myPhysicalMesh == PhysicalUserDefined)||((int) h_data.myPhysicalMesh == SizeMap) ) {
794       if ( h->GetPhySize() != h_data.myPhySize.toDouble() )
795         h->SetPhySize( h_data.myPhySize.toDouble() );
796     }
797     if( (int) h_data.myGeometricMesh == UserDefined ) {
798       if ( h->GetAngleMeshS() != h_data.myAngleMeshS )
799         h->SetAngleMeshS( h_data.myAngleMeshS );
800       if ( h->GetAngleMeshC() != h_data.myAngleMeshC )
801         h->SetAngleMeshC( h_data.myAngleMeshC );
802     }
803 #ifdef WITH_SIZE_BOUNDARIES
804     if ( !isDouble( h_data.myPhyMin ))
805       h->SetPhyMin( -1 );
806     else if ( h->GetPhyMin() != h_data.myPhyMin.toDouble() )
807       h->SetPhyMin( h_data.myPhyMin.toDouble() );
808     if ( !isDouble( h_data.myPhyMax ))
809       h->SetPhyMax( -1 );
810     else if ( h->GetPhyMax() != h_data.myPhyMax.toDouble() )
811       h->SetPhyMax( h_data.myPhyMax.toDouble() );
812     if ( !isDouble( h_data.myGeoMin ))
813       h->SetGeoMin( -1 );
814     else if ( h->GetGeoMin() != h_data.myGeoMin.toDouble() )
815       h->SetGeoMin( h_data.myGeoMin.toDouble() );
816     if ( !isDouble( h_data.myGeoMax ))
817       h->SetGeoMax( -1 );
818     else if ( h->GetGeoMax() != h_data.myGeoMax.toDouble() )
819       h->SetGeoMax( h_data.myGeoMax.toDouble() );
820 #endif
821
822     //printf("storeParamsToHypo():myOptions->length()=%d\n",myOptions->length());
823     h->SetOptionValues( myOptions ); // is set in checkParams()
824
825     BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
826     QMapIterator<QString,QString> i(that->mySMPMap);
827     // Iterate over each size map
828     while (i.hasNext()) {
829       i.next();
830       const QString entry = i.key();
831       const QString sizeMap = i.value();
832
833       if (sizeMap == "__TO_DELETE__") {
834         MESSAGE("Delete entry " << entry.toStdString() << " from engine");
835         h->UnsetEntry(entry.toLatin1().constData());
836       }
837       else if (sizeMap.startsWith("ATTRACTOR")) {
838         MESSAGE("SetAttractorEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString());
839         h->SetAttractorEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData() );
840       }
841       else if (sizeMap.startsWith("def")) {
842         MESSAGE("SetCustomSizeMapEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString());
843 //        h->SetCustomSizeMapEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData() );
844       }
845       else {
846         QString fullSizeMap;
847         fullSizeMap = QString("");
848         if (that->mySMPShapeTypeMap[entry]  == TopAbs_FACE)
849           fullSizeMap = QString("def f(u,v): return ") + sizeMap;
850         else if (that->mySMPShapeTypeMap[entry]  == TopAbs_EDGE)
851           fullSizeMap = QString("def f(t): return ") + sizeMap;
852         else if (that->mySMPShapeTypeMap[entry] == TopAbs_VERTEX)
853           fullSizeMap = QString("def f(): return ") + sizeMap;
854
855         MESSAGE("SetSizeMapEntry("<<entry.toStdString()<<") = " <<fullSizeMap.toStdString());
856         h->SetSizeMapEntry( entry.toLatin1().constData(), fullSizeMap.toLatin1().constData() );
857       }
858     }
859   }
860   catch(const SALOME::SALOME_Exception& ex)
861   {
862     SalomeApp_Tools::QtCatchCorbaException(ex);
863     ok = false;
864   }
865   return ok;
866 }
867
868 QString BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets( BlsurfHypothesisData& h_data ) const
869 {
870   MESSAGE("BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets");
871   h_data.myName             = myName ? myName->text() : "";
872   h_data.myTopology         = myTopology->currentIndex();
873   h_data.myPhysicalMesh     = myPhysicalMesh->currentIndex();
874   h_data.myPhySize          = myPhySize->text();
875 #ifdef WITH_SIZE_BOUNDARIES
876   h_data.myPhyMin           = myPhyMin->text();
877   h_data.myPhyMax           = myPhyMax->text();
878   h_data.myGeoMin           = myGeoMin->text();
879   h_data.myGeoMax           = myGeoMax->text();
880 #endif
881   h_data.myGeometricMesh    = myGeometricMesh->currentIndex();
882   h_data.myAngleMeshS       = myAngleMeshS->value();
883   h_data.myAngleMeshC       = myAngleMeshC->value();
884   h_data.myGradation        = myGradation->value();
885   h_data.myAllowQuadrangles = myAllowQuadrangles->isChecked();
886   h_data.myDecimesh         = myDecimesh->isChecked();
887   h_data.myVerbosity        = myVerbosity->value();
888
889   QString guiHyp;
890   guiHyp += tr("BLSURF_TOPOLOGY") + " = " + QString::number( h_data.myTopology ) + "; ";
891   guiHyp += tr("BLSURF_PHY_MESH") + " = " + QString::number( h_data.myPhysicalMesh ) + "; ";
892   guiHyp += tr("BLSURF_HPHYDEF") + " = " + h_data.myPhySize + "; ";
893   guiHyp += tr("BLSURF_GEOM_MESH") + " = " + QString::number( h_data.myGeometricMesh ) + "; ";
894   guiHyp += tr("BLSURF_ANGLE_MESH_S") + " = " + QString::number( h_data.myAngleMeshS ) + "; ";
895   guiHyp += tr("BLSURF_GRADATION") + " = " + QString::number( h_data.myGradation ) + "; ";
896   guiHyp += tr("BLSURF_ALLOW_QUADRANGLES") + " = " + QString(h_data.myAllowQuadrangles ? "yes" : "no") + "; ";
897   guiHyp += tr("BLSURF_DECIMESH") + " = " + QString(h_data.myDecimesh ? "yes" : "no") + "; ";
898 #ifdef WITH_SIZE_BOUNDARIES
899   if ( isDouble( h_data.myPhyMin )) guiHyp += "hphymin = " + h_data.myPhyMin + "; ";
900   if ( isDouble( h_data.myPhyMax )) guiHyp += "hphymax = " + h_data.myPhyMax + "; ";
901   if ( isDouble( h_data.myGeoMin )) guiHyp += "hgeomin = " + h_data.myGeoMin + "; ";
902   if ( isDouble( h_data.myGeoMax )) guiHyp += "hgeomax = " + h_data.myGeoMax + "; ";
903 #endif
904
905   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
906   int row = 0, nbRows = myOptionTable->rowCount();
907   for ( ; row < nbRows; ++row )
908   {
909     int id = myOptionTable->item( row, OPTION_ID_COLUMN )->text().toInt();
910     if ( id >= 0 && id < myOptions->length() )
911     {
912       QString name  = myOptionTable->item( row, OPTION_NAME_COLUMN )->text();
913       QString value = myOptionTable->item( row, OPTION_VALUE_COLUMN )->text().trimmed();
914       if ( value.isNull() )
915         value = "";
916       that->myOptions[ id ] = ( name + ":" + value).toLatin1().constData();
917       if ( value != "" )
918         guiHyp += name + " = " + value + "; ";
919     }
920   }
921
922   // SizeMap
923   row = 0, nbRows = mySizeMapTable->rowCount();
924   for ( ; row < nbRows; ++row )
925   {
926       QString entry   = mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->text();
927       if ( that->mySMPMap.contains(entry) )
928         guiHyp += entry + " = " + that->mySMPMap[entry] + "; ";
929   }
930
931   MESSAGE("guiHyp : " << guiHyp.toLatin1().data());
932
933   return guiHyp;
934 }
935
936 void BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged() {
937   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged");
938   bool isCustom = ((myPhysicalMesh->currentIndex() == PhysicalUserDefined) || (myPhysicalMesh->currentIndex() == SizeMap)) ;
939   myPhySize->setEnabled(isCustom);
940   myPhyMax->setEnabled(isCustom);
941   myPhyMin->setEnabled(isCustom);
942
943   if ( !isCustom ) {
944     QString aPhySize = "";
945     switch( myPhysicalMesh->currentIndex() ) {
946       case DefaultSize:
947       default:
948         aPhySize = "10";
949         break;
950       }
951     myPhySize->setText( aPhySize );
952     if ( !isDouble( myPhyMin->text(), true ))
953       myPhyMin->setText("");
954     if ( !isDouble( myPhyMax->text(), true ))
955       myPhyMax->setText("");
956     if ( myGeometricMesh->currentIndex() == DefaultGeom ) {
957       myGeometricMesh->setCurrentIndex( UserDefined );
958       onGeometricMeshChanged();
959     }
960   }
961 }
962
963 void BLSURFPluginGUI_HypothesisCreator::onGeometricMeshChanged() {
964   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onGeometricMeshChanged");
965   bool isCustom = (myGeometricMesh->currentIndex() == UserDefined);
966   myAngleMeshS->setEnabled(isCustom);
967   myAngleMeshC->setEnabled(isCustom);
968   myGradation->setEnabled(isCustom);
969   myGeoMax->setEnabled(isCustom);
970   myGeoMin->setEnabled(isCustom);
971
972   if ( ! isCustom ) {
973     double aAngleMeshS, aGradation;
974     switch( myGeometricMesh->currentIndex() ) {
975       case DefaultGeom:
976       default:
977         aAngleMeshS = 8;
978         aGradation = 1.1;
979         break;
980       }
981     myAngleMeshS->setValue( aAngleMeshS );
982     myAngleMeshC->setValue( aAngleMeshS );
983     myGradation->setValue( aGradation );
984     if ( !isDouble( myGeoMin->text(), true ))
985       myGeoMin->setText("");
986     if ( !isDouble( myGeoMax->text(), true ))
987       myGeoMax->setText("");
988     //  hphy_flag = 0 and hgeo_flag = 0 is not allowed (spec)
989     if ( myPhysicalMesh->currentIndex() == DefaultSize ) {
990       myPhysicalMesh->setCurrentIndex( PhysicalUserDefined );
991       onPhysicalMeshChanged();
992     }
993   }
994 }
995
996 void BLSURFPluginGUI_HypothesisCreator::onAddOption()
997 {
998   QMenu* menu = (QMenu*)sender();
999   // fill popup with option names
1000   menu->clear();
1001   if ( myOptions.operator->() ) {
1002     for ( int i = 0, nb = myOptions->length(); i < nb; ++i ) {
1003       QString name_value = myOptions[i].in();
1004       QString name = name_value.split( ":", QString::KeepEmptyParts )[0];
1005       menu->addAction( name );
1006     }
1007   }
1008 }
1009
1010 void BLSURFPluginGUI_HypothesisCreator::onOptionChosenInPopup( QAction* a )
1011 {
1012   myOptionTable->setFocus();
1013   QMenu* menu = (QMenu*)( a->parent() );
1014
1015   int idx = menu->actions().indexOf( a );
1016   QString idStr = QString("%1").arg( idx );
1017   QString option = myOptions[idx].in();
1018   QString optionName = option.split( ":", QString::KeepEmptyParts )[0];
1019
1020   // look for a row with optionName
1021   int row = 0, nbRows = myOptionTable->rowCount();
1022   for ( ; row < nbRows; ++row )
1023     if ( myOptionTable->item( row, OPTION_ID_COLUMN )->text() == idStr )
1024       break;
1025   // add a row if not found
1026   if ( row == nbRows ) {
1027     myOptionTable->setRowCount( row+1 );
1028     myOptionTable->setItem( row, OPTION_ID_COLUMN, new QTableWidgetItem( idStr ) );
1029     myOptionTable->item( row, OPTION_ID_COLUMN )->setFlags( 0 );
1030     myOptionTable->setItem( row, OPTION_NAME_COLUMN, new QTableWidgetItem( optionName ) );
1031     myOptionTable->item( row, OPTION_NAME_COLUMN )->setFlags( 0 );
1032     myOptionTable->setItem( row, OPTION_VALUE_COLUMN, new QTableWidgetItem( "" ) );
1033     myOptionTable->item( row, OPTION_VALUE_COLUMN )->setFlags( Qt::ItemIsSelectable |
1034                                                                Qt::ItemIsEditable   |
1035                                                                Qt::ItemIsEnabled );
1036     myOptionTable->resizeColumnToContents( OPTION_NAME_COLUMN );
1037   }
1038   myOptionTable->clearSelection();
1039   myOptionTable->scrollToItem( myOptionTable->item( row, OPTION_VALUE_COLUMN ) );
1040   //myOptionTable->item( row, OPTION_VALUE_COLUMN )->setSelected( true );
1041   myOptionTable->setCurrentCell( row, OPTION_VALUE_COLUMN );
1042   //myOptionTable->openPersistentEditor( myOptionTable->item( row, OPTION_VALUE_COLUMN ) );
1043 }
1044
1045 void BLSURFPluginGUI_HypothesisCreator::onDeleteOption()
1046 {
1047   // clear option values and remember selected row
1048   QList<int> selectedRows;
1049   QList<QTableWidgetItem*> selected = myOptionTable->selectedItems();
1050   QTableWidgetItem* item;
1051   foreach( item, selected ) {
1052     int row = item->row();
1053     if ( !selectedRows.contains( row ) ) {
1054       selectedRows.append( row );
1055       int id = myOptionTable->item( row, OPTION_ID_COLUMN )->text().toInt();
1056       if ( id >= 0 && id < myOptions->length() )
1057         myOptions[ id ] = myOptionTable->item( row, OPTION_NAME_COLUMN )->text().toLatin1().constData();
1058     }
1059   }
1060   qSort( selectedRows );
1061   QListIterator<int> it( selectedRows );
1062   it.toBack();
1063   while ( it.hasPrevious() )
1064     myOptionTable->removeRow( it.previous() );
1065 }
1066
1067 // **********************
1068 // *** BEGIN SIZE MAP ***
1069 // **********************
1070
1071
1072 void BLSURFPluginGUI_HypothesisCreator::onRemoveMap()
1073 {
1074   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onRemoveMap()");
1075   QList<int> selectedRows;
1076   QList<QTableWidgetItem*> selected = mySizeMapTable->selectedItems();
1077   QTableWidgetItem* item;
1078   int row;
1079   foreach( item, selected ) {
1080     row = item->row();
1081     if ( !selectedRows.contains( row ) )
1082       selectedRows.append( row );
1083   }
1084
1085   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1086
1087   qSort( selectedRows );
1088   QListIterator<int> it( selectedRows );
1089   it.toBack();
1090   while ( it.hasPrevious() ) {
1091       row = it.previous();
1092       QString entry = mySizeMapTable->item(row,SMP_ENTRY_COLUMN)->text();
1093       if (that->mySMPMap.contains(entry))
1094         that->mySMPMap[entry] = "__TO_DELETE__";
1095       if (that->mySMPShapeTypeMap.contains(entry))
1096         that->mySMPShapeTypeMap.remove(entry);
1097       mySizeMapTable->removeRow(row );
1098   }
1099   mySizeMapTable->resizeColumnToContents(SMP_NAME_COLUMN);
1100   mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
1101 }
1102
1103 void BLSURFPluginGUI_HypothesisCreator::onSetSizeMap(int row,int col)
1104 {
1105   MESSAGE("BLSURFPluginGUI_HypothesisCreator::onSetSizeMap("<< row << "," << col << ")");
1106   if (col == SMP_SIZEMAP_COLUMN) {
1107     BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1108     QString entry   = that->mySizeMapTable->item(row, SMP_ENTRY_COLUMN)->text();
1109     QString sizeMap = that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->text().trimmed();
1110     MESSAGE("entry: " << entry.toStdString() << ", sizeMap: " << sizeMap.toStdString());
1111     if (not that->mySMPShapeTypeMap.contains(entry))
1112       return;
1113     if (that->mySMPMap.contains(entry))
1114       if (that->mySMPMap[entry] == sizeMap)
1115         return;
1116     QColor* bgColor = new QColor("white");
1117     QColor* fgColor = new QColor("black");
1118     if (not sizeMap.isEmpty()) {
1119       that->mySMPMap[entry] = sizeMap;
1120       if (not sizeMapValidationFromRow(row)) {
1121         bgColor->setRgb(255,0,0);
1122         fgColor->setRgb(255,255,255);
1123       }
1124     }
1125     else {
1126       MESSAGE("Size map empty: reverse to precedent value" );
1127       that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setText(that->mySMPMap[entry]);
1128     }
1129     that->mySizeMapTable->item(row, SMP_NAME_COLUMN)->setBackground(QBrush(*bgColor));
1130     that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setBackground(QBrush(*bgColor));
1131     that->mySizeMapTable->item(row, SMP_NAME_COLUMN)->setForeground(QBrush(*fgColor));
1132     that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setForeground(QBrush(*fgColor));
1133     mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
1134   }
1135 }
1136
1137 void BLSURFPluginGUI_HypothesisCreator::onAddMapOnSurface()
1138 {
1139  insertElementType(TopAbs_FACE);
1140 }
1141
1142 void BLSURFPluginGUI_HypothesisCreator::onAddMapOnEdge()
1143 {
1144  insertElementType(TopAbs_EDGE);
1145 }
1146
1147 void BLSURFPluginGUI_HypothesisCreator::onAddMapOnPoint()
1148 {
1149  insertElementType(TopAbs_VERTEX);
1150 }
1151
1152 void BLSURFPluginGUI_HypothesisCreator::insertElementType(TopAbs_ShapeEnum typeShapeAsked)
1153 {
1154   MESSAGE("BLSURFPluginGUI_HypothesisCreator::insertElementType()");
1155
1156   BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
1157     BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis());
1158
1159   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1160
1161   TopoDS_Shape S;
1162   string entry, shapeName;
1163   GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool();
1164
1165   LightApp_SelectionMgr* mySel = myGeomToolSelected->selectionMgr();
1166
1167   SALOME_ListIO ListSelectedObjects;
1168   mySel->selectedObjects(ListSelectedObjects, NULL, false );
1169   if (!ListSelectedObjects.IsEmpty())
1170   {
1171     SALOME_ListIteratorOfListIO Object_It(ListSelectedObjects);
1172     for (; Object_It.More(); Object_It.Next())
1173     {
1174       Handle(SALOME_InteractiveObject) anObject = Object_It.Value();
1175       entry     = myGeomToolSelected->getEntryOfObject(anObject);
1176       shapeName = anObject->getName();
1177       S         = myGeomToolSelected->entryToShape(entry);
1178       if ((! S.IsNull()) && (S.ShapeType() == typeShapeAsked))
1179       {
1180         mySizeMapTable->setFocus();
1181         QString shapeEntry;
1182         shapeEntry = QString::fromStdString(entry);
1183         double phySize = h->GetPhySize();
1184         std::ostringstream oss;
1185         oss << phySize;
1186         QString sizeMap;
1187         sizeMap  = QString::fromStdString(oss.str());
1188         if (that->mySMPMap.contains(shapeEntry)) {
1189           if (that->mySMPMap[shapeEntry] != "__TO_DELETE__") {
1190             MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")");
1191             break;
1192           }
1193         }
1194         that->mySMPMap[shapeEntry] = sizeMap;
1195         that->mySMPShapeTypeMap[shapeEntry] = typeShapeAsked;
1196         int row = mySizeMapTable->rowCount() ;
1197         mySizeMapTable->setRowCount( row+1 );
1198         mySizeMapTable->setItem( row, SMP_ENTRY_COLUMN, new QTableWidgetItem( shapeEntry ) );
1199         mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->setFlags( 0 );
1200         mySizeMapTable->setItem( row, SMP_NAME_COLUMN, new QTableWidgetItem( QString::fromStdString(shapeName) ) );
1201         mySizeMapTable->item( row, SMP_NAME_COLUMN )->setFlags( 0 );
1202         mySizeMapTable->setItem( row, SMP_SIZEMAP_COLUMN, new QTableWidgetItem( sizeMap ) );
1203         mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->setFlags( Qt::ItemIsSelectable |Qt::ItemIsEditable   |Qt::ItemIsEnabled );
1204         mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN );
1205         mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN);
1206         mySizeMapTable->clearSelection();
1207         mySizeMapTable->scrollToItem( mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN ) );
1208
1209         if ( myPhysicalMesh->currentIndex() != SizeMap ) {
1210           myPhysicalMesh->setCurrentIndex( SizeMap );
1211           onPhysicalMeshChanged();
1212         }
1213       }
1214     }
1215   }
1216 }
1217
1218 bool BLSURFPluginGUI_HypothesisCreator::sizeMapsValidation()
1219 {
1220   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapsValidation()");
1221   int row = 0, nbRows = mySizeMapTable->rowCount();
1222   for ( ; row < nbRows; ++row )
1223     if (not sizeMapValidationFromRow(row))
1224       return false;
1225   return true;
1226 }
1227
1228 bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow(int myRow, bool displayError)
1229 {
1230   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow()");
1231   QString myEntry   = mySizeMapTable->item( myRow, SMP_ENTRY_COLUMN )->text();
1232   bool res = sizeMapValidationFromEntry(myEntry,displayError);
1233   mySizeMapTable->setFocus();
1234   return res;
1235 }
1236
1237 bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry(QString myEntry, bool displayError)
1238 {
1239   MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry()");
1240
1241   BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this;
1242
1243   if (not that->mySMPMap.contains(myEntry)) {
1244     MESSAGE("Geometry with entry "<<myEntry.toStdString()<<" was not found.");
1245     return false;
1246   }
1247   if (not that->mySMPShapeTypeMap.contains(myEntry)) {
1248     MESSAGE("Shape type with entry "<<myEntry.toStdString()<<" was not found.");
1249     return false;
1250   }
1251
1252   string expr;
1253
1254   if (that->mySMPMap[myEntry].startsWith("def")) {
1255     MESSAGE("custom function" );
1256     expr = that->mySMPMap[myEntry].toStdString();
1257   }
1258   else if (that->mySMPMap[myEntry].startsWith("ATTRACTOR")) {
1259     MESSAGE("Attractor" );
1260 //    if ((that->mySMPMap[myEntry].count(QRegExp("ATTRACTOR([0-9])")) != 1))
1261     if ((that->mySMPMap[myEntry].count('(') != 1) or
1262         (that->mySMPMap[myEntry].count(')') != 1) or
1263         (that->mySMPMap[myEntry].count(';') != 4) or
1264         (that->mySMPMap[myEntry].size() == 15)){
1265       if (displayError)
1266         SUIT_MessageBox::warning( dlg(),"Definition of attractor : Error" ,"An attractor is defined with the following pattern: ATTRACTOR(xa;ya;za;a;b)" );
1267       return false;
1268     }
1269     return true;
1270   }
1271   else {
1272     // case size map is empty
1273     if (that->mySMPMap[myEntry].isEmpty()) {
1274       if (displayError)
1275         SUIT_MessageBox::warning( dlg(),"Definition of size map : Error" , "Size map can't be empty");
1276       return false;
1277     }
1278
1279     if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_FACE)
1280       expr = "def f(u,v) : return " + that->mySMPMap[myEntry].toStdString();
1281     else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_EDGE)
1282       expr = "def f(t) : return " + that->mySMPMap[myEntry].toStdString();
1283     else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_VERTEX)
1284       expr = "def f() : return " + that->mySMPMap[myEntry].toStdString();
1285   }
1286   //assert(Py_IsInitialized());
1287   if (not Py_IsInitialized())
1288     throw ("Erreur: Python interpreter is not initialized");
1289   PyGILState_STATE gstate;
1290   gstate = PyGILState_Ensure();
1291
1292   PyObject * obj = NULL;
1293   PyObject* new_stderr = NULL;
1294   string  err_description="";
1295   obj= PyRun_String(expr.c_str(), Py_file_input, main_dict, NULL);
1296   if (obj == NULL){
1297     fflush(stderr);
1298     err_description="";
1299     new_stderr=newPyStdOut(err_description);
1300     PySys_SetObject("stderr", new_stderr);
1301     PyErr_Print();
1302     PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
1303     Py_DECREF(new_stderr);
1304     if (displayError)
1305       SUIT_MessageBox::warning( dlg(),"Definition of Python Function : Error" ,err_description.c_str() );
1306     PyGILState_Release(gstate);
1307     return false;
1308   }
1309   Py_DECREF(obj);
1310
1311   PyObject * func = NULL;
1312   func = PyObject_GetAttrString(main_mod, "f");
1313   if ( func == NULL){
1314     fflush(stderr);
1315     err_description="";
1316     new_stderr=newPyStdOut(err_description);
1317     PySys_SetObject("stderr", new_stderr);
1318     PyErr_Print();
1319     PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
1320     Py_DECREF(new_stderr);
1321     if (displayError)
1322       SUIT_MessageBox::warning( dlg(),"Python Error" ,err_description.c_str() );
1323     PyGILState_Release(gstate);
1324     return false;
1325   }
1326
1327   PyGILState_Release(gstate);
1328
1329   MESSAGE("SizeMap expression "<<expr<<" is valid");
1330
1331   return true;
1332 }
1333
1334 /*
1335 void BLSURFPluginGUI_HypothesisCreator::OnEditMapFunction(QModelIndex* index) {
1336   int myRow = index->row();
1337   int myColumn = index->column();
1338
1339   if (myColumn == 2){
1340      if (!myEditor) {
1341          myEditor = new BLSURFPluginGUI_MapFunctionEditor(sizeMapModel->item(myRow,0)->text());
1342          connect(myEditor, SIGNAL(FunctionEntered(QString)), this, SLOT(FunctionLightValidation(QString)));
1343      }
1344      myEditor->exec();
1345 //      myEditor->show();
1346 //      myEditor->raise();
1347 //      myEditor->activateWindow();
1348
1349
1350 //     BLSURFPluginGUI_MapFunctionEditor* myEditor = new BLSURFPluginGUI_MapFunctionEditor(sizeMapModel->item(myRow,0)->text());
1351 //     myEditor->exec();
1352      QString myFunction = myEditor->GetFunctionText();
1353      // FIN RECUPERATION FONCTION
1354
1355      if (! myFunction.isEmpty()) {
1356
1357      // MAJ DE LA MAP
1358
1359      BLSURFPlugin::BLSURFPlugin_Hypothesis_var h =
1360        BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis());
1361
1362 //     h->SetSizeMapEntry(sizeMapModel->item(myRow,1)->text().toLatin1().constData(),
1363 //                        item->text().toLatin1().constData());
1364      h->SetSizeMapEntry(sizeMapModel->item(myRow,1)->text().toLatin1().constData(),
1365                         myFunction.toLatin1().constData());
1366      // FIN MAJ DE LA MAP
1367      }
1368   }
1369 }*/
1370
1371 QString BLSURFPluginGUI_HypothesisCreator::caption() const
1372 {
1373   return tr( "BLSURF_TITLE" );
1374 }
1375
1376 QPixmap BLSURFPluginGUI_HypothesisCreator::icon() const
1377 {
1378   return SUIT_Session::session()->resourceMgr()->loadPixmap( "BLSURFPlugin", tr( "ICON_DLG_BLSURF_PARAMETERS") );
1379 }
1380
1381 QString BLSURFPluginGUI_HypothesisCreator::type() const
1382 {
1383   return tr( "BLSURF_HYPOTHESIS" );
1384 }
1385
1386 QString BLSURFPluginGUI_HypothesisCreator::helpPage() const
1387 {
1388   return "blsurf_hypo_page.html";
1389 }
1390
1391 LightApp_SelectionMgr* BLSURFPluginGUI_HypothesisCreator::selectionMgr()
1392 {
1393
1394   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
1395   if( anApp )
1396     return dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
1397   else
1398     return 0;
1399 }
1400