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