First working GUI demo of the periodic hyperbolic Delaunay triangulation. For the time being the working features are initialization with dummy points, point insertion, random point insertion, clear() and circumsenter visualization.

This commit is contained in:
Iordan Iordanov 2016-06-16 12:21:30 +02:00
parent f3fd833b4a
commit b23c64a679
23 changed files with 928 additions and 160 deletions

View File

@ -7,14 +7,14 @@ project (Playground)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
#set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOMOC ON)
cmake_minimum_required(VERSION 2.8.11)
if(POLICY CMP0043)
cmake_policy(SET CMP0043 OLD)
endif()
find_package(CGAL QUIET COMPONENTS Core)
find_package(CGAL QUIET COMPONENTS Core Qt5)
include(${CGAL_USE_FILE})
find_package(Qt5 QUIET COMPONENTS Widgets)
@ -22,21 +22,22 @@ find_package(Qt5 QUIET COMPONENTS Widgets)
find_package( Boost REQUIRED )
include_directories(${Boost_INCLUDE_DIRS})
include_directories (BEFORE ../../../Hyperbolic_triangulation_2/include ../../../Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/include ../../include include)
include_directories (BEFORE ../../include include)
# ui files, created with Qt Designer
#qt5_wrap_ui( uis Periodic_4_hyperbolic_triangulation_2.ui )
qt5_wrap_ui( uis Periodic_4_hyperbolic_Delaunay_triangulation_2.ui )
# qrc files (resources files, that contain icons, at least)
#qt5_add_resources ( RESOURCE_FILES resources/Periodic_4_hyperbolic_triangulation_2.qrc )
qt5_add_resources ( RESOURCE_FILES res.qrc )
# cpp files
add_executable ( Playground playground.cpp )
add_executable ( Triangulation triangulation.cpp )
#qt5_use_modules( Playground Widgets )
add_executable ( Demo Periodic_4_hyperbolic_Delaunay_triangulation_2_demo.cpp ${RESOURCE_FILES} )
qt5_use_modules( Demo Widgets )
target_link_libraries( Playground ${CGAL_LIBRARIES} )
target_link_libraries( Triangulation ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ${Boost_LIBRARIES} )
target_link_libraries( Demo ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ${Boost_LIBRARIES} )

View File

@ -0,0 +1,458 @@
#include <fstream>
// CGAL headers
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h>
#include <CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_traits_2.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/Hyperbolic_octagon_translation_matrix.h>
// unique words
#include <CGAL/Square_root_2_field.h>
// to be deleted (iiordano: why?)
#include <CGAL/Qt/HyperbolicPainterOstream.h>
// for viewportsBbox
#include <CGAL/Qt/utility.h>
// Qt headers
#include <QtGui>
#include <QString>
#include <QActionGroup>
#include <QFileDialog>
#include <QInputDialog>
#include <QGraphicsEllipseItem>
// for filtering
#include <set>
#include <string>
// GraphicsView items and event filters (input classes)
#include <CGAL/Qt/TriangulationCircumcircle.h>
#include <CGAL/Qt/TriangulationMovingPoint.h>
#include <CGAL/Qt/TriangulationConflictZone.h>
#include <CGAL/Qt/TriangulationRemoveVertex.h>
#include <CGAL/Qt/TriangulationPointInputAndConflictZone.h>
#include <CGAL/Qt/VoronoiGraphicsItem.h>
#include <CGAL/Qt/TriangulationGraphicsItemWithColorInfo.h> // Visualise color
//#include <CGAL/TranslationInfo.h> // Store color
#include <CGAL/Qt/DemosMainWindow.h>
#include <CGAL/CORE_Expr.h>
#include <CGAL/Cartesian.h>
#define INITIAL_RECURSION_DEPTH 4
// dummy points
#include <CGAL/Periodic_4_hyperbolic_triangulation_dummy_14.h>
// the two base classes
#include "ui_Periodic_4_hyperbolic_Delaunay_triangulation_2.h"
typedef CORE::Expr NT;
typedef CGAL::Cartesian<NT> Kernel;
typedef CGAL::Periodic_4_hyperbolic_Delaunay_triangulation_traits_2<Kernel> Traits;
typedef CGAL::Periodic_4_hyperbolic_Delaunay_triangulation_2<Traits> Triangulation;
typedef Hyperbolic_octagon_translation_matrix<Traits> Octagon_matrix;
typedef Kernel::Point_2 Point;
typedef Triangulation::Vertex_handle Vertex_handle;
typedef Traits::Side_of_fundamental_octagon Side_of_fundamental_octagon;
struct PointsComparator {
static double eps;
bool operator() (const Point& l, const Point& r) const
{
if(l.x() < r.x() - eps) {
return true;
}
if(l.x() < r.x() + eps) {
if(l.y() < r.y() - eps) {
return true;
}
}
return false;
}
};
double PointsComparator::eps = 0.0001;
string glabels[] = { "a", "\\bar{b}", "c", "\\bar{d}", "\\bar{a}", "b", "\\bar{c}", "d" };
void recurr(vector<Octagon_matrix>& v, vector<Octagon_matrix> g, int depth = 1) {
if (depth > 1) {
recurr(v, g, depth-1);
vector<Octagon_matrix> tmp;
vector<string> tmpw;
for (int i = 0; i < v.size(); i++) {
tmp.push_back(v[i]);
}
for (int i = 0; i < tmp.size(); i++) {
for (int j = 0; j < g.size(); j++) {
v.push_back(tmp[i]*g[j]);
}
}
} else if (depth == 1) {
for (int i = 0; i < g.size(); i++) {
v.push_back(g[i]);
}
}
}
void my_unique_words(std::vector<Point>& p, Point input, int depth) {
std::vector<Octagon_matrix> g;
get_generators(g);
std::vector<Octagon_matrix> v;
recurr(v, g, depth);
std::set<Octagon_matrix> s;
for (int i = 0; i < v.size(); i++) {
s.insert( v[i] );
}
cout << "Translating... " << endl;
for (set<Octagon_matrix>::iterator it = s.begin(); it != s.end(); it++) {
Octagon_matrix m = *it;
Point res;
res = m.apply(input);
p.push_back( res );
}
cout << "Done! Now I need to draw " << p.size() << " points..." << endl;
}
class MainWindow :
public CGAL::Qt::DemosMainWindow,
public Ui::Periodic_4_hyperbolic_Delaunay_triangulation_2
{
Q_OBJECT
private:
int cidx;
std::vector<int> ccol;
bool dummy_mode;
Triangulation dt;
QGraphicsEllipseItem * disk;
QGraphicsScene scene;
CGAL::Qt::TriangulationGraphicsItem<Triangulation> * dgi;
// for drawing Voronoi diagram of the orbit of the origin
CGAL::Qt::TriangulationMovingPoint<Triangulation> * mp;
CGAL::Qt::TriangulationRemoveVertex<Triangulation> * trv;
CGAL::Qt::TriangulationPointInputAndConflictZone<Triangulation> * pi;
CGAL::Qt::TriangulationCircumcircle<Triangulation> * tcc;
public:
MainWindow();
public slots:
void processInput(CGAL::Object o);
void on_actionCircumcenter_toggled(bool checked);
void on_actionShowTriangulation_toggled(bool checked);
void on_actionInsertPoint_toggled(bool checked);
void on_actionInsertRandomPoints_triggered();
void on_actionLoadPoints_triggered();
void on_actionClear_triggered();
void on_actionRecenter_triggered();
signals:
void changed();
};
MainWindow::MainWindow()
: DemosMainWindow(), dt(Traits(1))
{
dt.insert_dummy_points();
cidx = 0;
for (int i = 0; i < 14; i++)
ccol.push_back(i);
setupUi(this);
this->graphicsView->setAcceptDrops(false);
// Add Poincaré disk
qreal origin_x = 0, origin_y = 0, radius = 1, diameter = 2*radius;
qreal left_top_corner_x = origin_x - radius;
qreal left_top_corner_y = origin_y - radius;
qreal width = diameter, height = diameter;
// set background
qreal eps = 0.01;
QGraphicsRectItem* rect = new QGraphicsRectItem(left_top_corner_x - eps, left_top_corner_y - eps, width + 2*eps, height + 2*eps);
rect->setPen(Qt::NoPen);
rect->setBrush(Qt::white);
scene.addItem(rect);
// set disk
disk = new QGraphicsEllipseItem(left_top_corner_x, left_top_corner_y, width, height);
QPen pen; // creates a default pen
pen.setWidth(0);
//pen.setBrush(Qt::black);
pen.setBrush(Qt::black);
disk->setPen(pen);
scene.addItem(disk);
// Add a GraphicItem for the Triangulation triangulation
dgi = new CGAL::Qt::TriangulationGraphicsItem<Triangulation>(&dt);
QObject::connect(this, SIGNAL(changed()),
dgi, SLOT(modelChanged()));
dgi->setVerticesPen(QPen(Qt::red, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
dgi->setEdgesPen(QPen(QColor(200, 200, 0), 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
scene.addItem(dgi);
// Setup input handlers. They get events before the scene gets them
// and the input they generate is passed to the triangulation with
// the signal/slot mechanism
pi = new CGAL::Qt::TriangulationPointInputAndConflictZone<Triangulation>(&scene, &dt, this );
QObject::connect(pi, SIGNAL(generate(CGAL::Object)),
this, SLOT(processInput(CGAL::Object)));
mp = new CGAL::Qt::TriangulationMovingPoint<Triangulation>(&dt, this);
// TriangulationMovingPoint<Triangulation> emits a modelChanged() signal each
// time the moving point moves.
// The following connection is for the purpose of emitting changed().
QObject::connect(mp, SIGNAL(modelChanged()),
this, SIGNAL(changed()));
trv = new CGAL::Qt::TriangulationRemoveVertex<Triangulation>(&dt, this);
QObject::connect(trv, SIGNAL(modelChanged()),
this, SIGNAL(changed()));
tcc = new CGAL::Qt::TriangulationCircumcircle<Triangulation>(&scene, &dt, this);
tcc->setPen(QPen(Qt::blue, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
//cz = new CGAL::Qt::TriangulationConflictZone<Triangulation>(&scene, &dt, this);
//
// Manual handling of actions
//
QObject::connect(this->actionQuit, SIGNAL(triggered()),
this, SLOT(close()));
// We put mutually exclusive actions in an QActionGroup
QActionGroup* ag = new QActionGroup(this);
ag->addAction(this->actionInsertPoint);
ag->addAction(this->actionCircumcenter);
// Check two actions
this->actionInsertPoint->setChecked(true);
this->actionShowTriangulation->setChecked(true);
// //
// // Setup the scene and the view
// //
scene.setItemIndexMethod(QGraphicsScene::NoIndex);
scene.setSceneRect(left_top_corner_x, left_top_corner_y, width, height);
this->graphicsView->setScene(&scene);
this->graphicsView->setMouseTracking(true);
this->graphicsView->shear(230, 230);
this->graphicsView->rotate(90);
// // The navigation adds zooming and translation functionality to the
// // QGraphicsView
this->addNavigation(this->graphicsView);
this->setupStatusBar();
this->setupOptionsMenu();
this->addAboutDemo(":/cgal/help/about_Triangulation_triangulation_2.html");
this->addAboutCGAL();
//this->addRecentFiles(this->menuFile, this->actionQuit);
//connect(this, SIGNAL(openRecentFile(QString)),
// this, SLOT(open(QString)));
}
void
MainWindow::processInput(CGAL::Object o)
{
Point p;
if(CGAL::assign(p, o)){
Vertex_handle v = dt.insert(p);
}
emit(changed());
assert(dt.is_valid());
}
/*
* Qt Automatic Connections
* http://doc.trolltech.com/4.4/designer-using-a-component.html#automatic-connections
*
* setupUi(this) generates connections to the slots named
* "on_<action_name>_<signal_name>"
*/
void
MainWindow::on_actionInsertPoint_toggled(bool checked)
{
if(checked){
scene.installEventFilter(pi);
scene.installEventFilter(trv);
} else {
scene.removeEventFilter(pi);
scene.removeEventFilter(trv);
}
}
void
MainWindow::on_actionCircumcenter_toggled(bool checked)
{
if(checked){
scene.installEventFilter(tcc);
tcc->show();
} else {
scene.removeEventFilter(tcc);
tcc->hide();
}
}
void
MainWindow::on_actionShowTriangulation_toggled(bool checked)
{
dgi->setVisibleEdges(checked);
}
void
MainWindow::on_actionClear_triggered()
{
dt.clear();
dt.insert_dummy_points();
emit(changed());
}
void
MainWindow::on_actionInsertRandomPoints_triggered()
{
bool ok = false;
const int number_of_points =
QInputDialog::getInt(this,
tr("Number of random points"),
tr("Enter number of random points"),
100,
0,
std::numeric_limits<int>::max(),
1,
&ok);
if(!ok) {
return;
}
// wait cursor
QApplication::setOverrideCursor(Qt::WaitCursor);
vector<Point> pts;
pts.reserve(number_of_points);
typedef CGAL::Creator_uniform_2<double, Point> Creator;
CGAL::Random_points_in_disc_2<Point, Creator> g( 1.0 );
CGAL::cpp11::copy_n( g, number_of_points, std::back_inserter(pts));
for(int i = 0; i < number_of_points; ++i){
processInput(make_object(pts[i]));
}
QApplication::restoreOverrideCursor();
emit(changed());
}
void
MainWindow::on_actionLoadPoints_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Points file"),
".");
if(! fileName.isEmpty()){
//open(fileName);
}
}
void
MainWindow::on_actionRecenter_triggered()
{
this->graphicsView->setSceneRect(dgi->boundingRect());
this->graphicsView->fitInView(dgi->boundingRect(), Qt::KeepAspectRatio);
}
#include "Periodic_4_hyperbolic_Delaunay_triangulation_2_demo.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Q_INIT_RESOURCE(res);
app.setOrganizationDomain("geometryfactory.com");
app.setOrganizationName("GeometryFactory");
app.setApplicationName("Periodic_4_hyperbolic_Delaunay_triangulation_2 demo");
// Import resources from libCGALQt4.
// See http://doc.trolltech.com/4.4/qdir.html#Q_INIT_RESOURCE
//Q_INIT_RESOURCE(File);
//Q_INIT_RESOURCE(Triangulation_2);
//Q_INIT_RESOURCE(Input);
//Q_INIT_RESOURCE(CGAL);
MainWindow mainWindow;
mainWindow.show();
QStringList args = app.arguments();
args.removeAt(0);
//Q_FOREACH(QString filename, args) {
//mainWindow.open(filename);
//}
return app.exec();
}

View File

@ -0,0 +1,10 @@
<RCC>
<qresource prefix="/cgal/help" >
<file>about_CGAL.html</file>
</qresource>
<qresource prefix="/cgal/logos">
<file alias="CGAL.gif" >cgal_logo_ipe_2013.png</file>
<file alias="CGAL.png" >cgal_logo_ipe_2013.png</file>
<file alias="cgal_icon" >cgal_logo.xpm</file>
</qresource>
</RCC>

View File

@ -0,0 +1,8 @@
<html>
<body>
<p><img src=":/cgal/logos/CGAL.png"></p>
<h2>Computational Geometry Algorithms Library<!--CGAL_VERSION--></h2>
<p>CGAL provides efficient and reliable geometric algorithms in the form of a C++ library.</p>
<p>For more information visit <a href="http://www.cgal.org/">www.cgal.org</a></p>
</body>
</html>

View File

@ -0,0 +1,24 @@
/* XPM */
const char * demoicon_xpm[] = {
/* columns rows colors chars-per-pixel */
"16 16 3 1",
" c None",
". c #FFFF00",
"+ c #000000",
/* pixels */
"................",
"...++++...++++..",
"..+....+.+....+.",
"..+......+......",
"..+......+..+++.",
"..+......+....+.",
"..+....+.+....+.",
"...++++...++++..",
"................",
"...++++...+.....",
"..+....+..+.....",
"..+....+..+.....",
"..++++++..+.....",
"..+....+..+.....",
"..+....+..+++++.",
"................"};

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@ -0,0 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/icons">
<file alias="circumcenter.png">icons/circumcenter.png</file>
<file alias="triangulation.png">icons/triangulation.png</file>
</qresource>
</RCC>

View File

@ -192,9 +192,9 @@ public:
// just to give an order(ing)
template< class GT, template <class> class Hyperbolic_octagon_translation_matrix >
bool operator < (const std::complex< typename Hyperbolic_octagon_translation_matrix<GT>:: template Field_number<GT::FT> >& lh,
const std::complex< typename Hyperbolic_octagon_translation_matrix<GT>:: template Field_number<GT::FT> >& rh)
template< class GT >
bool operator<( const std::complex<GT>& lh,
const std::complex<GT>& rh)
{
if (real(lh) < real(rh)) {
return true;
@ -210,10 +210,11 @@ bool operator < (const std::complex< typename Hyperbolic_octagon_translation_mat
}
// just to order octagon_matrices
template<class Field_number>
bool operator < (const Hyperbolic_octagon_translation_matrix<Field_number>& lh,
const Hyperbolic_octagon_translation_matrix<Field_number>& rh)
template<class GT>
bool operator<( const Hyperbolic_octagon_translation_matrix<GT>& lh,
const Hyperbolic_octagon_translation_matrix<GT>& rh)
{
if (lh.A < rh.A) {
return true;
}
@ -227,15 +228,15 @@ bool operator < (const Hyperbolic_octagon_translation_matrix<Field_number>& lh,
return false;
}
template<class Field_number>
bool operator == (const Hyperbolic_octagon_translation_matrix<Field_number>& lh,
const Hyperbolic_octagon_translation_matrix<Field_number>& rh)
template<class GT >
bool operator == (const Hyperbolic_octagon_translation_matrix<GT>& lh,
const Hyperbolic_octagon_translation_matrix<GT>& rh)
{
return (lh.A == rh.A && lh.B == rh.B);
}
template<class Field_number>
std::ostream& operator<<(std::ostream& os, const Hyperbolic_octagon_translation_matrix<Field_number>& m)
template<class GT>
std::ostream& operator<<(std::ostream& os, const Hyperbolic_octagon_translation_matrix<GT>& m)
{
os << m.A << " " << m.B;
return os;

View File

@ -43,7 +43,7 @@ void Hyperbolic_random_points_in_disc_2(std::vector<typename Gt::Point_2>& outpu
rand = CGAL::Random(seed);
}
/* CGAL::Random_points_in_disc_2<Point_2, Creator> in_Euclidean_disk(rh, rand); */
CGAL::Random_points_in_disc_2<Point_2, Creator> in_Euclidean_disk(rh, rand);
CGAL::Random_points_in_disc_2<Creator> in_Euclidean_disk(rh, rand);
std::vector<Point_2> pts;
pts.reserve(nb);

View File

@ -46,6 +46,13 @@ public Periodic_4_hyperbolic_triangulation_2<GT, TDS> {
typedef Periodic_4_hyperbolic_triangulation_2<GT, TDS> Base;
public:
#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
using Base::cw;
using Base::ccw;
using Base::geom_traits;
#endif
typedef typename Base::Locate_type Locate_type;
typedef typename Base::Geometric_traits Geometric_traits;
typedef typename Base::Triangulation_data_structure Triangulation_data_structure;
@ -80,6 +87,7 @@ public:
typedef typename Base::Face_circulator Face_circulator;
typedef typename Base::Edge_circulator Edge_circulator;
typedef typename Base::Vertex_circulator Vertex_circulator;
typedef typename Base::Line_face_circulator Line_face_circulator;
typedef Face_iterator All_faces_iterator;
typedef Edge_iterator All_edges_iterator;
@ -164,9 +172,200 @@ public:
InputIterator last,
bool is_large_point_set = true);
bool locally_Delaunay(const Face_handle&, int);
void propagating_flip(Face_handle&, int);
void restore_Delaunay(Vertex_handle);
void flip_single_edge(Face_handle, int);
bool flippable(Face_handle, int);
}; // class Periodic_4_hyperbolic_Delaunay_triangulation_2
template<class Gt, class Tds>
bool Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::flippable(Face_handle f, int i)
{
Face_handle nb = f->neighbor(i);
int j = nb->index(f);
const Point *p[4];
p[0] = &f->vertex(i)->point(); // i
p[1] = &nb->vertex(j)->point(); // opposite
p[2] = &f->vertex(ccw(i))->point(); // ccw
p[3] = &f->vertex(cw(i))->point(); // cw
if (f->has_zero_offsets() && nb->has_zero_offsets()) {
if (orientation(*p[0], *p[1], *p[2]) == LEFT_TURN)
return false;
if (orientation(*p[0], *p[1], *p[3]) == RIGHT_TURN)
return false;
} else {
Offset off[4];
off[0] = f->offset(i);
off[1] = f->neighbor_offset(j).append(nb->offset(j));
off[2] = f->offset(ccw(i));
off[3] = f->offset(cw(i));
if (orientation(*p[0], *p[1], *p[2], off[0], off[1], off[2]) == LEFT_TURN)
return false;
if (orientation(*p[0], *p[1], *p[3], off[0], off[1], off[3]) == RIGHT_TURN)
return false;
}
return true;
}
template<class Gt, class Tds>
void Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::flip_single_edge(Face_handle f, int i)
{
CGAL_triangulation_precondition(f != Face_handle());
CGAL_triangulation_precondition(i == 0 || i == 1 || i == 2);
CGAL_triangulation_precondition(dimension() == 2);
CGAL_triangulation_precondition(flippable(f, i));
if (f->has_zero_offsets() && f->neighbor(i)->has_zero_offsets()) {
_tds.flip(f, i);
return;
} else {
Face_handle nb = f->neighbor(i);
int nb_idx = nb->index(f);
Vertex_handle vh[] = { f->vertex(i),
f->vertex(ccw(i)),
nb->vertex(nb_idx),
f->vertex(cw(i)) };
Offset o[] = { f->offset(i),
f->offset(ccw(i)),
nb->offset(nb_idx),
f->offset(cw(i)) };
Offset no[] = { f->neighbor_offset(cw(i)),
nb->neighbor_offset(ccw(nb_idx)),
nb->neighbor_offset(cw(nb_idx)),
f->neighbor_offset(ccw(i)) };
_tds.flip(f, i);
nb = f->neighbor(ccw(i));
nb_idx = nb->index(f);
f->set_offsets();
nb->set_offsets();
f->set_offset(i, o[0]);
f->set_neighbor_face_offset(i, no[1]);
f->set_offset(ccw(i), o[1]);
f->set_neighbor_face_offset(ccw(i), Offset());
f->set_offset(cw(i), o[2]);
f->set_neighbor_face_offset(cw(i), no[0]);
nb->set_offset(nb_idx, o[3]);
nb->set_neighbor_face_offset(nb_idx, Offset());
nb->set_offset(ccw(nb_idx), o[0]);
nb->set_neighbor_face_offset(ccw(nb_idx), no[2]);
nb->set_offset(cw(nb_idx), o[2]);
nb->set_neighbor_face_offset(cw(nb_idx), no[3]);
}
}
template < class Gt, class Tds >
void
Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::
restore_Delaunay(Vertex_handle v)
{
Face_handle f = v->face();
Face_handle next;
int i;
Face_handle start(f);
do
{
i = f->index(v);
next = f->neighbor(ccw(i)); // turn ccw around v
propagating_flip(f, i);
f = next;
}
while(next != start);
}
template < class Gt, class Tds >
void
Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::
propagating_flip(Face_handle& f, int i)
{
Face_handle nb = f->neighbor(i);
if (locally_Delaunay(f, i))
return;
this->flip_single_edge(f, i);
propagating_flip(f, i);
i = nb->index(f->vertex(i));
propagating_flip(nb, i);
}
template < class Gt, class Tds >
bool
Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::
locally_Delaunay(const Face_handle &f, int nbi)
{
CGAL_BRANCH_PROFILER("locally_Delaunay(), simplicity check failures", tmp);
Face_handle nb = f->neighbor(nbi);
bool simplicity_criterion = f->has_zero_offsets() && nb->has_zero_offsets();
const Point *p[4];
for (int index = 0; index < 3; ++index)
{
p[index] = &nb->vertex(index)->point();
}
p[3] = &f->vertex(nbi)->point();
Oriented_side os;
if (simplicity_criterion)
{
// No periodic offsets
os = side_of_oriented_circle(*p[0], *p[1], *p[2], *p[3]);
}
else
{
CGAL_BRANCH_PROFILER_BRANCH(tmp);
Offset off[4];
for (int index = 0; index < 3; ++index)
{
off[index] = nb->offset(index);
}
off[3] = f->neighbor_offset(nbi);
os = side_of_oriented_circle( off[0].apply(*p[0]),
off[1].apply(*p[1]),
off[2].apply(*p[2]),
off[3].apply(*p[3]) );
}
return (ON_POSITIVE_SIDE != os);
}
template < class Gt, class Tds >
inline
typename Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::Vertex_handle
@ -174,16 +373,23 @@ Periodic_4_hyperbolic_Delaunay_triangulation_2<Gt, Tds>::
insert(const Point &p, Face_handle start)
{
typedef typename Gt::Side_of_fundamental_octagon Side_of_fundamental_octagon;
Side_of_fundamental_octagon check = Side_of_fundamental_octagon();
CGAL::Bounded_side side = check(p);
if (side != CGAL::ON_UNBOUNDED_SIDE) {
cout << "Point inserted in face " << start->get_number() << ", vertices: ";
if ( start == Face_handle() ) {
Locate_type lt;
int li;
start = this->euclidean_visibility_locate(p, lt, li);
}
cout << "Point inserted in face " << start->get_number() << ", vertices: " << endl;
for (int i = 0; i < 3; i++)
cout << start->vertex(i)->idx() << " with offset " << start->offset(i) << ", ";
cout << start->vertex(i)->idx() << " with offset " << start->offset(i) << ", " << endl;
cout << endl;
cout << "Neighbor offsets: " << start->neighbor_offset(0) << ", " << start->neighbor_offset(1) << ", " << start->neighbor_offset(2) << endl;
@ -242,7 +448,7 @@ insert(const Point &p, Face_handle start)
cout << "--------- end ----------" << endl << endl;
}
restore_Delaunay(new_vertex);
return new_vertex;
} else {

View File

@ -214,7 +214,7 @@ public:
Construct_segment_2
construct_segment_2_object() const {
return Construct_segment_2(_domain);
return Construct_segment_2(&_domain);
}
Construct_midpoint_2
@ -269,7 +269,7 @@ public:
Construct_triangle_2
construct_triangle_2_object() const {
return Construct_triangle_2();
return Construct_triangle_2(&_domain);
}
Construct_direction_2

View File

@ -34,34 +34,26 @@
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_smallint.hpp>
#include <boost/random/variate_generator.hpp>
#include <CGAL/Triangulation_utils_2.h>
#include <CGAL/triangulation_assertions.h>
#include <CGAL/utility.h>
#include <CGAL/use.h>
#include <CGAL/Triangulation_utils_2.h>
//#include <CGAL/Triangulation_data_structure_2.h>
#include <CGAL/Triangulation_2.h>
#include <CGAL/Periodic_4_hyperbolic_triangulation_ds_face_base_2.h>
#include <CGAL/Periodic_4_hyperbolic_triangulation_ds_vertex_base_2.h>
#include <CGAL/Triangulation_face_base_with_info_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Periodic_4_hyperbolic_triangulation_iterators_2.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/NT_converter.h>
#include <CGAL/Triangulation_structural_filtering_traits.h>
#include <CGAL/Hyperbolic_word_4.h>
#include <CGAl/Hyperbolic_translation_info.h>
namespace CGAL {
#ifndef CGAL_P4T2_STRUCTURAL_FILTERING_MAX_VISITED_CELLS
@ -159,15 +151,22 @@ template < class GT,
Periodic_4_hyperbolic_triangulation_ds_face_base_2<GT>
>
>
class Periodic_4_hyperbolic_triangulation_2 : public Triangulation_cw_ccw_2 {
class Periodic_4_hyperbolic_triangulation_2 : public Triangulation_2<GT, TDS> {
// friend std::istream& operator>> <>
// (std::istream& is, Periodic_4_hyperbolic_triangulation_2<GT, TDS> &tr);
typedef Periodic_4_hyperbolic_triangulation_2<GT, TDS> Self;
typedef Triangulation_cw_ccw_2 Base;
typedef Triangulation_2<GT, TDS> Base;
public:
#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
using Base::cw;
using Base::ccw;
using Base::geom_traits;
#endif
typedef GT Geometric_traits;
typedef TDS Triangulation_data_structure;
typedef unsigned short int Int;
@ -204,6 +203,8 @@ public:
//typedef typename TDS::Face_base Face_base;
typedef typename Base::Line_face_circulator Line_face_circulator;
typedef Face_iterator All_faces_iterator;
typedef Edge_iterator All_edges_iterator;
typedef Vertex_iterator All_vertices_iterator;
@ -348,87 +349,69 @@ public:
bool is_infinite(Vertex_handle v) const
{
return is_infinite(v);
return false;
}
bool is_infinite(Face_handle f) const
{
return has_infinite_vertex(f) || is_finite_invisible(f);
return false;
}
bool is_infinite(Face_handle f, int i) const
{
return has_infinite_vertex(f, i) || is_finite_invisible(f, i);
return false;
}
bool is_infinite(const Edge& e) const
{
return is_infinite(e.first, e.second);
return false;
}
bool is_infinite(const Edge_circulator& ec) const
{
return is_infinite(*ec);
return false;
}
bool is_infinite(const All_edges_iterator& ei) const
{
return is_infinite(*ei);
return false;
}
private:
bool has_infinite_vertex(Face_handle f) const
{
return is_infinite(f);
return false;
}
bool has_infinite_vertex(Face_handle f, int i) const
{
return is_infinite(f, i);
return false;
}
bool has_infinite_vertex(const Edge& e) const
{
return is_infinite(e);
return false;
}
int get_finite_invisible_edge(Face_handle f) const
{
assert(is_finite_invisible(f));
return f->info().get_invisible_edge();
{
return false;
}
bool is_finite_invisible(Face_handle f) const
{
return f->info().is_finite_invisible();
return false;
}
bool is_finite_invisible(Face_handle f, int i) const
{
if(this->dimension() <= 1) {
return false;
}
if(is_finite_invisible(f) && get_finite_invisible_edge(f) == i) {
return true;
}
// another incident face and corresponding index
Face_handle f2 = f->neighbor(i);
int i2 = f2->index(f);
if(is_finite_invisible(f2) && get_finite_invisible_edge(f2) == i2) {
return true;
}
{
return false;
}
bool is_finite_invisible(const Edge& e) const
{
return is_finite_invisible(e.first, e.second);
return false;
}
@ -553,37 +536,37 @@ public:
Periodic_triangle construct_periodic_3_triangle(const Point &p1, const Point &p2, const Point &p3) const {
return make_array( std::make_pair(p1,Offset()),
std::make_pair(p2,Offset()),
std::make_pair(p3,Offset()) );
return make_array( std::make_pair(p1,Offset()),
std::make_pair(p2,Offset()),
std::make_pair(p3,Offset()) );
}
Periodic_triangle construct_periodic_3_triangle(const Point &p1, const Point &p2, const Point &p3,
const Offset &o1, const Offset &o2, const Offset &o3) const {
return make_array( std::make_pair(p1,o1),
std::make_pair(p2,o2),
std::make_pair(p3,o3) );
return make_array( std::make_pair(p1,o1),
std::make_pair(p2,o2),
std::make_pair(p3,o3) );
}
Periodic_segment construct_periodic_3_segment(const Point &p1, const Point &p2) const {
return make_array( std::make_pair(p1,Offset()),
std::make_pair(p2,Offset()) );
std::make_pair(p2,Offset()) );
}
Periodic_segment construct_periodic_3_segment( const Point &p1, const Point &p2,
const Offset &o1, const Offset &o2) const {
return make_array( std::make_pair(p1,o1),
std::make_pair(p2,o2) );
std::make_pair(p2,o2) );
}
Triangle construct_triangle(const Point &p1, const Point &p2, const Point &p3) const {
return geom_traits().construct_triangle_3_object()(p1,p2,p3);
return geom_traits().construct_triangle_2_object()(p1,p2,p3);
}
Triangle construct_triangle(const Point &p1, const Point &p2, const Point &p3,
const Offset &o1, const Offset &o2, const Offset &o3) const {
return geom_traits().construct_triangle_3_object()(p1,p2,p3,o1,o2,o3);
return geom_traits().construct_triangle_2_object()(p1,p2,p3,o1,o2,o3);
}
Triangle construct_triangle(const Periodic_triangle& tri) {
@ -592,12 +575,12 @@ public:
}
Segment construct_segment(const Point &p1, const Point &p2) const {
return geom_traits().construct_segment_3_object()(p1, p2);
return geom_traits().construct_segment_2_object()(p1, p2);
}
Segment construct_segment( const Point &p1, const Point &p2,
const Offset &o1, const Offset &o2) const {
return geom_traits().construct_segment_3_object()(p1,p2,o1,o2);
return geom_traits().construct_segment_2_object()(p1,p2,o1,o2);
}
Segment construct_segment(const Periodic_segment& seg) const {
@ -606,7 +589,7 @@ public:
}
Point construct_point(const Point& p, const Offset &o) const {
return geom_traits().construct_point_3_object()(p,o);
return geom_traits().construct_point_2_object()(p,o);
}
Point construct_point(const Periodic_point& pp) const {
@ -619,7 +602,7 @@ public:
if (it == virtual_vertices.end()) {
// if v is not contained in virtual_vertices, then it is in the
// original domain.
return std::make_pair(v->point(), Offset(0,0,0));
return std::make_pair(v->point(), Offset());
} else {
// otherwise it has to be looked up as well as its offset.
return std::make_pair(it->second.first->point(), it->second.second);
@ -662,14 +645,32 @@ public:
pp.second);
}
Segment segment(const Face_handle & fh, int idx) const {
return construct_segment( fh->vertex(idx)->point(), fh->vertex(ccw(idx))->point(),
fh->offset(idx), fh->offset(ccw(idx)) );
}
Segment segment(const pair<Face_handle, int> & edge) {
return segment(edge.first, ccw(edge.second));
}
Segment segment(const Periodic_segment & ps) const {
return construct_segment( ps[0].first, ps[1].first,
ps[0].second, ps[1].second );
ps[0].second, ps[1].second );
}
Triangle triangle(const Face_handle & fh) const {
return construct_triangle( fh->vertex(0)->point(), fh->vertex(1)->point(), fh->vertex(2)->point(),
fh->offset(0), fh->offset(1), fh->offset(2) );
}
Triangle triangle(const Periodic_triangle & pt) const {
return construct_triangle( pt[0].first, pt[1].first, pt[2].first,
pt[0].second,pt[1].second,pt[2].second );
pt[0].second,pt[1].second,pt[2].second );
}
@ -849,7 +850,7 @@ public:
Face_handle locate( const Point & p, Locate_type & lt, int & li, int & lj,
Face_handle start = Face_handle()) const {
return periodic_locate(p, Offset(), lt, li, lj, start);
return euclidean_visibility_locate(p, lt, li, start); //periodic_locate(p, Offset(), lt, li, lj, start);
}
@ -881,6 +882,11 @@ public:
Face_handle euclidean_visibility_locate(const Point& p, Locate_type& lt, int& li, Face_handle f = Face_handle()) const;
Face_handle locate(const Point& p, Locate_type& lt, int& li, Face_handle f = Face_handle()) const {
return euclidean_visibility_locate(p, lt, li, f);
}
protected:
// COMMON INSERTION for DELAUNAY and REGULAR TRIANGULATION
template < class Conflict_tester, class Point_hider >
@ -1073,6 +1079,18 @@ public:
return _tds.adjacent_vertices(v, vertices);
}
template <class OutputIterator>
OutputIterator incident_vertices(Vertex_handle v) const {
return _tds.adjacent_vertices(v);
}
Vertex_circulator incident_vertices(Vertex_handle v) const {
return _tds.adjacent_vertices(v);
}
size_type degree(Vertex_handle v) const {
return _tds.degree(v);
}
@ -1462,7 +1480,7 @@ is_valid(bool verbose, int level) const {
if (orientation( *p[0], *p[1], *p[2],
off[0], off[1], off[2] ) != POSITIVE) {
if (verbose) {
cit->restore_orientation();
cit->reorient();
for (int i=0; i<3; i++) {
p[i] = &cit->vertex(i)->point();
off[i] = cit->offset(i);
@ -1551,6 +1569,14 @@ typename TDS::Face_handle Periodic_4_hyperbolic_triangulation_2<GT, TDS>::
euclidean_visibility_locate(const Point& p, Locate_type& lt, int& li, Face_handle f) const
{
typedef typename GT::Side_of_fundamental_octagon Side_of_fundamental_octagon;
Side_of_fundamental_octagon check = Side_of_fundamental_octagon();
CGAL::Bounded_side side = check(p);
if (side != ON_BOUNDED_SIDE) {
return Face_handle();
}
// Random generator (used to introduce a small perturbation to the choice of the starting vertex each time)
boost::rand48 rng;
boost::uniform_smallint<> three(0, 2);
@ -1571,8 +1597,9 @@ euclidean_visibility_locate(const Point& p, Locate_type& lt, int& li, Face_handl
while (true) {
Orientation o = orientation(f->vertex(curr)->point(), f->vertex(succ)->point(), p,
f->offset(curr), f->offset(succ), Offset());
if (o == NEGATIVE) {
pair< typename std::set<Face_handle>::iterator, bool> r = visited_faces.insert(f->neighbor(cw(curr)));
if (r.second) {
f = f->neighbor(cw(curr));

View File

@ -166,6 +166,15 @@ public:
}
bool has_zero_offsets() {
bool b = true;
for (int i = 0; i < 3 && b; i++) {
b = (b && o[i].is_identity());
}
return b;
}
// SETTING
void set_number(int n) {
@ -228,7 +237,7 @@ public:
V[0] = V[1] = V[2] = Vertex_handle();
}
void set_vertex(int k, Vertex_handle& vh) {
void set_vertex(int k, const Vertex_handle& vh) {
V[k] = vh;
}
@ -254,7 +263,7 @@ public:
N[2] = n2;
}
void set_neighbor(int k, Face_handle& nfh) {
void set_neighbor(int k, const Face_handle& nfh) {
N[k] = nfh;
}
@ -281,13 +290,15 @@ public:
}
void restore_orientation() {
void reorient() {
// N(eighbors), V(ertices), o(ffsets), no (neighbor offsets)
swap(N[1], N[2]);
swap(V[1], V[2]);
swap(o[1], o[2]);
swap(no[1], no[2]);
int idx0 = 0, idx1 = 1; // the indices to swap
swap( N[idx0], N[idx1]);
swap( V[idx0], V[idx1]);
swap( o[idx0], o[idx1]);
swap(no[idx0], no[idx1]);
}

View File

@ -46,7 +46,7 @@ TriangulationCircumcircle<T>::TriangulationCircumcircle(QGraphicsScene* s,
QObject* parent)
: GraphicsViewInput(parent), dt(dt_), scene_(s)
{
hint = dt->infinite_vertex();
hint = typename T::Vertex_handle();
circle = new QGraphicsEllipseItem();
circle->hide();
scene_->addItem(circle);
@ -92,15 +92,27 @@ TriangulationCircumcircle<T>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
return;
}
typename T::Point p = typename T::Point(event->scenePos().x(), event->scenePos().y());
fh = dt->locate(p, hint->face());
hint = fh->vertex(0);
if(!dt->is_infinite(fh)){
typename T::Geom_traits::Circle_2 c(fh->vertex(0)->point(),
fh->vertex(1)->point(),
fh->vertex(2)->point());
CGAL::Bbox_2 bb = c.bbox();
circle->setRect(bb.xmin(), bb.ymin(), bb.xmax()-bb.xmin(), bb.ymax()-bb.ymin());
circle->show();
if (hint == typename T::Vertex_handle())
fh = dt->locate(p);
else
fh = dt->locate(p, hint->face());
if (fh != typename T::Face_handle()) {
hint = fh->vertex(0);
if(!dt->is_infinite(fh)){
typename T::Point p0, p1, p2;
p0 = fh->offset(0).apply(fh->vertex(0)->point());
p1 = fh->offset(1).apply(fh->vertex(1)->point());
p2 = fh->offset(2).apply(fh->vertex(2)->point());
typename T::Geom_traits::Circle_2 c(p0, p1, p2);
CGAL::Bbox_2 bb = c.bbox();
circle->setRect(bb.xmin(), bb.ymin(), bb.xmax()-bb.xmin(), bb.ymax()-bb.ymin());
circle->show();
} else {
circle->hide();
}
} else {
circle->hide();
}

View File

@ -63,7 +63,7 @@ TriangulationConflictZone<T>::localize_and_insert_point(QPointF qt_point)
}
qfaces.clear();
hint = dt->locate(p, hint);
dt->find_conflicts(p, faces, hint);
//dt->find_conflicts(p, faces, hint);
for(typename std::list<Face_handle>::iterator it = faces.begin();
it != faces.end();
++it){

View File

@ -147,7 +147,7 @@ TriangulationGraphicsItem<T>::operator()(typename T::Face_handle fh)
for (int i=0; i<3; i++) {
if (fh < fh->neighbor(i) || t->is_infinite(fh->neighbor(i))){
m_painter->setPen(this->edgesPen());
painterostream << t->segment(fh,i);
painterostream << t->segment(fh, i);
}
}
}
@ -207,7 +207,7 @@ TriangulationGraphicsItem<T>::paintVertices(QPainter *painter)
it != t->finite_vertices_end();
it++){
/*
switch (it->info().getColor()) {
case 0:
painter->setPen(QPen(::Qt::red, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
@ -251,7 +251,7 @@ TriangulationGraphicsItem<T>::paintVertices(QPainter *painter)
default:
painter->setPen(QPen(::Qt::gray, 3., ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
break;
}
} */
//
@ -335,18 +335,17 @@ TriangulationGraphicsItem<T>::paint(QPainter *painter,
painter->setPen(this->edgesPen());
// painter->drawRect(boundingRect());
if ( t->dimension()<2 || option->exposedRect.contains(boundingRect()) ) {
std::cout << "Drawing all!" << std::endl;
drawAll(painter);
} else {
std::cout << "Else-ing!" << std::endl;
m_painter = painter;
painterostream = PainterOstream<Geom_traits>(painter);
/*
CGAL::apply_to_range (*t,
typename T::Point(option->exposedRect.left(),
option->exposedRect.bottom()),
typename T::Point(option->exposedRect.right(),
option->exposedRect.top()),
*this);
*this); */
}
}
@ -357,33 +356,31 @@ void
TriangulationGraphicsItem<T>::updateBoundingBox()
{
prepareGeometryChange();
if(t->number_of_vertices() == 0){
bb = Bbox_2(0,0,0,0);
bb_initialized = false;
return;
} else if(! bb_initialized){
bb = t->finite_vertices_begin()->point().bbox();
bb_initialized = true;
}
// if(t->number_of_vertices() == 0){
// bb = Bbox_2(0,0,0,0);
// bb_initialized = false;
// return;
// } else if(! bb_initialized){
// bb = t->finite_vertices_begin()->point().bbox();
// bb_initialized = true;
// }
if(t->dimension() <2){
for(typename T::Finite_vertices_iterator it = t->finite_vertices_begin();
it != t->finite_vertices_end();
++it){
bb = bb + it->point().bbox();
}
} else {
typename T::Vertex_handle inf = t->infinite_vertex();
typename T::Vertex_circulator vc = t->incident_vertices(inf), done(vc);
do {
bb = bb + vc->point().bbox();
++vc;
} while(vc != done);
}
bounding_rect = QRectF(bb.xmin(),
bb.ymin(),
bb.xmax()-bb.xmin(),
bb.ymax()-bb.ymin());
// if(t->dimension() <2){
// for(typename T::Finite_vertices_iterator it = t->finite_vertices_begin();
// it != t->finite_vertices_end();
// ++it){
// bb = bb + it->point().bbox();
// }
// } else {
// typename T::Vertex_handle inf = t->infinite_vertex();
// typedef typename T::Vertex_circulator Circ;
// Circ vc = t->incident_vertices(inf), done(vc);
// do {
// bb = bb + vc->point().bbox();
// ++vc;
// } while(vc != done);
// }
bounding_rect = QRectF(-1., -1., 2., 2.);
}

View File

@ -81,6 +81,8 @@ TriangulationMovingPoint<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
template <typename T>
void
TriangulationMovingPoint<T>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{}
/*
{
if(! movePointToInsert) return;
@ -95,11 +97,13 @@ TriangulationMovingPoint<T>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
vh = next_hint;
localize_and_insert_point(event->scenePos());
}
*/
template <typename T>
void
TriangulationMovingPoint<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{}
/*
{
if(! movePointToInsert ||
event->button() != ::Qt::LeftButton) {
@ -115,7 +119,7 @@ TriangulationMovingPoint<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
movePointToInsert = false;
}
*/
template <typename T>

View File

@ -50,34 +50,35 @@ TriangulationPointInputAndConflictZone<T>::TriangulationPointInputAndConflictZon
// TODO: Do this!
template <typename T>
void
TriangulationPointInputAndConflictZone<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
p = convert(event->scenePos());
if(dt->dimension() < 2 ||
event->modifiers() != 0 ||
event->button() != ::Qt::LeftButton) {
return;
}
// if(dt->dimension() < 2 ||
// event->modifiers() != 0 ||
// event->button() != ::Qt::LeftButton) {
// return;
// }
dt->get_conflicts(p, std::back_inserter(faces));
for(typename std::list<Face_handle>::iterator it = faces.begin();
it != faces.end();
++it){
if(! dt->is_infinite(*it)){
QGraphicsPolygonItem *item = new QGraphicsPolygonItem(convert(dt->triangle(*it)));
QColor color(::Qt::blue);
color.setAlpha(150);
item->setBrush(color);
scene_->addItem(item);
qfaces.push_back(item);
}
}
// dt->get_conflicts(p, std::back_inserter(faces));
// for(typename std::list<Face_handle>::iterator it = faces.begin(); it != faces.end(); it++) {
// if( !dt->is_infinite(*it) ){
// QGraphicsPolygonItem *item = new QGraphicsPolygonItem(convert(dt->triangle(*it)));
// QColor color(::Qt::blue);
// color.setAlpha(150);
// item->setBrush(color);
// scene_->addItem(item);
// qfaces.push_back(item);
// }
// }
}
template <typename T>
void
TriangulationPointInputAndConflictZone<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)

View File

@ -44,6 +44,8 @@ TriangulationRemoveVertex<T>::TriangulationRemoveVertex(T * dt_,
template <typename T>
void
TriangulationRemoveVertex<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
{}
/*
{
if((event->modifiers() & ::Qt::ShiftModifier)
&& (! (event->modifiers() & ::Qt::ControlModifier))){
@ -57,7 +59,7 @@ TriangulationRemoveVertex<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
emit (modelChanged());
}
}
*/
template <typename T>