1 /** @file gsGeometryDialog.cpp
2 
3     @brief This file Provides implemetation of G+Smo geometry dialog for Axel modeler.
4 
5     This file is part of the G+Smo library.
6 
7     This Source Code Form is subject to the terms of the Mozilla Public
8     License, v. 2.0. If a copy of the MPL was not distributed with this
9     file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11     Author(s): A. Mantzaflaris
12 */
13 
14 #include "gsGeometryDialog.h"
15 
16 #include "gsGeometryData.h"
17 #include "gsBasisData.h"
18 #include "gsGeometryCreator.h"
19 
20 #include "QDialogEditCP.h"
21 
22 #include <axlCore/axlAbstractData.h>
23 #include <axlCore/axlMenuFactory.h>
24 #include <axlGui/axlInspectorUtils.h>
25 #include <dtkCoreSupport/dtkAbstractData.h>
26 
27 #include <dtkGuiSupport/dtkColorButton.h>
28 #include <dtkGuiSupport/dtkSplitter.h>
29 
30 #include <QtGui>
31 
32 #include <gsIO/gsFileData.h>
33 
34 #define DEFAULT_SAMPLES 20
35 
36 // Process
37 #include <axlCore/axlAbstractFieldGenerator.h>
38 
39 
40 
41 //
42 #define CALL_DATA_METHOD(method) \
43 if ( gsAxelCurve * obj = dynamic_cast<gsAxelCurve *>(d->data) ) \
44         obj-> method ();  else \
45     if ( gsAxelSurface * obj = dynamic_cast<gsAxelSurface *>(d->data) ) \
46         obj-> method (); else \
47     if ( gsAxelVolume * obj = dynamic_cast<gsAxelVolume *>(d->data) ) \
48         obj-> method (); else \
49     if ( gsAxelTrimSurf * obj = dynamic_cast<gsAxelTrimSurf *>(d->data) ) \
50         obj-> method ();
51 #define CALL_DATA_METHOD1(method,arg1)  \
52 if ( gsAxelCurve * obj = dynamic_cast<gsAxelCurve *>(d->data) ) \
53         obj-> method (arg1);  else \
54     if ( gsAxelSurface * obj = dynamic_cast<gsAxelSurface *>(d->data) ) \
55         obj-> method (arg1); else \
56     if ( gsAxelVolume * obj = dynamic_cast<gsAxelVolume *>(d->data) ) \
57         obj-> method (arg1); else \
58     if ( gsAxelTrimSurf * obj = dynamic_cast<gsAxelTrimSurf *>(d->data) ) \
59         obj-> method (arg1);
60 //
61 
62 class gsGeometryDialogPrivate
63 {
64 public:
65     axlAbstractData *data;
66 
67     dtkColorButton *colorButton;
68 
69     QComboBox *comboBoxShader;
70     QCheckBox *checkBoxShader;
71     QLineEdit *lineEditShader;
72     QPushButton *buttonShader;
73     QSlider *sliderOpacity;
74 
75     QSpinBox *spinBoxSampling_u;
76     QSpinBox *spinBoxSampling_v;
77     QSpinBox *spinBoxSampling_w;
78 
79     // Control point box
80     QSpinBox       *cpIndex;
81     QPushButton    *cpEdit;
82 
83     QPushButton *basisButton;
84 
85     QPushButton *saveButton;
86 
87     QPushButton * refineButton;
88 
89     QPushButton * insertKnotButton;
90 
91     /* Joker
92     QPushButton * jokerButton;
93     //*/
94 
95     QTextEdit *info;
96 
97 };
98 
gsGeometryDialog(QWidget * parent)99 gsGeometryDialog::gsGeometryDialog(QWidget *parent) : axlInspectorObjectInterface(parent), d(new gsGeometryDialogPrivate)
100 {
101     d->data = NULL;
102 
103     d->comboBoxShader = NULL;
104     d->sliderOpacity = NULL;
105     d->checkBoxShader = NULL;
106     d->lineEditShader = NULL;
107     d->buttonShader = NULL;
108     d->colorButton = NULL;
109     d->info = NULL;
110 }
111 
initWidget(void)112 void gsGeometryDialog::initWidget(void) {
113 
114     //OPACITY//
115     d->sliderOpacity = new QSlider(Qt::Horizontal, this);
116 
117     QHBoxLayout *layoutOpacity = new QHBoxLayout;
118     layoutOpacity->addWidget(new QLabel("Opacity",this));
119     layoutOpacity->addWidget(d->sliderOpacity);
120     d->sliderOpacity->setMaximum(100);
121     d->sliderOpacity->setValue(initOpacityValue());
122 
123     //SHADER//
124     d->comboBoxShader = new QComboBox(this);
125     d->comboBoxShader->setInsertPolicy(QComboBox::InsertAlphabetically);
126     d->checkBoxShader = new QCheckBox(this);
127     d->lineEditShader = new QLineEdit(this);
128     d->buttonShader = new QPushButton(this);
129     d->buttonShader->setText("open");
130 
131     d->lineEditShader->setText(initShaderValue());
132     this->initComboBoxShaderValue();
133 
134     if(d->lineEditShader->text().isEmpty())
135     {
136         d->lineEditShader->setEnabled(false);
137         d->buttonShader->setEnabled(false);
138         d->comboBoxShader->setEnabled(false);
139     }
140     else
141         d->checkBoxShader->setChecked(true);
142 
143     //COLOR//
144     d->colorButton = new dtkColorButton(this);
145 
146     QHBoxLayout *layoutColorButton = new QHBoxLayout;
147     layoutColorButton->addWidget(new QLabel("Color",this));
148     layoutColorButton->addWidget(d->colorButton);
149     d->colorButton->setColor(this->initColorValue());
150 
151     //GUI//
152     QVBoxLayout *layoutShader = new QVBoxLayout;
153     QHBoxLayout *layoutShader1 = new QHBoxLayout;
154 
155     QLabel *labelShader  = new QLabel("Shader",this);
156     layoutShader1->addWidget(labelShader);
157     layoutShader1->addWidget(d->checkBoxShader);
158     layoutShader1->addWidget(d->comboBoxShader);
159     layoutShader1->addWidget(d->buttonShader);
160 
161     layoutShader1->setStretchFactor(labelShader, 2);
162     layoutShader1->setStretchFactor(d->checkBoxShader, 1);
163     layoutShader1->setStretchFactor(d->comboBoxShader, 4);
164     layoutShader1->setStretchFactor(d->buttonShader, 3);
165 
166     layoutShader->addLayout(layoutShader1);
167     layoutShader->addWidget(d->lineEditShader);
168     QVBoxLayout *layoutTop = new QVBoxLayout;
169     layoutTop->addWidget(new QLabel("Gismo Geometry Properties", this));
170     layoutTop->addLayout(layoutColorButton);
171     layoutTop->addLayout(layoutOpacity);
172     layoutTop->addLayout(layoutShader);
173 
174     // Sampling
175     QHBoxLayout *layoutSampling = new QHBoxLayout;
176     layoutSampling->addWidget(new QLabel("Sampling",this));
177     d->spinBoxSampling_u = new QSpinBox(this);
178     d->spinBoxSampling_u->setMaximum(5000);
179     d->spinBoxSampling_u->setMinimum(5);
180     d->spinBoxSampling_u->setValue(DEFAULT_SAMPLES);
181     layoutSampling->addWidget(d->spinBoxSampling_u);
182     connect(d->spinBoxSampling_u, SIGNAL(valueChanged(int)), this, SLOT(onSamplingDataChanged_u(int)));
183     int pdim = getGeometryPointer(d->data)->parDim();
184     if (  pdim > 1)
185 	{
186 	    d->spinBoxSampling_v = new QSpinBox(this);
187 	    d->spinBoxSampling_v->setMaximum(5000);
188 	    d->spinBoxSampling_v->setMinimum(5);
189 	    d->spinBoxSampling_v->setValue(DEFAULT_SAMPLES);
190 	    layoutSampling->addWidget(d->spinBoxSampling_v);
191 	    connect(d->spinBoxSampling_v, SIGNAL(valueChanged(int)), this, SLOT(onSamplingDataChanged_v(int)));
192 	    if ( pdim > 2)
193 		{
194 		    d->spinBoxSampling_w = new QSpinBox(this);
195 		    d->spinBoxSampling_w->setMaximum(5000);
196 		    d->spinBoxSampling_w->setMinimum(5);
197 		    d->spinBoxSampling_w->setValue(DEFAULT_SAMPLES);
198 		    layoutSampling->addWidget(d->spinBoxSampling_w);
199 		    connect(d->spinBoxSampling_w, SIGNAL(valueChanged(int)), this, SLOT(onSamplingDataChanged_w(int)));
200 		}
201 	}
202     layoutTop->addLayout(layoutSampling);
203 
204     // CONTROL POINT
205     //gismo::gsGeometry<> * g = getGeometryPointer(d->data);
206     d->cpIndex           = new QSpinBox(this);
207     //d->cpIndex->setButtonSymbols(QAbstractSpinBox::NoButtons);
208     d->cpIndex->setMinimum(0  );
209     d->cpIndex->setMaximum(1e6);
210     QHBoxLayout *layout_cpid = new QHBoxLayout;
211     layout_cpid->addWidget(new QLabel("Control point",this));
212     layout_cpid->addWidget(d->cpIndex);
213     layoutTop->addLayout(layout_cpid);
214     d->cpEdit = new QPushButton("Edit",this);
215     layoutTop->addWidget(d->cpEdit);
216     layout_cpid->addWidget(d->cpEdit);
217     connect(d->cpEdit, SIGNAL(clicked()), this, SLOT(onEditCP()) );
218 /*
219     d->coordinatePoint_x = new QDoubleSpinBox(this);
220     d->coordinatePoint_x->setRange(-1e6, 1e6);
221     d->coordinatePoint_x->setValue(g->coef(0,0));
222     d->coordinatePoint_x->setSingleStep(0.1);
223     d->coordinatePoint_y = new QDoubleSpinBox(this);
224     d->coordinatePoint_y->setRange(-1e6, 1e6);
225     d->coordinatePoint_y->setValue(g->coef(0,1));
226     d->coordinatePoint_y->setSingleStep(0.1);
227     d->coordinatePoint_z = new QDoubleSpinBox(this);
228     d->coordinatePoint_z->setRange(-1e6, 1e6);
229     d->coordinatePoint_z->setValue(g->coef(0,2));
230     d->coordinatePoint_z->setSingleStep(0.1);
231     QHBoxLayout *layout_coord = new QHBoxLayout;
232     layout_coord->addWidget(d->coordinatePoint_x);
233     //QHBoxLayout *layout_coord_y = new QHBoxLayout;
234     //layout_cpid->addWidget(new QLabel("y",this));
235     layout_cpid->addWidget(d->coordinatePoint_y);
236     layout_cpid->addWidget(d->coordinatePoint_z);
237     layoutTop->addLayout(layout_coord);
238 */
239     // when changing the value, grab the new index
240     //connect(d->cpIndex, SIGNAL(valueChanged(int)), this, SLOT(onControlPointIndexChanged(int)));
241 
242     // When selecting a control point inside the view, update the coordinate boxes
243     connect(d->data, SIGNAL(indexSelected(int)), this, SLOT(onIndexSelected(int)));
244 
245     //Basis button
246     d->basisButton = new QPushButton("Show basis",this);
247     layoutTop->addWidget(d->basisButton);
248     connect(d->basisButton, SIGNAL(clicked()), this, SLOT(showBasis()));
249 
250     //Save button
251     d->saveButton = new QPushButton("Save geometry",this);
252     layoutTop->addWidget(d->saveButton);
253     connect(d->saveButton, SIGNAL(clicked()), this, SLOT(saveGeometry()));
254 
255     //Refine button
256     d->refineButton = new QPushButton("Refine here",this);
257     layoutTop->addWidget(d->refineButton);
258     connect(d->refineButton, SIGNAL(clicked()), this, SLOT(refineGeometry()));
259 
260     // Insert knot button
261     d->insertKnotButton = new QPushButton("Insert knot",this);
262     layoutTop->addWidget(d->insertKnotButton);
263     connect(d->insertKnotButton, SIGNAL(clicked()), this, SLOT(insertKnot()));
264 
265     /* Joker
266     d->jokerButton = new QPushButton("Joker",this);
267     layoutTop->addWidget(d->jokerButton);
268     connect(d->jokerButton, SIGNAL(clicked()), this, SLOT(jokerPlay()));
269     //*/
270 
271     d->info = new QTextEdit("G+Smo");
272     d->info->setTextInteractionFlags(Qt::NoTextInteraction);
273     updateText();
274 
275     layoutTop->addWidget(d->info);
276     // QSize myEditSize = d->info->document()->size().toSize();
277     // myEditSize.setWidth(QWIDGETSIZE_MAX);
278     // d->info->setMaximumSize(myEditSize);
279 
280     layoutTop->addStretch(1);
281     QWidget *top = new QWidget(this);
282     top->setMaximumWidth(295);
283     top->setLayout(layoutTop);
284 
285     connect(d->comboBoxShader, SIGNAL(currentIndexChanged(QString)), this, SLOT(onLineEditShaderChanged(QString)));
286     connect(d->checkBoxShader, SIGNAL(clicked(bool)), this, SLOT(onShaderStateChanged(bool)));
287     connect(d->buttonShader, SIGNAL(clicked()), this, SLOT(openShader()));
288     connect(d->colorButton, SIGNAL(colorChanged(QColor)), this, SLOT(onColorChanged(QColor)));
289     connect(d->sliderOpacity, SIGNAL(sliderMoved(int)), this, SLOT(onOpacityChanged(int)));
290     connect(d->lineEditShader, SIGNAL(textChanged(QString)), this, SLOT(onShaderChanged(QString)));
291 
292 
293 
294     // G+Smo menu
295     QMenu * m = axlMenuFactory::instance()->menus().at(0);
296     QAction * a = m->actions().at(0);
297     a->setEnabled(true);
298     connect(a, SIGNAL(triggered()), this, SLOT(refineGeometry()));
299     // note: function ptr can go there instead of SLOT
300 }
301 
302 
~gsGeometryDialog(void)303 gsGeometryDialog::~gsGeometryDialog(void)
304 {
305     delete d;
306 
307     d = NULL;
308 
309     QAction * a = axlMenuFactory::instance()->menus().at(0)->actions().at(0);
310     a->setEnabled(false);
311 }
312 
registered(void)313 bool gsGeometryDialog::registered(void)
314 {
315     return
316         axlInspectorObjectFactory::instance()->registerInspectorObject("SplineCurve", creategsGeometryDialog)
317         &&
318         axlInspectorObjectFactory::instance()->registerInspectorObject("SplineSurface", creategsGeometryDialog)
319         &&
320         axlInspectorObjectFactory::instance()->registerInspectorObject("TrimSurface", creategsGeometryDialog)
321         &&
322         axlInspectorObjectFactory::instance()->registerInspectorObject("SplineVolume", creategsGeometryDialog);
323 }
324 
data(void)325 axlAbstractData * gsGeometryDialog::data(void)
326 {
327     return d->data;
328 }
329 
selectedCp()330 int gsGeometryDialog::selectedCp()
331 {
332     return d->cpIndex->value();
333 }
334 
335 
creategsGeometryDialog(void)336 axlInspectorObjectInterface *creategsGeometryDialog(void)
337 {
338     return new gsGeometryDialog;
339 }
340 
sizeHint(void) const341 QSize gsGeometryDialog::sizeHint(void) const
342 {
343     return QSize(600, 600);
344 }
345 
updateText()346 void gsGeometryDialog::updateText()
347 {
348     std::stringstream s;
349     s << * getGeometryPointer(d->data) ;
350     d->info->setText( s.str().c_str() );
351 }
352 
353 
setData(dtkAbstractData * data)354 void gsGeometryDialog::setData(dtkAbstractData *data)
355 {
356     if(
357           (d->data = dynamic_cast<gsAxelCurve   *>(data))
358        || (d->data = dynamic_cast<gsAxelSurface *>(data))
359        || (d->data = dynamic_cast<gsAxelVolume  *>(data))
360        || (d->data = dynamic_cast<gsAxelTrimSurf*>(data))
361        )
362     {
363         initWidget();
364     }
365 }
366 
onIndexSelected(int i)367 void gsGeometryDialog::onIndexSelected(int i)
368 {
369     //--i;// 1-based numbering? --> no.
370     d->cpIndex->setValue(i);
371 }
372 
onSamplingDataChanged_u(int numSamples)373 void gsGeometryDialog::onSamplingDataChanged_u(int numSamples)
374 {
375     //CALL_DATA_METHOD(
376     if ( gsAxelCurve * obj = dynamic_cast<gsAxelCurve *>(d->data) )
377             obj->setNumSamples_u(numSamples);
378     else
379     if ( gsAxelSurface * obj = dynamic_cast<gsAxelSurface *>(d->data) )
380             obj->setNumSamples_u(numSamples);
381     else
382     if ( gsAxelVolume * obj = dynamic_cast<gsAxelVolume *>(d->data) )
383             obj->setNumSamples_u(numSamples);
384     else
385     if ( gsAxelTrimSurf * obj = dynamic_cast<gsAxelTrimSurf *>(d->data) )
386             obj->setNumSamples_u(numSamples);
387     emit update();
388 }
389 
onSamplingDataChanged_v(int numSamples)390 void gsGeometryDialog::onSamplingDataChanged_v(int numSamples)
391 {
392     if ( gsAxelCurve * obj = dynamic_cast<gsAxelCurve *>(d->data) )
393         obj->setNumSamples_v(numSamples);
394     else
395         if ( gsAxelSurface * obj = dynamic_cast<gsAxelSurface *>(d->data) )
396             obj->setNumSamples_v(numSamples);
397         else
398             if ( gsAxelVolume * obj = dynamic_cast<gsAxelVolume *>(d->data) )
399                 obj->setNumSamples_v(numSamples);
400             else
401                 if ( gsAxelTrimSurf * obj = dynamic_cast<gsAxelTrimSurf *>(d->data) )
402                     obj->setNumSamples_v(numSamples);
403     emit update();
404 }
405 
onSamplingDataChanged_w(int numSamples)406 void gsGeometryDialog::onSamplingDataChanged_w(int numSamples)
407 {
408     if ( gsAxelCurve * obj = dynamic_cast<gsAxelCurve *>(d->data) )
409             obj->setNumSamples_w(numSamples);
410     else
411     if ( gsAxelSurface * obj = dynamic_cast<gsAxelSurface *>(d->data) )
412             obj->setNumSamples_w(numSamples);
413     else
414     if ( gsAxelVolume * obj = dynamic_cast<gsAxelVolume *>(d->data) )
415             obj->setNumSamples_w(numSamples);
416     else
417     if ( gsAxelTrimSurf * obj = dynamic_cast<gsAxelTrimSurf *>(d->data) )
418             obj->setNumSamples_w(numSamples);
419     emit update();
420 }
421 
422 
onColorChanged(QColor color)423 void gsGeometryDialog::onColorChanged(QColor color)
424 {
425     d->data->setColor(color);
426 
427     emit dataChangedByColor(d->data, color.redF(), color.greenF(), color.blueF());
428 
429     emit update();
430 }
431 
initComboBoxShaderValue(void)432 void gsGeometryDialog::initComboBoxShaderValue(void)
433 {
434     if(d->comboBoxShader)
435     {
436         // First add item of axlShader.qrc, then find shader from shader path
437         QDir dirShader( ":axlShader/shader/");
438         dirShader.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
439 
440         QFileInfoList list = dirShader.entryInfoList();
441         //        for (int i = 0; i < list.size(); ++i) {
442         //            d->comboBoxShader->addItem(list.at(i).fileName());
443         //        }
444 
445         QSettings settings("inria", "dtk");
446         QString defaultPath;
447         settings.beginGroup("shader");
448         QString defaultPathShader = settings.value("path", defaultPath).toString();
449         defaultPathShader.append("/");
450 
451         QDir defaultDirShader(defaultPathShader);
452         QStringList filters;
453         filters << "*.xml";
454         defaultDirShader.setNameFilters(filters);
455         QFileInfoList list2 = defaultDirShader.entryInfoList();
456 
457         list.append(list2);
458 
459         QStringList items;
460 
461         for (int i = 0; i < list.size(); ++i) {
462             if(!items.contains(list.at(i).fileName()))
463                 items << list.at(i).fileName();
464         }
465 
466         qSort(items.begin(), items.end(), caseInsensitiveLessThan);
467         int indInitShader = -1;
468         int indCurrentShader = -1;
469 
470 
471         foreach(QString item, items)
472         {
473             indCurrentShader++;
474             d->comboBoxShader->addItem(item);
475 
476             QFileInfo currentFileInfo(d->lineEditShader->text());
477 
478             if(currentFileInfo.exists())
479             {
480                 if(item == currentFileInfo.fileName())
481                     indInitShader =indCurrentShader;
482             }
483         }
484 
485         //init the value from the lineEditShader.
486         if(indInitShader != -1)
487             d->comboBoxShader->setCurrentIndex(indInitShader);
488 
489     }
490 }
491 
onLineEditShaderChanged(QString shader)492 void gsGeometryDialog::onLineEditShaderChanged(QString shader)
493 {
494     // First add item of axlShader.qrc, then find shader from shader path
495     QDir dirShader( ":axlShader/shader/");
496     dirShader.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
497 
498     QFileInfo currentFile(dirShader, shader);
499     if(!currentFile.exists())
500     {
501         QSettings settings("inria", "dtk");
502         QString defaultPath;
503         settings.beginGroup("shader");
504         QString defaultPathShader = settings.value("path", defaultPath).toString();
505         defaultPathShader.append("/");
506 
507         QDir defaultDirShader(defaultPathShader);
508         currentFile = QFileInfo(defaultDirShader, shader);
509 
510     }
511 
512     d->lineEditShader->setText(currentFile.absoluteFilePath());
513 }
514 
openShader()515 void gsGeometryDialog::openShader()
516 {
517     if(d->lineEditShader->isEnabled())
518     {
519         QString fileToOpen;
520         fileToOpen = QFileDialog::getOpenFileName(this, tr("Open shader"), "", tr("xml document (*.xml)"));
521         d->lineEditShader->setText(fileToOpen);
522     }
523 }
524 
onShaderChanged(QString shader)525 void gsGeometryDialog::onShaderChanged(QString shader)
526 {
527     d->data->setShader(shader);
528 
529     //emit dataChangedByShader(d->data, d->lineEditShader->text());
530     emit modifiedProperty(d->data, 2);
531 
532     emit update();
533 }
534 
onShaderStateChanged(bool isShader)535 void gsGeometryDialog::onShaderStateChanged(bool isShader)
536 {
537     if(isShader)
538     {
539         d->comboBoxShader->setEnabled(true);
540         d->lineEditShader->setEnabled(true);
541         d->buttonShader->setEnabled(true);
542         emit dataChangedByShader(d->data, d->lineEditShader->text());
543     }
544     else
545     {
546         d->comboBoxShader->setEnabled(false);
547         d->lineEditShader->setEnabled(false);
548         d->buttonShader->setEnabled(false);
549         emit dataChangedByShader(d->data, "");
550     }
551     emit update();
552 }
553 
onOpacityChanged(int opacity)554 void gsGeometryDialog::onOpacityChanged(int opacity)
555 {
556     double opacity_d = 1.0 - 0.01 * opacity; // range from 0.00 to 1.00
557     d->data->setOpacity(opacity_d);
558 
559     //emit dataChangedByOpacity(d->data, opacity_d);
560     emit modifiedProperty(d->data, 1);
561     emit update();
562 }
563 
initOpacityValue(void)564 int gsGeometryDialog::initOpacityValue(void)
565 {
566     double initOpacity = 0.0;
567     double opacity = d->data->opacity();
568     if(opacity > initOpacity)
569         initOpacity = opacity;
570 
571     return 100 * (1.0 - initOpacity);
572 }
573 
initShaderValue(void)574 QString gsGeometryDialog::initShaderValue(void)
575 {
576     return  d->data->shader();
577 }
578 
579 
initColorValue(void)580 QColor gsGeometryDialog::initColorValue(void)
581 {
582     return d->data->color();
583 }
584 
585 
showBasis(void)586 void gsGeometryDialog::showBasis(void)
587 {
588     gsBasisPointer myGismoData =
589 	    getGeometryPointer(d->data)->basis().clone().release();
590 	std::cout << "Plotting basis "<< * myGismoData <<"\n";
591 
592 	// Create basis object and add it in the object list
593     gsBasisData * myData = new gsBasisData(myGismoData);
594     // myData->setColor(QColor("#0080ff"));
595     // double opacity = 1.0 - 0.01 * d->sliderOpacity->value();
596     // myData->setOpacity(opacity);
597 
598 	emit dataInserted(myData);
599 }
600 
saveGeometry(void)601 void gsGeometryDialog::saveGeometry(void)
602 {
603     QString fileName = QFileDialog::getSaveFileName(this, tr("Save File to Gismo XML format"),"~/",tr("Gismo files (*.xml);;"));
604 
605     if ( fileName.size() )
606     {
607         gsGeometryPointer myGismoData = getGeometryPointer(d->data);
608 	if ( myGismoData )
609 	    {
610 		std::cout << "Saving to "<< fileName.toUtf8().constData() <<"\n";
611                 gismo::gsFileData<double> out;
612                 out<< *myGismoData ;
613                 out.dump(fileName.toUtf8().constData());
614             }
615     }
616 }
617 
insertKnot(void)618 void gsGeometryDialog::insertKnot(void)
619 {
620     gsGeometryPointer myGismoData = getGeometryPointer(d->data);
621     gsAxelSurface * surf = dynamic_cast<gsAxelSurface *>(d->data);
622 
623     if ( ! surf )
624     {
625         gsWarn<<"Not a surface.\n";
626         return;
627     }
628 
629     // Get index of the selected control point
630     const int parameter = surf->getParameter();
631 
632     // knot coordinates
633     real_t u, v;
634 
635     if ( gismo::gsTHBSpline<2> * hb = dynamic_cast<gismo::gsTHBSpline<2>*>(myGismoData.get()) )
636     {
637       // get level of basis function
638       const int lvl = hb->basis().levelOf(parameter);
639 
640       gsDebugVar(lvl);
641 
642       const gismo::gsTensorBSplineBasis<2,real_t> &
643       tb = hb->basis().tensorLevel(lvl);
644 
645       const unsigned ind = hb->basis().flatTensorIndexOf(parameter);
646       const gismo::gsVector<unsigned,2> tind = tb.tensorIndex(ind);
647 
648       const int degu = tb.degree(0);
649       const int degv = tb.degree(1);
650 
651       const unsigned us = tind[0] + (degu + 1) / 2  ;
652       const unsigned vs = tind[1] + (degv + 1) / 2  ;
653 
654       gsDebugVar(us);
655       gsDebugVar(vs);
656 
657       u = tb.knot(0,us);
658       v = tb.knot(1,vs);
659 
660       gsDebugVar(u);
661       gsDebugVar(v);
662 
663       // Inserting knots u and v ..
664       //hb->increaseMultiplicity( lvl,0,u,1);// knot, direction, incrAmount
665 
666       hb->basis().increaseMultiplicity(1,0,0.5,1);
667 
668 
669       gsDebugVar( tb.knots(0).detail() );
670 
671     }
672 }
673 
674 
675 /* Joker
676 void gsGeometryDialog::jokerPlay(void)
677 {
678     gsGeometryPointer myGismoData = getGeometryPointer(d->data);
679 	if ( myGismoData )
680     {
681         gsInfo<<"Joker!\n";
682 
683         emit update();
684     }
685 }
686 //*/
687 
onEditCP(void)688 void gsGeometryDialog::onEditCP(void)
689 {
690     QDialogEditCP cpEdit(this);
691 
692     const int ret = cpEdit.exec();
693     if ( ret == QDialog::Accepted)
694     {
695         gismo::gsGeometry<> * g = getGeometryPointer(d->data).get();
696         const int cp  = d->cpIndex->value();
697         const int gdim = g->geoDim();
698         g->coef(cp,0) = cpEdit.xCoord();
699         if ( gdim > 1)
700         {
701             g->coef(cp,1) = cpEdit.yCoord();
702                 if ( gdim > 2)
703                     g->coef(cp,2) = cpEdit.zCoord();
704         }
705 
706         d->data->touchStructure();// should be just onControlPointChange
707         d->data->touchGeometry();
708 
709         emit update();
710 
711         //CALL_DATA_METHOD( samplingChanged );
712     }
713 }
714 
refineGeometry(void)715 void gsGeometryDialog::refineGeometry(void)
716 {
717     gsGeometryPointer myGismoData = getGeometryPointer(d->data);
718     gsAxelSurface * surf = dynamic_cast<gsAxelSurface *>(d->data);
719 
720     if ( ! surf )
721     {
722         gsWarn<<"Not a surface.\n";
723         return;
724     }
725 
726     // Get index of the selected control point
727     const int parameter = surf->getParameter(); // to do: replace by signal
728 
729     if ( gismo::gsTHBSpline<2> * hb = dynamic_cast<gismo::gsTHBSpline<2>*>(myGismoData.get()) )
730     {
731          gismo::gsMatrix<unsigned, 2, 2> elements;
732          hb->basis().elementSupport_into(parameter, elements);
733          gsInfo<<"element support: \n"<<  elements <<"\n";
734 
735          std::vector<unsigned> box;
736          const int lvl = hb->basis().levelOf(parameter) + 1;// increase level by 1
737          gsInfo<<"level: \n"<< lvl-1  <<"\n";
738          box.push_back(lvl);
739          box.insert(box.end(), elements.data(), elements.data()+4 );
740          box[1]= elements(0,0) << 1; // Take indices to the next level
741          box[2]= elements(1,0) << 1;
742          box[3]= elements(0,1) << 1;
743          box[4]= elements(1,1) << 1;
744 
745          gsInfo<<"Refining control point "<<parameter<<".\n";
746          gsInfo<<"with support: "<<  box[1]<<", "<<box[2]<<", "<<box[3]<<", "<<box[4] <<"\n";
747 
748          hb->basis().refineElements_withCoefs(hb->coefs(), box);
749 
750          updateText();
751 
752          surf->updateControlGrid();
753 
754          emit update();
755     }
756     else
757     {
758         gsWarn<<"We cannot refine nothing else than a hier. spline yet.\n";
759     }
760 
761 
762     // m_process: member of the gsGeometryData
763     //axlFieldSpatialCoordinatesCreator * m_process = new axlFieldSpatialCoordinatesCreator();
764     // somewhere to delete it
765 
766     //process->setInput(d->data, 0); //+ PDE solution
767     //process->update();
768 
769     // not needed, in general we add it to the
770     //emit dataInserted(process->output);
771 }
772