added an edit-vertex layer; this does not work however when the moving the

site is chosen; when a moved site becomes hidden, then the program breaks
down since hidden sites do not correspond to vertex handles
This commit is contained in:
Menelaos Karavelas 2003-10-03 08:19:18 +00:00
parent ae48e09f41
commit cdaee9ec92
4 changed files with 360 additions and 42 deletions

View File

@ -59,12 +59,14 @@ private:
CGAL::Qt_widget_standard_toolbar *stoolbar;
CGAL::Qt_widget_get_circle<Rep> get_circle;
CGAL::Qt_widget_get_point<Rep> get_point;
bool is_edit_mode;
bool is_remove_mode;
bool is_insert_point_mode;
public:
My_Window(int x, int y)
{
is_edit_mode = false;
is_remove_mode = false;
is_insert_point_mode = false;
@ -100,6 +102,9 @@ public:
connect(layers_toolbar, SIGNAL(removeModeChanged(bool)), this,
SLOT(get_remove_mode(bool)));
connect(layers_toolbar, SIGNAL(editModeChanged(bool)), this,
SLOT(get_edit_mode(bool)));
connect(file_toolbar, SIGNAL(fileToRead(const QString&)), this,
SLOT(read_from_file(const QString&)));
@ -134,6 +139,7 @@ public:
private slots:
void get_object(CGAL::Object obj)
{
if ( is_edit_mode ) { return; }
if ( is_remove_mode ) {
if ( ag.number_of_vertices() == 0 ) { return; }
Point_2 p;
@ -187,7 +193,7 @@ private slots:
{
is_insert_point_mode = b;
if ( !is_remove_mode ) {
if ( !is_remove_mode && !is_edit_mode ) {
if ( is_insert_point_mode ) {
get_point.activate();
get_circle.deactivate();
@ -199,46 +205,61 @@ private slots:
}
void get_remove_mode(bool b)
{
is_remove_mode = b;
{
is_remove_mode = b;
if ( is_remove_mode ) {
get_point.activate();
get_circle.deactivate();
} else {
if ( !is_insert_point_mode ) {
get_point.deactivate();
get_circle.activate();
}
if ( is_remove_mode ) {
get_point.activate();
get_circle.deactivate();
} else {
if ( !is_insert_point_mode ) {
get_point.deactivate();
get_circle.activate();
}
}
}
void get_edit_mode(bool b)
{
is_edit_mode = b;
if ( is_edit_mode ) {
get_point.activate();
get_circle.deactivate();
} else {
if ( !is_insert_point_mode ) {
get_point.deactivate();
get_circle.activate();
}
}
}
void read_from_file(const QString& fileName)
{
std::ifstream f(fileName);
assert( f );
{
std::ifstream f(fileName);
assert( f );
// int n;
// f >> n;
Apollonius_site_2 wp;
// int n;
// f >> n;
Apollonius_site_2 wp;
int counter = 0;
std::cout << std::endl;
int counter = 0;
std::cout << std::endl;
while ( f >> wp ) {
ag.insert(wp);
counter++;
if ( counter % 500 == 0 ) {
std::cout << "\r" << counter
<< " sites haved been inserted..." << std::flush;
}
while ( f >> wp ) {
ag.insert(wp);
counter++;
if ( counter % 500 == 0 ) {
std::cout << "\r" << counter
<< " sites haved been inserted..." << std::flush;
}
std::cout << "\r" << counter
<< " sites haved been inserted... Done!"
<< std::endl;
assert( ag.is_valid(false, 1) );
widget->redraw();
}
std::cout << "\r" << counter
<< " sites haved been inserted... Done!"
<< std::endl;
assert( ag.is_valid(false, 1) );
widget->redraw();
}
void write_to_file(const QString& fileName)
{
@ -253,15 +274,15 @@ private slots:
}
void print_screen()
{
widget->print_to_ps();
}
{
widget->print_to_ps();
}
void remove_all()
{
ag.clear();
widget->redraw();
}
{
ag.clear();
widget->redraw();
}
};
@ -282,6 +303,7 @@ main(int argc, char* argv[])
W.show();
W.set_window(0,size,0,size);
W.setCaption("Apollonius diagram 2");
W.setMouseTracking(TRUE);
return app.exec();
}

View File

@ -0,0 +1,264 @@
#ifndef APOLLONIUS_GRAPH_2_EDIT_VERTEX_H
#define APOLLONIUS_GRAPH_2_EDIT_VERTEX_H
#ifdef CGAL_USE_QT
#include <CGAL/IO/Qt_widget.h>
#include <CGAL/IO/Qt_widget_layer.h>
#include <qobject.h>
#include <qpopupmenu.h>
#include <qcursor.h>
class Edit_vertex_layer_helper
: public CGAL::Qt_widget_layer
{
Q_OBJECT
public:
virtual void delete_vertexi(){};
virtual void move_vertexi(){};
virtual void change_weighti(){};
protected:
void emit_signal() {
emit( apollonius_graph_changed() );
}
public slots:
void stateChanged(int i)
{
if( i == 2 ) {
activate();
} else if ( i == 0 ) {
deactivate();
}
}
void delete_vertex()
{
delete_vertexi();
emit( apollonius_graph_changed() );
}
void move_vertex() {
move_vertexi();
}
void change_weight() {
change_weighti();
}
signals:
void apollonius_graph_changed();
};
#include "edit_vertex_layer.moc"
template <class AG>
class Edit_vertex_layer : public Edit_vertex_layer_helper
{
public:
typedef typename AG::Site_2 Site_2;
typedef typename AG::Point_2 Point_2;
typedef typename AG::Face_handle Face_handle;
typedef typename AG::Vertex_handle Vertex_handle;
typedef typename AG::Geom_traits GT;
typedef typename GT::FT FT;
protected:
FT first_x, first_y;
FT x2, y2;
bool wasrepainted;
bool on_first;
//true if right mouse button was pressed
bool
move_button_pressed;
//true if the popup's move button was pressed
bool
change_weight_pressed;
//true if the popup's change_weight button was pressed
Vertex_handle current_v;
//the vertex that will be processed
Point_2 old_point;
FT old_weight;
//contains the old vertex that should be removed
AG* ag;
//pointer to regular triangulation being used
QPopupMenu* popup;
//the popup being displayed when right mouse button is pressed
public:
Edit_vertex_layer(AG* ag)
: wasrepainted(true), on_first(false),
move_button_pressed(false), change_weight_pressed(false),
ag(ag) {};
// void set_apollonius_graph (AG* ag) { this->ag = ag; }
template < class TRIANGULATION >
Vertex_handle
closest_vertex(const TRIANGULATION &T,
Face_handle f, const Point_2& p)
{
return ag->nearest_neighbor(p, f->vertex());
#if 0
Vertex_handle v ;
typename GT::Compare_distance_2 cmp =
T.geom_traits().compare_distance_2_object();
if( T.is_infinite(f)){
int i = f->index(T.infinite_vertex());
Bare_point pcwi = f->vertex(f->cw(i))->point();
Bare_point pccwi = f->vertex(f->ccw(i))->point();
v = cmp(p, pcwi, pccwi) == CGAL::SMALLER ? f->vertex(f->cw(i)) :
f->vertex(f->ccw(i));
}
else{
v = f->vertex(0);
if (cmp(p, f->vertex(1)->point(), v->point()) == CGAL::SMALLER)
v = f->vertex(1);
if (cmp(p, f->vertex(2)->point(), v->point()) == CGAL::SMALLER)
v = f->vertex(2);
}
return v;
#endif
}
private:
QCursor oldcursor;
void draw() {
wasrepainted = true;
}
void mousePressEvent(QMouseEvent *e)
{
if(e->button() == Qt::LeftButton && on_first) {
on_first = false;
}
if(e->button() == Qt::RightButton) {
if ( ag->dimension() < 0 ) { return; }
FT x, y;
widget->x_real(e->x(), x);
widget->y_real(e->y(), y);
Point_2 p(x, y);
Vertex_handle v = ag->nearest_neighbor(p);
// RasterOp old = widget->rasterOp(); //save the initial raster mode
CGAL::PointStyle pstyle = widget->pointStyle();
int psize = widget->pointSize();
// widget->setRasterOp(XorROP);
widget->lock();
*widget << CGAL::RED << CGAL::PointSize(10)
<< CGAL::PointStyle(CGAL::CIRCLE);
if( !wasrepainted ) {
*widget << old_point;
*widget << CGAL::RED;
*widget << old_point;
}
*widget << v->site();
widget->unlock();
// widget->setRasterOp(old);
*widget << CGAL::PointSize(psize) << pstyle;
popup->popup(widget->mapToGlobal(e->pos()));
old_point = v->site().point();
// old_weight = v->site().weight();
current_v = v;
wasrepainted = false;
on_first = false;
}
}
void mouseMoveEvent(QMouseEvent *e)
{
if ( on_first ) {
if( move_button_pressed ){
FT x, y;
widget->x_real(e->x(), x);
widget->y_real(e->y(), y);
if( !wasrepainted ) {
*widget << old_point;
}
*widget << Point_2(x, y);
FT wght = current_v->site().weight();
ag->remove(current_v);
current_v = ag->insert(Site_2(Point_2(x, y), wght/*old_weight*/));
widget->redraw(); //redraw the scenes
old_point = Point_2(x, y);
} else if( change_weight_pressed ) {
FT x, y;
widget->x_real(e->x(), x);
widget->y_real(e->y(), y);
Point_2 lastp = current_v->site().point();
ag->remove(current_v);
FT w = CGAL::sqrt(CGAL::squared_distance(lastp,
Point_2(x,y)));
Site_2 s(lastp, w);
current_v = ag->insert(s);
widget->redraw(); //redraw the scenes
old_point = lastp;
}
}
}
void activating()
{
oldcursor = widget->cursor();
widget->setCursor(crossCursor);
wasrepainted = false;
popup = new QPopupMenu( widget, 0);
popup->insertItem("Delete Vertex", this, SLOT(delete_vertex()));
popup->insertItem("Move Vertex", this, SLOT(move_vertex()));
popup->insertItem("Change Weight", this, SLOT(change_weight()));
}
void deactivating()
{
widget->setCursor(oldcursor);
}
void delete_vertexi()
{
ag->remove(current_v);
widget->redraw(); //redraw the scenes
}
void move_vertexi()
{
on_first = true;
change_weight_pressed = false;
move_button_pressed = true;
double x = CGAL::to_double( old_point.x() );
double y = CGAL::to_double( old_point.y() );
widget->cursor().setPos(widget->mapToGlobal(
QPoint( widget->x_pixel(x),
widget->y_pixel(y) )
));
}
void change_weighti()
{
on_first = true;
move_button_pressed = false;
change_weight_pressed = true;
double x = CGAL::to_double( old_point.x() );
double y = CGAL::to_double( old_point.y() );
widget->cursor().setPos(widget->mapToGlobal(
QPoint( widget->x_pixel(x),
widget->y_pixel(y) )
));
}
}; //end class
#endif // CGAL_USE_QT
#endif // APOLLONIUS_GRAPH_2_EDIT_VERTEX_H

View File

@ -51,8 +51,12 @@ qt_file_toolbar.moc: qt_file_toolbar.h
qt_layers_toolbar.moc: qt_layers_toolbar.h
$(QT_MOC) -o qt_layers_toolbar.moc qt_layers_toolbar.h
edit_vertex_layer.moc: edit_vertex_layer.h
$(QT_MOC) -o edit_vertex_layer.moc edit_vertex_layer.h
apollonius_graph_2$(OBJ_EXT): apollonius_graph_2.moc \
qt_file_toolbar.moc qt_layers_toolbar.moc
qt_file_toolbar.moc qt_layers_toolbar.moc \
edit_vertex_layer.moc
apollonius_graph_2$(EXE_EXT): apollonius_graph_2$(OBJ_EXT)
$(CGAL_CXX) $(LIBPATH) $(EXE_OPT)apollonius_graph_2 \

View File

@ -11,6 +11,7 @@
#include <qwhatsthis.h>
#include "qt_layers.h"
#include "edit_vertex_layer.h"
// icons
#include <CGAL/IO/pixmaps/points.xpm>
@ -19,6 +20,7 @@
#include <CGAL/IO/pixmaps/triangulation.xpm>
#include <CGAL/IO/pixmaps/voronoi.xpm>
#include <CGAL/IO/pixmaps/notool.xpm>
#include <CGAL/IO/pixmaps/movepoint.xpm>
//#include "removecircle.xpm"
@ -37,6 +39,7 @@ public:
showDG = new Delaunay_graph_layer<AG_2>(ag);
showNT = new Visible_sites_layer<AG_2>(ag);
showTR = new Hidden_sites_layer<AG_2>(ag);
edit_V = new Edit_vertex_layer<AG_2>(&ag);
// set the widget
this->widget = widget;
@ -47,7 +50,7 @@ public:
widget->attach(showDG);
widget->attach(showVD);
widget->attach(showNT);
widget->attach(edit_V);
but[0] = new QToolButton(QPixmap( (const char**)points_small_xpm ),
"Show sites",
@ -107,9 +110,18 @@ public:
this,
"Remove site");
#endif
showDG->deactivate();
but[6] = new QToolButton(QPixmap( (const char**)movepoint_xpm ),
"Edit site",
0,
this,
SLOT(edit_mode()),
this,
"Edit site");
nr_of_buttons = 6;
showDG->deactivate();
edit_V->deactivate();
nr_of_buttons = 7;
for(int i = 0; i < nr_of_buttons; i++){
but[i]->setToggleButton(TRUE);
}
@ -127,6 +139,7 @@ public:
delete showDG;
delete showTR;
delete showNT;
delete edit_V;
}
inline QToolBar* toolbar() { return this; };
@ -134,6 +147,7 @@ public:
signals:
void new_object(CGAL::Object);
void removeModeChanged(bool);
void editModeChanged(bool);
void inputModeChanged(bool);
private slots:
@ -192,6 +206,19 @@ private slots:
emit removeModeChanged( but[5]->isOn() );
}
void edit_mode() {
#if 0
if ( but[6]->isOn() ) {
edit_V->activate();
} else {
edit_V->deactivate();
}
emit editModeChanged( but[6]->isOn() );
// emit editModeChanged( but[6]->isOn() );
#endif
}
private:
QToolButton *but[10];
CGAL::Qt_widget *widget;
@ -202,6 +229,7 @@ private:
Delaunay_graph_layer<AG_2> *showDG;
Visible_sites_layer<AG_2> *showNT;
Hidden_sites_layer<AG_2> *showTR;
Edit_vertex_layer<AG_2> *edit_V;
};//end class