mirror of https://github.com/CGAL/cgal
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:
parent
ae48e09f41
commit
cdaee9ec92
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue