// if QT is not installed, a message will be issued in runtime.
#ifndef CGAL_USE_QT
#include <iostream>
int main(int, char*)
{
std::cout << "Sorry, this demo needs QT...";
std::cout << std::endl;
return 0;
}
#else
#include <fstream>
#include <stack>
#include <set>
#include <string>
#include <CGAL/basic.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Point_2.h>
#include <CGAL/Triangulation_euclidean_traits_2.h>
#include <CGAL/Constrained_triangulation_2.h>
#include <CGAL/IO/Qt_widget.h>
#include <CGAL/IO/Qt_widget_Constrained_triangulation_2.h>
#include <CGAL/IO/Qt_widget_get_point.h>
#include <qapplication.h>
#include <qmainwindow.h>
#include <qstatusbar.h>
#include <qfiledialog.h>
#include <qmessagebox.h>
#include <qpopupmenu.h>
#include <qmenubar.h>
typedef double Coord_type;
typedef CGAL::Cartesian<Coord_type> K;
typedef K::Point_2 Point_2;
typedef K::Segment_2 Segment;
typedef K::Triangle_2 Triangle;
typedef CGAL::Constrained_triangulation_2<K> Constrained_triangulation;
typedef Constrained_triangulation::Constraint Constraint;
typedef Constrained_triangulation::Face_handle Face_handle;
typedef Constrained_triangulation::Vertex_handle Vertex_handle;
const QString my_title_string("Contrained Triangulation Demo with"
" CGAL Qt_widget");
class MyWindow : public QMainWindow
{
Q_OBJECT
public:
MyWindow(int x, int y) {
widget = new CGAL::Qt_widget(this);
setCentralWidget(widget);
widget->set_window(-1.1, 1.1, -1.1, 1.1, true);
point_factory = new CGAL::Qt_widget_get_point<K>();
connect(widget, SIGNAL(new_cgal_object(CGAL::Object)),
this, SLOT(new_point(CGAL::Object)) );
widget->attach(point_factory);
connect(widget, SIGNAL(redraw_on_back()), this, SLOT(redrawWin()) );
statusBar();
// file menu
QPopupMenu * file = new QPopupMenu( this );
menuBar()->insertItem( "&File", file );
file->insertItem("&Open", this, SLOT(open()), CTRL+Key_O );
file->insertItem("&Quit", this, SLOT(close()), CTRL+Key_Q );
// help menu
QPopupMenu * help = new QPopupMenu( this );
menuBar()->insertItem( "&Help", help );
help->insertItem("&About", this, SLOT(about()), CTRL+Key_A );
widget->show();
resize(x,y);
};
void draw_constraints()
{
*widget << CGAL::RED;
widget->lock();
std::list<Constraint>::iterator cit=lc.begin();
for( ; cit != lc.end(); ++cit) {
*widget << Segment((*cit).first,(*cit).second);
}
widget -> unlock();
*widget << CGAL::BLUE;
}
void draw_connected_component(const Point_2& p)
{
Face_handle fh = ct.locate(p);
if(fh==0) return;
std::set<Face_handle> component;
std::list<Face_handle> st;
//std::list<Vertex_handle> stv;
// component includes the faces of the connected_component
// stack includes the faces in component whose neighbors
// have not yet been looked at
st.push_back(fh);
component.insert(fh);
while (! st.empty()){
fh = st.back();
st.pop_back();
for(int i = 0 ; i < 3 ; ++i){
if ( (! fh->is_constrained(i)) &&
component.find(fh->neighbor(i)) == component.end() ) {
component.insert(fh->neighbor(i));
st.push_back(fh->neighbor(i));
}
}
}
// draw
int width=widget->lineWidth();
*widget << CGAL::FillColor(CGAL::GREEN) << CGAL::LineWidth(0);
std::set<Face_handle>::iterator it;
for ( it = component.begin(); it != component.end(); it++) {
if (! ct.is_infinite( *it)) *widget << ct.triangle( *it);
else *widget << ct.segment(*it, (*it)->index(ct.infinite_vertex()));
}
*widget << CGAL::LineWidth(width);
};
void init_paint()
{
widget->lock();
load_file("data/fish");
widget->unlock();
statusBar()->message("Enter points with the left button");
};
void load_file(QString name)
{
std::ifstream is(name);
if(!is) return;
lc.clear();
int n;
is >> n;
qDebug("Reading %d constraints", n);
Point_2 p,q;
for(; n > 0; n--) {
is >> p >> q;
lc.push_back(std::make_pair(p,q));
}
ct=lc;
assert(ct.is_valid());
redrawWin();
};
~MyWindow()
{
delete(point_factory);
};
public slots:
void redrawWin()
{
widget->lock();
widget->clear();
*widget << CGAL::BLUE << ct;
draw_constraints();
widget->unlock();
}
void new_point(CGAL::Object obj)
{
Point_2 p;
if (CGAL::assign(p,obj))
{
widget->clear();
widget->lock();
*widget << CGAL::BLUE <<ct;
draw_connected_component(p);
draw_constraints();
*widget << p ;
widget->unlock();
}
};
void about()
{
QMessageBox::about( this, my_title_string,
"This is a demo from Mariette Yvinec courses,\n"
"adapted to work with CGAL Qt_widget by\n"
"Laurent Rineau ( rineau@clipper.ens.fr )");
};
void open()
{
QString fileName = QFileDialog::getOpenFileName( "data",
QString::null, this );
if ( fileName.isEmpty() )
return;
load_file(fileName);
};
private:
CGAL::Qt_widget* widget;
CGAL::Qt_widget_layer* point_factory;
std::list<Constraint> lc;
Constrained_triangulation ct;
};
// moc_source_file : constrained.C
#include "constrained.moc"
int
main(int argc, char **argv)
{
QApplication app( argc, argv );
MyWindow win(400,430); // physical window size
app.setMainWidget(&win);
win.setCaption(my_title_string);
win.show();
// initial paiting must be done after show()
// because Qt send resizeEvent only on show.
win.load_file("data/fish");
win.statusBar()->message("Enter points with the left button");
return app.exec();
}
#endif // CGAL_USE_QT
syntax highlighted by Code2HTML, v. 0.9.1