1 #include <QApplication>
2 #include <QMainWindow>
3 #include <QAction>
4 #include <QVector>
5 #include <QMessageBox>
6 #include <QBitmap>
7 #include <QTabBar>
8
9 #include <CGAL/boost/graph/helpers.h>
10 #include <CGAL/boost/graph/Euler_operations.h>
11
12 #include <CGAL/subdivision_method_3.h>
13 #include <CGAL/Kernel_traits.h>
14
15 #include <CGAL/Polygon_mesh_processing/triangulate_hole.h>
16 #include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
17
18 #include <CGAL/Three/Scene_item.h>
19 #include <CGAL/Three/Viewer_interface.h>
20 #include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
21 #include <CGAL/Three/Three.h>
22
23 #include "Scene_surface_mesh_item.h"
24 #include "Scene_points_with_normal_item.h"
25 #include "Scene_polylines_item.h"
26
27 #include "ui_Basic_generator_widget.h"
28
29 struct Face : public std::array<int,3>
30 {
FaceFace31 Face(int i, int j, int k)
32 {
33 (*this)[0] = i;
34 (*this)[1] = j;
35 (*this)[2] = k;
36 }
37 };
38
39 class GeneratorWidget :
40 public QDockWidget,
41 public Ui::BasicGenerator
42 {
43 Q_OBJECT
44 public:
GeneratorWidget(QString name,QWidget * parent)45 GeneratorWidget(QString name, QWidget *parent)
46 :QDockWidget(name,parent)
47 {
48 setupUi(this);
49 }
50 };
51
52 typedef Kernel::Point_3 Point;
53
54 namespace euler = CGAL::Euler;
55 using namespace CGAL::Three;
56 namespace params = CGAL::parameters;
57
58 class Q_DECL_EXPORT Basic_generator_plugin :
59 public QObject,
60 public Polyhedron_demo_plugin_helper
61 {
62 Q_OBJECT
63 Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
64 Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "basic_generator_plugin.json")
65 public :
init(QMainWindow * mainWindow,CGAL::Three::Scene_interface * scene_interface,Messages_interface *)66 void init(QMainWindow* mainWindow,
67 CGAL::Three::Scene_interface* scene_interface,
68 Messages_interface*)
69 {
70 this->scene = scene_interface;
71 this->mw = mainWindow;
72 for(int i=0; i<=POLYLINE; ++i)
73 nbs[i]=0;
74
75
76 QMenu* menuFile = mw->findChild<QMenu*>("menuFile");
77
78 QMenu* menu = menuFile->findChild<QMenu*>("menuGenerateObject");
79 if(!menu){
80 QAction* actionLoad = mw->findChild<QAction*>("actionLoadPlugin");
81 menu = new QMenu(tr("Generate &Object"), menuFile);
82 menu->setObjectName("menuGenerateObject");
83 menuFile->insertMenu(actionLoad, menu);
84 }
85
86
87 QAction* actionPrism = new QAction("P&rism", mw);
88 QAction* actionSphere = new QAction("&Sphere", mw);
89 QAction* actionPyramid = new QAction("Py&ramid", mw);
90 QAction* actionHexahedron = new QAction("&Hexahedron", mw);
91 QAction* actionTetrahedron = new QAction("&Tetrahedron", mw);
92 QAction* actionGrid = new QAction("&Grid", mw);
93 QAction* actionPointSet = new QAction("Po&int Set", mw);
94 QAction* actionPolyline = new QAction("Po&lyline", mw);
95
96
97
98
99 connect(actionPrism, SIGNAL(triggered()),
100 this, SLOT(on_actionPrism_triggered()));
101 _actions << actionPrism;
102
103 connect(actionSphere, SIGNAL(triggered()),
104 this, SLOT(on_actionSphere_triggered()));
105 _actions << actionSphere;
106
107 connect(actionPyramid, SIGNAL(triggered()),
108 this, SLOT(on_actionPyramid_triggered()));
109 _actions << actionPyramid;
110
111 connect(actionHexahedron, SIGNAL(triggered()),
112 this, SLOT(on_actionHexahedron_triggered()));
113 _actions << actionHexahedron;
114
115 connect(actionTetrahedron, SIGNAL(triggered()),
116 this, SLOT(on_actionTetrahedron_triggered()));
117 _actions << actionTetrahedron;
118
119 connect(actionGrid, SIGNAL(triggered()),
120 this, SLOT(on_actionGrid_triggered()));
121 _actions << actionGrid;
122
123 connect(actionPointSet, SIGNAL(triggered()),
124 this, SLOT(on_actionPointSet_triggered()));
125 _actions << actionPointSet;
126
127 connect(actionPolyline, SIGNAL(triggered()),
128 this, SLOT(on_actionPolyline_triggered()));
129 _actions << actionPolyline;
130
131 Q_FOREACH(QAction* action, _actions)
132 {
133 menu->addAction(action);
134 }
135 dock_widget = new GeneratorWidget("Basic Objects", mw);
136 dock_widget->setVisible(false); // do not show at the beginning
137 addDockWidget(dock_widget);
138 connect(dock_widget->generateButton, &QAbstractButton::clicked,
139 this, &Basic_generator_plugin::on_generate_clicked);
140 connect(dock_widget->selector_tabWidget, &QTabWidget::currentChanged,
141 this, &Basic_generator_plugin::on_tab_changed);
142 connect(dock_widget, &GeneratorWidget::visibilityChanged,
143 this, &Basic_generator_plugin::on_tab_changed);
144 connect(dock_widget->prismCheckBox, &QCheckBox::stateChanged,
145 this, &Basic_generator_plugin::on_tab_changed);
146 connect(dock_widget->pyramidCheckBox, &QCheckBox::stateChanged,
147 this, &Basic_generator_plugin::on_tab_changed);
148 }
149
applicable(QAction *) const150 bool applicable(QAction*) const
151 {
152 //not in the Operations menu
153 return false;
154 }
actions() const155 QList<QAction*> actions() const {
156 return QList<QAction*>();
157 }
158 public Q_SLOTS:
159
160 void on_actionPrism_triggered();
161 void on_actionSphere_triggered();
162 void on_actionPyramid_triggered();
163 void on_actionHexahedron_triggered();
164 void on_actionTetrahedron_triggered();
165 void on_actionGrid_triggered();
166 void on_actionPointSet_triggered();
167 void on_actionPolyline_triggered();
168 void on_generate_clicked();
169 void on_tab_changed();
closure()170 void closure(){ dock_widget->hide(); }
171 private:
172 QList<QAction*> _actions;
173 GeneratorWidget* dock_widget;
174 enum VolumeTab
175 {
176 PRISM=0,
177 SPHERE,
178 PYRAMID,
179 HEXAHEDRON,
180 TETRAHEDRON,
181 GRID,
182 POINT_SET,
183 POLYLINE
184 };
185
186 int nbs[POLYLINE+1];
187 template<class Facegraph_item>
188 void generateCube();
189 template<class Facegraph_item>
190 void generatePrism();
191 template<class Facegraph_item>
192 void generatePyramid();
193 template<class Facegraph_item>
194 void generateSphere();
195 template<class Facegraph_item>
196 void generateTetrahedron();
197 void generatePoints();
198 void generateLines();
199 template<class Facegraph_item>
200 void generateGrid();
201 }; //end of class Basic_generator_plugin
202
203 //show the widget
on_actionPrism_triggered()204 void Basic_generator_plugin::on_actionPrism_triggered()
205 {
206 dock_widget->show(); dock_widget->raise();
207 dock_widget->selector_tabWidget->tabBar()->setCurrentIndex(PRISM);
208 }
on_actionSphere_triggered()209 void Basic_generator_plugin::on_actionSphere_triggered()
210 {
211 dock_widget->show(); dock_widget->raise();
212 dock_widget->selector_tabWidget->tabBar()->setCurrentIndex(SPHERE);
213 }
on_actionPyramid_triggered()214 void Basic_generator_plugin::on_actionPyramid_triggered()
215 {
216 dock_widget->show(); dock_widget->raise();
217 dock_widget->selector_tabWidget->tabBar()->setCurrentIndex(PYRAMID);
218 }
on_actionHexahedron_triggered()219 void Basic_generator_plugin::on_actionHexahedron_triggered()
220 {
221 dock_widget->show(); dock_widget->raise();
222 dock_widget->selector_tabWidget->tabBar()->setCurrentIndex(HEXAHEDRON);
223 }
on_actionTetrahedron_triggered()224 void Basic_generator_plugin::on_actionTetrahedron_triggered()
225 {
226 dock_widget->show(); dock_widget->raise();
227 dock_widget->selector_tabWidget->tabBar()->setCurrentIndex(TETRAHEDRON);
228 }
on_actionGrid_triggered()229 void Basic_generator_plugin::on_actionGrid_triggered()
230 {
231 dock_widget->show(); dock_widget->raise();
232 dock_widget->selector_tabWidget->tabBar()->setCurrentIndex(GRID);
233 }
on_actionPointSet_triggered()234 void Basic_generator_plugin::on_actionPointSet_triggered()
235 {
236 dock_widget->show(); dock_widget->raise();
237 dock_widget->selector_tabWidget->tabBar()->setCurrentIndex(POINT_SET);
238 }
on_actionPolyline_triggered()239 void Basic_generator_plugin::on_actionPolyline_triggered()
240 {
241 dock_widget->show(); dock_widget->raise();
242 dock_widget->selector_tabWidget->tabBar()->setCurrentIndex(POLYLINE);
243 }
on_tab_changed()244 void Basic_generator_plugin::on_tab_changed()
245 {
246 QString name;
247 int nb = 0;
248 switch(dock_widget->selector_tabWidget->currentIndex())
249 {
250 case PRISM:
251 {
252 name = QString("Prism");
253 nb = nbs[PRISM];
254 QPixmap pic;
255 if(dock_widget->prismCheckBox->isChecked())
256 pic = QPixmap(":/cgal/Polyhedron_3/resources/prism.png");
257 else
258 pic = QPixmap(":/cgal/Polyhedron_3/resources/prism-open.png");
259 dock_widget->prism_picLabel->setPixmap(pic);
260 dock_widget->prism_picLabel->show();
261 }
262 break;
263 case SPHERE:
264 name = QString("Sphere");
265 nb = nbs[SPHERE];
266 break;
267
268 case PYRAMID:
269 {
270 name = QString("Pyramid");
271 nb = nbs[PYRAMID];
272 QPixmap pic;
273 if(dock_widget->pyramidCheckBox->isChecked())
274 pic = QPixmap(":/cgal/Polyhedron_3/resources/pyramid.png");
275 else
276 pic = QPixmap(":/cgal/Polyhedron_3/resources/pyramid-open.png");
277 dock_widget->pyramid_picLabel->setPixmap(pic);
278 dock_widget->pyramid_picLabel->show();
279 }
280 break;
281
282 case HEXAHEDRON:
283 name = QString("Hexahedron");
284 nb = nbs[HEXAHEDRON];
285 break;
286
287 case TETRAHEDRON:
288 name = QString("Tetrahedron");
289 nb = nbs[TETRAHEDRON];
290 break;
291 case GRID:
292 name = QString("Grid");
293 nb = nbs[GRID];
294 break;
295 case POINT_SET:
296 name = QString("Point_set");
297 nb = nbs[POINT_SET];
298 break;
299
300 case POLYLINE:
301 name = QString("Polyline");
302 nb = nbs[POLYLINE];
303 break;
304 default:
305 break;
306 };
307 dock_widget->name_lineEdit->setText((nb==0)?name:QString(name).append(QString("%1").arg(nb)));
308 }
309 //generate
on_generate_clicked()310 void Basic_generator_plugin::on_generate_clicked()
311 {
312 switch(dock_widget->selector_tabWidget->currentIndex())
313 {
314 case PRISM:
315 generatePrism<Scene_surface_mesh_item>();
316 ++nbs[PRISM];
317 break;
318
319 case SPHERE:
320 generateSphere<Scene_surface_mesh_item>();
321 ++nbs[SPHERE];
322 break;
323
324 case PYRAMID:
325 generatePyramid<Scene_surface_mesh_item>();
326 ++nbs[PYRAMID];
327 break;
328
329 case HEXAHEDRON:
330 generateCube<Scene_surface_mesh_item>();
331 ++nbs[HEXAHEDRON];
332 break;
333
334 case TETRAHEDRON:
335 generateTetrahedron<Scene_surface_mesh_item>();
336 ++nbs[TETRAHEDRON];
337 break;
338 case GRID:
339 generateGrid<Scene_surface_mesh_item>();
340 ++nbs[GRID];
341 break;
342 case POINT_SET:
343 generatePoints();
344 ++nbs[POINT_SET];
345 break;
346
347 case POLYLINE:
348 generateLines();
349 ++nbs[POLYLINE];
350 break;
351 default:
352 break;
353 };
354 on_tab_changed();
355 }
356 //make a non triangle hexahedron
357 template<class Facegraph_item>
generateCube()358 void Basic_generator_plugin::generateCube()
359 {
360 typename Facegraph_item::Face_graph cube;
361 if(dock_widget->tabWidget_2->currentIndex() == 0)
362 {
363 QString point_texts[8];
364 Point points[8];
365 point_texts[0] = dock_widget->cubeP0->text(); point_texts[4] = dock_widget->cubeP4->text();
366 point_texts[1] = dock_widget->cubeP1->text(); point_texts[5] = dock_widget->cubeP5->text();
367 point_texts[2] = dock_widget->cubeP2->text(); point_texts[6] = dock_widget->cubeP6->text();
368 point_texts[3] = dock_widget->cubeP3->text(); point_texts[7] = dock_widget->cubeP7->text();
369
370 for(int i=0; i<8; ++i)
371 {
372 QStringList list = point_texts[i].split(QRegExp("\\s+"), CGAL_QT_SKIP_EMPTY_PARTS);
373 if (list.isEmpty()) return;
374 if (list.size()!=3){
375 QMessageBox *msgBox = new QMessageBox;
376 msgBox->setWindowTitle("Error");
377 msgBox->setText("ERROR : Input should consists of 3 doubles.");
378 msgBox->exec();
379 return;
380 }
381 double coords[3];
382 for(int j=0; j<3; ++j)
383 {
384 bool ok;
385 coords[j] = list.at(j).toDouble(&ok);
386 if(!ok)
387 {
388 QMessageBox *msgBox = new QMessageBox;
389 msgBox->setWindowTitle("Error");
390 msgBox->setText("ERROR : Coordinates are invalid.");
391 msgBox->exec();
392 return;
393 }
394 }
395 points[i] = Point(coords[0], coords[1], coords[2]);
396 }
397
398 CGAL::make_hexahedron(
399 points[0],
400 points[1],
401 points[2],
402 points[3],
403
404 points[4],
405 points[5],
406 points[6],
407 points[7],
408 cube);
409 }
410 else
411 {
412 QString text = dock_widget->extremaEdit->text();
413 QStringList list = text.split(QRegExp("\\s+"), CGAL_QT_SKIP_EMPTY_PARTS);
414 if (list.isEmpty()) return;
415 if (list.size()!=6){
416 QMessageBox *msgBox = new QMessageBox;
417 msgBox->setWindowTitle("Error");
418 msgBox->setText("ERROR : Input should consists of 6 doubles.");
419 msgBox->exec();
420 return;
421 }
422
423 for(int i=0; i<6; ++i)
424 {
425 bool ok;
426 list.at(i).toDouble(&ok);
427 if(!ok)
428 {
429 QMessageBox *msgBox = new QMessageBox;
430 msgBox->setWindowTitle("Error");
431 msgBox->setText("ERROR : Coordinates are invalid.");
432 msgBox->exec();
433 return;
434 }
435 }
436 CGAL::make_hexahedron(
437 Point(list.at(0).toDouble(),list.at(1).toDouble(),list.at(5).toDouble()),
438 Point(list.at(3).toDouble(),list.at(1).toDouble(),list.at(5).toDouble()),
439 Point(list.at(3).toDouble(),list.at(1).toDouble(),list.at(2).toDouble()),
440 Point(list.at(0).toDouble(),list.at(1).toDouble(),list.at(2).toDouble()),
441
442 Point(list.at(0).toDouble(),list.at(4).toDouble(),list.at(2).toDouble()),
443 Point(list.at(0).toDouble(),list.at(4).toDouble(),list.at(5).toDouble()),
444 Point(list.at(3).toDouble(),list.at(4).toDouble(),list.at(5).toDouble()),
445 Point(list.at(3).toDouble(),list.at(4).toDouble(),list.at(2).toDouble()),
446 cube);
447 }
448 Facegraph_item* cube_item = new Facegraph_item(cube);
449 cube_item->setName(dock_widget->name_lineEdit->text());
450 Scene_interface::Item_id id = scene->addItem(cube_item);
451 scene->setSelectedItem(id);
452 }
453 //make a prism
454 template<class Facegraph_item>
generatePrism()455 void Basic_generator_plugin::generatePrism()
456 {
457 //gets the precision parameter
458 int nb_vertices = dock_widget->prismSpinBox->value();
459 double height(dock_widget->prismHeightSpinBox->value()),
460 radius(dock_widget->prismBaseSpinBox->value());
461 bool is_closed = dock_widget->prismCheckBox->isChecked();
462
463 QString text = dock_widget->prism_lineEdit->text();
464 QStringList list = text.split(QRegExp("\\s+"), CGAL_QT_SKIP_EMPTY_PARTS);
465 if (list.isEmpty()) return;
466 if (list.size()!=3){
467 QMessageBox *msgBox = new QMessageBox;
468 msgBox->setWindowTitle("Error");
469 msgBox->setText("ERROR : Input should consists of 3 doubles.");
470 msgBox->exec();
471 return;
472 }
473 double coords[3];
474 for(int i=0; i<3; ++i)
475 {
476 bool ok;
477 coords[i] = list.at(i).toDouble(&ok);
478 if(!ok)
479 {
480 QMessageBox *msgBox = new QMessageBox;
481 msgBox->setWindowTitle("Error");
482 msgBox->setText("ERROR : Coordinates are invalid.");
483 msgBox->exec();
484 return;
485 }
486 }
487
488 typename Facegraph_item::Face_graph prism;
489 make_regular_prism(nb_vertices,
490 prism,
491 Point(coords[0], coords[1], coords[2]),
492 height,
493 radius,
494 is_closed);
495
496 Facegraph_item* prism_item = new Facegraph_item(prism);
497 prism_item->setName(dock_widget->name_lineEdit->text());
498 Scene_interface::Item_id id = scene->addItem(prism_item);
499 scene->setSelectedItem(id);
500 }
501 //make a pyramid
502 template<class Facegraph_item>
generatePyramid()503 void Basic_generator_plugin::generatePyramid()
504 {
505 int nb_vertices = dock_widget->pyramidSpinBox->value();
506 double height(dock_widget->pyramidHeightSpinBox->value()),
507 radius(dock_widget->pyramidBaseSpinBox->value());
508 bool is_closed = dock_widget->pyramidCheckBox->isChecked();
509
510 QString text = dock_widget->pyramid_lineEdit->text();
511 QStringList list = text.split(QRegExp("\\s+"), CGAL_QT_SKIP_EMPTY_PARTS);
512 if (list.isEmpty()) return;
513 if (list.size()!=3){
514 QMessageBox *msgBox = new QMessageBox;
515 msgBox->setWindowTitle("Error");
516 msgBox->setText("ERROR : Input should consists of 3 doubles.");
517 msgBox->exec();
518 return;
519 }
520 double coords[3];
521 for(int i=0; i<3; ++i)
522 {
523 bool ok;
524 coords[i] = list.at(i).toDouble(&ok);
525 if(!ok)
526 {
527 QMessageBox *msgBox = new QMessageBox;
528 msgBox->setWindowTitle("Error");
529 msgBox->setText("ERROR : Coordinates are invalid.");
530 msgBox->exec();
531 return;
532 }
533 }
534
535 typename Facegraph_item::Face_graph pyramid;
536 make_pyramid(nb_vertices,
537 pyramid,
538 Point(coords[0], coords[1], coords[2]),
539 height,
540 radius,
541 is_closed);
542
543 Facegraph_item* pyramid_item = new Facegraph_item(pyramid);
544 pyramid_item->setName(dock_widget->name_lineEdit->text());
545 Scene_interface::Item_id id = scene->addItem(pyramid_item);
546 scene->setSelectedItem(id);
547 }
548 //make a sphere
549 template<class Facegraph_item>
generateSphere()550 void Basic_generator_plugin::generateSphere()
551 {
552 int precision = dock_widget->SphereSpinBox->value();
553 QString text = dock_widget->center_radius_lineEdit->text();
554 QStringList list = text.split(QRegExp("\\s+"), CGAL_QT_SKIP_EMPTY_PARTS);
555 if (list.isEmpty()) return;
556 if (list.size()!=4){
557 QMessageBox *msgBox = new QMessageBox;
558 msgBox->setWindowTitle("Error");
559 msgBox->setText("ERROR : Input should consists of four doubles.");
560 msgBox->exec();
561 return;
562 }
563
564 double radius = list.at(3).toDouble();
565 Point center = Point(list.at(0).toDouble(), list.at(1).toDouble(), list.at(2).toDouble());
566 typename Facegraph_item::Face_graph sphere;
567 make_icosahedron(sphere, center, radius);
568 typedef typename boost::property_map<typename Facegraph_item::Face_graph, CGAL::vertex_point_t>::type VPMap;
569 if(precision !=0)
570 CGAL::Subdivision_method_3::Sqrt3_subdivision(sphere,
571 params::number_of_iterations(precision));
572 VPMap vpmap = get(CGAL::vertex_point, sphere);
573 //emplace the points back on the sphere
574 for(typename boost::graph_traits<typename Facegraph_item::Face_graph>::vertex_descriptor vd : vertices(sphere))
575 {
576 Kernel::Vector_3 vec(center, get(vpmap, vd));
577 vec = radius*vec/CGAL::sqrt(vec.squared_length());
578 put(vpmap, vd, Kernel::Point_3(center.x() + vec.x(),
579 center.y() + vec.y(),
580 center.z() + vec.z()));
581 }
582
583 Facegraph_item* sphere_item = new Facegraph_item(sphere);
584 sphere_item->setName(dock_widget->name_lineEdit->text());
585 Scene_interface::Item_id id = scene->addItem(sphere_item);
586 scene->setSelectedItem(id);
587 }
588 //make a tetrahedron
589 template<class Facegraph_item>
generateTetrahedron()590 void Basic_generator_plugin::generateTetrahedron()
591 {
592 typename Facegraph_item::Face_graph tetrahedron;
593
594 QString point_texts[4];
595 Point points[4];
596 point_texts[0] = dock_widget->tetP0->text();
597 point_texts[1] = dock_widget->tetP1->text();
598 point_texts[2] = dock_widget->tetP2->text();
599 point_texts[3] = dock_widget->tetP3->text();
600
601 for(int i=0; i<4; ++i)
602 {
603 QStringList list = point_texts[i].split(QRegExp("\\s+"), CGAL_QT_SKIP_EMPTY_PARTS);
604 if (list.isEmpty()) return;
605 if (list.size()!=3){
606 QMessageBox *msgBox = new QMessageBox;
607 msgBox->setWindowTitle("Error");
608 msgBox->setText("ERROR : Input should consists of 3 doubles.");
609 msgBox->exec();
610 return;
611 }
612 double coords[3];
613 for(int j=0; j<3; ++j)
614 {
615 bool ok;
616 coords[j] = list.at(j).toDouble(&ok);
617 if(!ok)
618 {
619 QMessageBox *msgBox = new QMessageBox;
620 msgBox->setWindowTitle("Error");
621 msgBox->setText("ERROR : Coordinates are invalid.");
622 msgBox->exec();
623 return;
624 }
625 }
626 points[i] = Point(coords[0], coords[1], coords[2]);
627 }
628 CGAL::make_tetrahedron(points[0],
629 points[1],
630 points[2],
631 points[3],
632 tetrahedron);
633
634 Facegraph_item* tet_item = new Facegraph_item(tetrahedron);
635 tet_item->setName(dock_widget->name_lineEdit->text());
636 Scene_interface::Item_id id = scene->addItem(tet_item);
637 scene->setSelectedItem(id);
638 }
639 //make a point set
generatePoints()640 void Basic_generator_plugin::generatePoints()
641 {
642 QString text = dock_widget->point_textEdit->toPlainText();
643 Scene_points_with_normal_item* item = new Scene_points_with_normal_item();
644 QStringList list = text.split(QRegExp("\\s+"), CGAL_QT_SKIP_EMPTY_PARTS);
645 int counter = 0;
646 double coord[3];
647 bool ok = true;
648 if (list.isEmpty()) return;
649 if (list.size()%3!=0){
650 QMessageBox *msgBox = new QMessageBox;
651 msgBox->setWindowTitle("Error");
652 msgBox->setText("ERROR : Input should consists of triplets.");
653 msgBox->exec();
654 return;
655 }
656
657 Q_FOREACH(QString s, list)
658 {
659 if(!s.isEmpty())
660 {
661 double res = s.toDouble(&ok);
662 if(!ok)
663 {
664 QMessageBox *msgBox = new QMessageBox;
665 msgBox->setWindowTitle("Error");
666 msgBox->setText("ERROR : Coordinates are invalid.");
667 msgBox->exec();
668 break;
669 }
670 else
671 {
672 coord[counter] = res;
673 counter++;
674 }
675 }
676 if(counter == 3)
677 {
678 const Kernel::Point_3 p(coord[0], coord[1], coord[2]);
679 item->point_set()->insert(p);
680 counter =0;
681 }
682 }
683 if(ok)
684 {
685 dock_widget->point_textEdit->clear();
686 item->point_set()->unselect_all();
687 item->setName(dock_widget->name_lineEdit->text());
688 item->setColor(Qt::black);
689 item->invalidateOpenGLBuffers();
690 Scene_interface::Item_id id = scene->addItem(item);
691 scene->setSelectedItem(id);
692 }
693 }
694 //make a polyline
generateLines()695 void Basic_generator_plugin::generateLines()
696 {
697 QString text = dock_widget->line_textEdit->toPlainText();
698 std::list<std::vector<Scene_polylines_item::Point_3> > polylines;
699 polylines.resize(polylines.size()+1);
700 std::vector<Scene_polylines_item::Point_3>& polyline = *(polylines.rbegin());
701 QStringList polylines_metadata;
702
703 QStringList list = text.split(QRegExp("\\s+"), CGAL_QT_SKIP_EMPTY_PARTS);
704 int counter = 0;
705 double coord[3];
706 bool ok = true;
707 if (list.isEmpty()) return;
708 if(!dock_widget->polygon_checkBox->isChecked() && list.size()%3!=0){
709 QMessageBox *msgBox = new QMessageBox;
710 msgBox->setWindowTitle("Error");
711 msgBox->setText("ERROR : Input should consists of triplets.");
712 msgBox->exec();
713 return;
714 }
715 else if(dock_widget->polygon_checkBox->isChecked()&& list.size()%2!=0){
716 QMessageBox *msgBox = new QMessageBox;
717 msgBox->setWindowTitle("Error");
718 msgBox->setText("ERROR : Input should consists of pairs.");
719 msgBox->exec();
720 return;
721 }
722 Q_FOREACH(QString s, list)
723 {
724 if(!s.isEmpty())
725 {
726 double res = s.toDouble(&ok);
727 if(!ok)
728 {
729 QMessageBox *msgBox = new QMessageBox;
730 msgBox->setWindowTitle("Error");
731 msgBox->setText("ERROR : Coordinates are invalid.");
732 msgBox->exec();
733 break;
734 }
735 else
736 {
737 coord[counter] = res;
738 counter++;
739 }
740 }
741 if(!dock_widget->polygon_checkBox->isChecked() && counter == 3)
742 {
743 Scene_polylines_item::Point_3 p(coord[0], coord[1], coord[2]);
744 polyline.push_back(p);
745 counter =0;
746 }
747 else if(dock_widget->polygon_checkBox->isChecked() && counter == 2)
748 {
749 Scene_polylines_item::Point_3 p(coord[0], coord[1], 0);
750 polyline.push_back(p);
751 counter = 0;
752 }
753 }
754 if(dock_widget->polygon_checkBox->isChecked())
755 {
756 polyline.push_back(polyline.front()); //polygon_2 are not closed.
757 }
758 if(ok)
759 {
760 dock_widget->line_textEdit->clear();
761 if(dock_widget->fill_checkBox->isChecked())
762 {
763 CGAL::Three::Three::CursorScopeGuard guard(Qt::WaitCursor);
764 QApplication::processEvents();
765 if(polyline.front() != polyline.back()) {
766 polyline.push_back(polyline.front());
767 }
768 if(polyline.size() < 4) { // no triangle, skip it (needs at least 3 + 1 repeat)
769 QMessageBox::warning(mw, "Warning", "Needs at least 3 points to triangulate. Aborting.");
770 return;
771 }
772 std::vector<Face> patch;
773 CGAL::Polygon_mesh_processing::triangulate_hole_polyline(polyline,
774 std::back_inserter(patch),
775 CGAL::Polygon_mesh_processing::parameters::use_delaunay_triangulation(true));
776
777 if(patch.empty()) {
778 QMessageBox::warning(mw, "Warning", "Triangulation failed.");
779 return;
780 }
781 SMesh* poly = new SMesh;
782 CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(polyline,
783 patch,
784 *poly);
785
786 Scene_surface_mesh_item* poly_item = new Scene_surface_mesh_item(poly);
787 poly_item->setName(dock_widget->name_lineEdit->text());
788 poly_item->setRenderingMode(FlatPlusEdges);
789 scene->setSelectedItem(scene->addItem(poly_item));
790 }
791 else
792 {
793 Scene_polylines_item* item = new Scene_polylines_item();
794 item->polylines = polylines;
795 item->invalidateOpenGLBuffers();
796 item->setName(dock_widget->name_lineEdit->text());
797 item->setColor(Qt::black);
798 item->setProperty("polylines metadata", polylines_metadata);
799 Scene_interface::Item_id id = scene->addItem(item);
800 scene->setSelectedItem(id);
801 }
802 }
803 }
804
805 struct Point_generator
806 {
807 std::size_t w,h;
808 Point bl, ur;
Point_generatorPoint_generator809 Point_generator(const std::size_t& w,
810 const std::size_t& h,
811 const Point& bl,
812 const Point& ur)
813 :w(w), h(h), bl(bl), ur(ur)
814 {}
operator ()Point_generator815 Point operator()(std::size_t i, std::size_t j) const
816 {
817 return Point(bl.x() + i*(ur.x()-bl.x())/(w-1),
818 bl.y() + j*(ur.y()-bl.y())/(h-1),
819 bl.z() + j*(ur.z()-bl.z())/(h-1));
820 }
821 };
822 template<class Facegraph_item>
generateGrid()823 void Basic_generator_plugin::generateGrid()
824 {
825 typedef typename Facegraph_item::Face_graph Face_graph;
826 Face_graph grid;
827
828 QString points_text;
829 Point extrema[2];
830 using size_type = typename boost::graph_traits<Face_graph>::vertices_size_type;
831 size_type nb_cells[2];
832 bool triangulated = dock_widget->grid_checkBox->isChecked();
833 points_text= dock_widget->grid_lineEdit->text();
834
835 QStringList list = points_text.split(QRegExp("\\s+"), CGAL_QT_SKIP_EMPTY_PARTS);
836 if (list.isEmpty()) return;
837 if (list.size()!=6){
838 QMessageBox *msgBox = new QMessageBox;
839 msgBox->setWindowTitle("Error");
840 msgBox->setText("ERROR : Input should consists of 6 doubles.");
841 msgBox->exec();
842 return;
843 }
844 double coords[6];
845 for(int j=0; j<6; ++j)
846 {
847 bool ok;
848 coords[j] = list.at(j).toDouble(&ok);
849 if(!ok)
850 {
851 QMessageBox *msgBox = new QMessageBox;
852 msgBox->setWindowTitle("Error");
853 msgBox->setText("ERROR : Coordinates are invalid.");
854 msgBox->exec();
855 return;
856 }
857 }
858 extrema[0] = Point(coords[0], coords[1], coords[2]);
859 extrema[1] = Point(coords[3], coords[4], coords[5]);
860 nb_cells[0] = static_cast<size_type>(dock_widget->gridX_spinBox->value());
861 nb_cells[1] = static_cast<size_type>(dock_widget->gridY_spinBox->value());
862
863 //nb_points = nb_cells+1
864 Point_generator point_gen(nb_cells[0]+1, nb_cells[1]+1, extrema[0], extrema[1]);
865
866 CGAL::make_grid(nb_cells[0], nb_cells[1], grid, point_gen, triangulated);
867 Facegraph_item* grid_item = new Facegraph_item(grid);
868 grid_item->setName(dock_widget->name_lineEdit->text());
869 Scene_interface::Item_id id = scene->addItem(grid_item);
870 scene->setSelectedItem(id);
871 }
872 #include "Basic_generator_plugin.moc"
873