Working on the P2T2 demo

This commit is contained in:
Nico Kruithof 2013-01-24 21:16:54 +01:00
parent 05f7dbc322
commit ae5565d912
6 changed files with 254 additions and 86 deletions

View File

@ -15,11 +15,13 @@
#include <QInputDialog>
// GraphicsView items and event filters (input classes)
#include "TriangulationPointInput.h"
#include "TriangulationCircumcircle.h"
#include "TriangulationMovingPoint.h"
#include "TriangulationConflictZone.h"
#include "TriangulationRemoveVertex.h"
#include "PeriodicTriangulationLocate.h"
#include "TriangulationPointInputAndConflictZone.h"
#include <CGAL/Qt/PeriodicTriangulationGraphicsItem.h>
#include <CGAL/Qt/PeriodicVoronoiGraphicsItem.h>
// for viewportsBbox
#include <CGAL/Qt/utility.h>
@ -34,12 +36,7 @@ typedef CGAL::Periodic_2_triangulation_traits_2<EPIC> K;
typedef K::Point_2 Point_2;
typedef K::Iso_rectangle_2 Iso_rectangle_2;
#define NGHK_DELAUNAY
#ifdef NGHK_DELAUNAY
typedef CGAL::Periodic_2_Delaunay_triangulation_2<K> Periodic_triangulation;
#else
typedef CGAL::Periodic_2_triangulation_2<K> Periodic_triangulation;
#endif
typedef CGAL::Periodic_2_Delaunay_triangulation_2<K> Periodic_DT;
class MainWindow :
public CGAL::Qt::DemosMainWindow,
@ -48,15 +45,17 @@ class MainWindow :
Q_OBJECT
private:
Periodic_triangulation triang;
Periodic_DT triang;
QGraphicsScene scene;
CGAL::Qt::PeriodicTriangulationGraphicsItem<Periodic_triangulation> * pt_gi;
CGAL::Qt::PeriodicTriangulationGraphicsItem<Periodic_DT> * pt_gi;
CGAL::Qt::PeriodicTriangulationVoronoiGraphicsItem<Periodic_DT> * vgi;
CGAL::Qt::TriangulationMovingPoint<Periodic_triangulation> * pt_mp;
CGAL::Qt::TriangulationRemoveVertex<Periodic_triangulation> * trv;
CGAL::Qt::TriangulationPointInput<Periodic_triangulation> * pt_pi;
CGAL::Qt::PeriodicTriangulationLocate<Periodic_triangulation> * pt_l;
CGAL::Qt::TriangulationMovingPoint<Periodic_DT> * pt_mp;
CGAL::Qt::TriangulationConflictZone<Periodic_DT> * pt_cz;
CGAL::Qt::TriangulationRemoveVertex<Periodic_DT> * pt_rv;
CGAL::Qt::TriangulationPointInputAndConflictZone<Periodic_DT> * pt_pi;
CGAL::Qt::TriangulationCircumcircle<Periodic_DT> *pt_cc;
public:
MainWindow();
@ -66,12 +65,17 @@ public slots:
void on_actionMovingPoint_toggled(bool checked);
void on_actionShowDelaunay_toggled(bool checked);
void on_actionInsertPoint_toggled(bool checked);
void on_actionShowConflictZone_toggled(bool checked);
void on_actionCircumcenter_toggled(bool checked);
void on_actionShowDelaunay_toggled(bool checked);
void on_actionShowVoronoi_toggled(bool checked);
void on_actionInsertPoint_toggled(bool checked);
void on_actionInsertRandomPoints_triggered();
void on_actionConvertTo9Cover_triggered();
@ -86,7 +90,7 @@ public slots:
void on_actionRecenter_triggered();
void open(const QString& fileName);
virtual void open(QString fileName);
signals:
void changed();
@ -98,8 +102,10 @@ MainWindow::MainWindow()
{
setupUi(this);
this->graphicsView->setAcceptDrops(false);
// Add a GraphicItem for the Periodic triangulation
pt_gi = new CGAL::Qt::PeriodicTriangulationGraphicsItem<Periodic_triangulation>(&triang);
pt_gi = new CGAL::Qt::PeriodicTriangulationGraphicsItem<Periodic_DT>(&triang);
QObject::connect(this, SIGNAL(changed()),
pt_gi, SLOT(modelChanged()));
@ -107,26 +113,38 @@ MainWindow::MainWindow()
pt_gi->setVerticesPen(QPen(Qt::red, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
scene.addItem(pt_gi);
// Add a GraphicItem for the Voronoi diagram
vgi = new CGAL::Qt::PeriodicTriangulationVoronoiGraphicsItem<Periodic_DT>(&triang);
QObject::connect(this, SIGNAL(changed()),
vgi, SLOT(modelChanged()));
vgi->setEdgesPen(QPen(Qt::blue, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
scene.addItem(vgi);
vgi->hide();
// 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
pt_pi = new CGAL::Qt::TriangulationPointInput<Periodic_triangulation>(&scene, &triang, this );
pt_pi = new CGAL::Qt::TriangulationPointInputAndConflictZone<Periodic_DT>(&scene, &triang, this );
QObject::connect(pt_pi, SIGNAL(generate(CGAL::Object)),
this, SLOT(processInput(CGAL::Object)));
pt_mp = new CGAL::Qt::TriangulationMovingPoint<Periodic_triangulation>(&triang, this);
// TriangulationMovingPoint<Periodic_triangulation> emits a modelChanged() signal each
pt_mp = new CGAL::Qt::TriangulationMovingPoint<Periodic_DT>(&triang, this);
// TriangulationMovingPoint<Periodic_DT> emits a modelChanged() signal each
// time the moving point moves.
// The following connection is for the purpose of emitting changed().
QObject::connect(pt_mp, SIGNAL(modelChanged()),
this, SIGNAL(changed()));
trv = new CGAL::Qt::TriangulationRemoveVertex<Periodic_triangulation>(&triang, this);
QObject::connect(trv, SIGNAL(modelChanged()),
pt_rv = new CGAL::Qt::TriangulationRemoveVertex<Periodic_DT>(&triang, this);
QObject::connect(pt_rv, SIGNAL(modelChanged()),
this, SIGNAL(changed()));
pt_l = new CGAL::Qt::PeriodicTriangulationLocate<Periodic_triangulation>(&scene, &triang, this);
pt_cc = new CGAL::Qt::TriangulationCircumcircle<Periodic_DT>(&scene, &triang, this);
QObject::connect(pt_cc, SIGNAL(modelChanged()),
this, SIGNAL(changed()));
//
// Manual handling of actions
@ -139,6 +157,7 @@ MainWindow::MainWindow()
QActionGroup* ag = new QActionGroup(this);
ag->addAction(this->actionInsertPoint);
ag->addAction(this->actionMovingPoint);
ag->addAction(this->actionCircumcenter);
ag->addAction(this->actionShowConflictZone);
// Check two actions
@ -163,6 +182,7 @@ MainWindow::MainWindow()
this->setupStatusBar();
this->setupOptionsMenu();
this->addAboutDemo(":/cgal/help/about_Periodic_2_triangulation_2.html");
this->addAboutCGAL();
this->addRecentFiles(this->menuFile, this->actionQuit);
connect(this, SIGNAL(openRecentFile(QString)),
@ -193,7 +213,7 @@ MainWindow::processInput(CGAL::Object o)
/*
* Qt Automatic Connections
* http://doc.trolltech.com/4.4/designer-using-a-copt_mponent.html#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>"
@ -203,10 +223,10 @@ MainWindow::on_actionInsertPoint_toggled(bool checked)
{
if(checked){
scene.installEventFilter(pt_pi);
scene.installEventFilter(trv);
scene.installEventFilter(pt_rv);
} else {
scene.removeEventFilter(pt_pi);
scene.removeEventFilter(trv);
scene.removeEventFilter(pt_rv);
}
}
@ -214,9 +234,9 @@ void
MainWindow::on_actionShowConflictZone_toggled(bool checked)
{
if(checked) {
scene.installEventFilter(pt_l);
scene.installEventFilter(pt_cc);
} else {
scene.removeEventFilter(pt_l);
scene.removeEventFilter(pt_cc);
}
}
@ -232,12 +252,30 @@ MainWindow::on_actionMovingPoint_toggled(bool checked)
}
}
void
MainWindow::on_actionCircumcenter_toggled(bool checked)
{
if(checked){
scene.installEventFilter(pt_cc);
pt_cc->show();
} else {
scene.removeEventFilter(pt_cc);
pt_cc->hide();
}
}
void
MainWindow::on_actionShowDelaunay_toggled(bool checked)
{
pt_gi->setVisibleEdges(checked);
}
void
MainWindow::on_actionShowVoronoi_toggled(bool checked)
{
vgi->setVisible(checked);
}
void
MainWindow::on_actionClear_triggered()
@ -313,7 +351,7 @@ MainWindow::on_actionLoadPoints_triggered()
void
MainWindow::open(const QString& fileName)
MainWindow::open(QString fileName)
{
// wait cursor
QApplication::setOverrideCursor(Qt::WaitCursor);
@ -342,7 +380,7 @@ MainWindow::on_actionSavePoints_triggered()
".");
if(! fileName.isEmpty()){
std::ofstream ofs(qPrintable(fileName));
for(Periodic_triangulation::Vertex_iterator
for(Periodic_DT::Vertex_iterator
vit = triang.vertices_begin(),
end = triang.vertices_end();
vit!= end; ++vit)
@ -362,6 +400,7 @@ MainWindow::on_actionRecenter_triggered()
#include "Periodic_2_triangulation_2.moc"
#include <CGAL/Qt/resources.h>
int main(int argc, char **argv)
{
@ -369,26 +408,18 @@ int main(int argc, char **argv)
app.setOrganizationDomain("www.nghk.nl");
app.setOrganizationName("Nico Kruithof");
app.setApplicationName("Periodic_2_triangulation_2 demo");
app.setApplicationName("Periodic_2_Delaunay_triangulation_2 demo");
// Ipt_mport resources from libCGALQt4.
// Import resources from libCGALQt4.
// See http://doc.trolltech.com/4.4/qdir.html#Q_INIT_RESOURCE
Q_INIT_RESOURCE(File);
Q_INIT_RESOURCE(Periodic_2_triangulation_2);
Q_INIT_RESOURCE(Input);
Q_INIT_RESOURCE(CGAL);
CGAL_QT4_INIT_RESOURCES;
MainWindow mainWindow;
mainWindow.show();
try {
return app.exec();
}
catch (char const *str) {
std::cerr << "EXCEPTION: " << str << std::endl;
return -1;
}
catch (...) {
std::cerr << "Unknown exception!" << std::endl;
return -1;
QStringList args = app.arguments();
args.removeAt(0);
Q_FOREACH(QString filename, args) {
mainWindow.open(filename);
}
return app.exec();
}

View File

@ -40,62 +40,67 @@ private:
};
template <typename T>
TriangulationCircumcircle<T>::TriangulationCircumcircle(QGraphicsScene* s,
T * dt_,
QObject* parent)
template <typename DT>
TriangulationCircumcircle<DT>::TriangulationCircumcircle(QGraphicsScene* s,
DT * dt_,
QObject* parent)
: GraphicsViewInput(parent), dt(dt_), scene_(s)
{
hint = dt->infinite_vertex();
hint = typename DT::Vertex_handle();
circle = new QGraphicsEllipseItem();
circle->hide();
scene_->addItem(circle);
}
template <typename T>
TriangulationCircumcircle<T>::~TriangulationCircumcircle()
template <typename DT>
TriangulationCircumcircle<DT>::~TriangulationCircumcircle()
{
}
template <typename T>
template <typename DT>
void
TriangulationCircumcircle<T>::setPen(const QPen& pen)
TriangulationCircumcircle<DT>::setPen(const QPen& pen)
{
circle->setPen(pen);
}
template <typename T>
template <typename DT>
void
TriangulationCircumcircle<T>::show()
TriangulationCircumcircle<DT>::show()
{
circle->show();
}
template <typename T>
template <typename DT>
void
TriangulationCircumcircle<T>::hide()
TriangulationCircumcircle<DT>::hide()
{
circle->hide();
}
template <typename T>
template <typename DT>
void
TriangulationCircumcircle<T>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
TriangulationCircumcircle<DT>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if(dt->dimension() != 2){
circle->hide();
return;
}
typename T::Point p = typename T::Point(event->scenePos().x(), event->scenePos().y());
typename DT::Point p = typename DT::Point(event->scenePos().x(), event->scenePos().y());
double dx = dt->domain().xmax() - dt->domain().xmin();
double dy = dt->domain().ymax() - dt->domain().ymin();
p = typename DT::Point(p.x()- std::floor(p.x()/dx), p.y()- std::floor(p.y()/dy));
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(),
typename DT::Geom_traits::Circle_2 c(fh->vertex(0)->point(),
fh->vertex(1)->point(),
fh->vertex(2)->point());
CGAL::Bbox_2 bb = c.bbox();
@ -107,9 +112,9 @@ TriangulationCircumcircle<T>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
}
template <typename T>
template <typename DT>
bool
TriangulationCircumcircle<T>::eventFilter(QObject *obj, QEvent *event)
TriangulationCircumcircle<DT>::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::GraphicsSceneMouseMove) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);

View File

@ -1,6 +1,6 @@
#ifndef CGAL_QT_PERIODIC_TRIANGULATION_LOCATE
#define CGAL_QT_PERIODIC_TRIANGULATION_LOCATE
#ifndef CGAL_QT_PERIODIC_TRIANGULATION_CONFLICT_ZONE
#define CGAL_QT_PERIODIC_TRIANGULATION_CONFLICT_ZONE
#include <CGAL/Qt/GraphicsViewInput.h>
#include <CGAL/Qt/Converter.h>
@ -14,7 +14,7 @@ namespace CGAL {
namespace Qt {
template <typename PT>
class PeriodicTriangulationLocate : public GraphicsViewInput
class TriangulationConflictZone : public GraphicsViewInput
{
public:
typedef PT Periodic_triangulation;
@ -26,7 +26,7 @@ public:
typedef typename PT::Geom_traits::Vector_2 Vector;
typedef typename PT::Triangle Triangle;
PeriodicTriangulationLocate(QGraphicsScene* s, PT * tr_, QObject* parent);
TriangulationConflictZone(QGraphicsScene* s, PT * tr_, QObject* parent);
protected:
@ -44,7 +44,7 @@ protected:
template <typename T>
PeriodicTriangulationLocate<T>::PeriodicTriangulationLocate(QGraphicsScene* s,
TriangulationConflictZone<T>::TriangulationConflictZone(QGraphicsScene* s,
T * tr_,
QObject* parent)
: GraphicsViewInput(parent), m_tr(tr_), m_containing_face(Face_handle()), m_scene(s), m_triangle(NULL)
@ -54,13 +54,13 @@ PeriodicTriangulationLocate<T>::PeriodicTriangulationLocate(QGraphicsScene* s,
template <typename T>
void
PeriodicTriangulationLocate<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
TriangulationConflictZone<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
}
template <typename T>
void
PeriodicTriangulationLocate<T>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
TriangulationConflictZone<T>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (m_triangle) {
m_scene->removeItem(m_triangle);
@ -90,7 +90,7 @@ PeriodicTriangulationLocate<T>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
template <typename T>
void
PeriodicTriangulationLocate<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
TriangulationConflictZone<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
}
@ -98,7 +98,7 @@ PeriodicTriangulationLocate<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent *even
template <typename T>
bool
PeriodicTriangulationLocate<T>::eventFilter(QObject *obj, QEvent *event)
TriangulationConflictZone<T>::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::GraphicsSceneMousePress) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
@ -122,4 +122,4 @@ PeriodicTriangulationLocate<T>::eventFilter(QObject *obj, QEvent *event)
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_PERIODIC_TRIANGULATION_LOCATE
#endif // CGAL_QT_PERIODIC_TRIANGULATION_CONFLICT_ZONE

View File

@ -3,6 +3,7 @@
#define CGAL_QT_TRIANGULATION_MOVING_POINT
#include <CGAL/Qt/GraphicsViewInput.h>
#include <CGAL/Qt/Converter.h>
#include <QGraphicsSceneMouseEvent>
#include <QEvent>
#include <list>

View File

@ -1,6 +1,6 @@
#ifndef CGAL_QT_TRIANGULATION_POINT_INPUT
#define CGAL_QT_TRIANGULATION_POINT_INPUT
#ifndef CGAL_QT_TRIANGULATION_POINT_INPUT_AND_CONFLICT_ZONE
#define CGAL_QT_TRIANGULATION_POINT_INPUT_AND_CONFLICT_ZONE
#include <CGAL/Qt/GraphicsViewInput.h>
#include <CGAL/Qt/Converter.h>
@ -14,14 +14,14 @@ namespace CGAL {
namespace Qt {
template <typename PT>
class TriangulationPointInput : public GraphicsViewInput
class TriangulationPointInputAndConflictZone : public GraphicsViewInput
{
public:
typedef typename PT::Geom_traits K;
typedef typename PT::Face_handle Face_handle;
typedef typename PT::Point Point;
TriangulationPointInput(QGraphicsScene* s, PT * dt_, QObject* parent);
TriangulationPointInputAndConflictZone(QGraphicsScene* s, PT * dt_, QObject* parent);
protected:
void localize_and_insert_point(QPointF qt_point);
@ -41,7 +41,7 @@ protected:
template <typename T>
TriangulationPointInput<T>::TriangulationPointInput(QGraphicsScene* s,
TriangulationPointInputAndConflictZone<T>::TriangulationPointInputAndConflictZone(QGraphicsScene* s,
T * dt_,
QObject* parent)
: GraphicsViewInput(parent), dt(dt_), scene_(s)
@ -52,7 +52,7 @@ TriangulationPointInput<T>::TriangulationPointInput(QGraphicsScene* s,
template <typename T>
void
TriangulationPointInput<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
TriangulationPointInputAndConflictZone<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
p = convert(event->scenePos());
@ -62,7 +62,7 @@ TriangulationPointInput<T>::mousePressEvent(QGraphicsSceneMouseEvent *event)
template <typename T>
void
TriangulationPointInput<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
TriangulationPointInputAndConflictZone<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (!(event->modifiers() & ::Qt::ShiftModifier)) {
emit (generate(CGAL::make_object(p)));
@ -73,7 +73,7 @@ TriangulationPointInput<T>::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
template <typename T>
bool
TriangulationPointInput<T>::eventFilter(QObject *obj, QEvent *event)
TriangulationPointInputAndConflictZone<T>::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::GraphicsSceneMousePress) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
@ -93,4 +93,4 @@ TriangulationPointInput<T>::eventFilter(QObject *obj, QEvent *event)
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_TRIANGULATION)POINT_INPUT
#endif // CGAL_QT_TRIANGULATION_POINT_INPUT_AND_CONFLICT_ZONE

View File

@ -0,0 +1,131 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
// Nico Kruithof <Nico@nghk.nl>
#ifndef CGAL_QT_PERIODIC_VORONOI_GRAPHICS_ITEM_H
#define CGAL_QT_PERIODIC_VORONOI_GRAPHICS_ITEM_H
#include <CGAL/Qt/GraphicsItem.h>
#include <CGAL/Qt/PainterOstream.h>
#include <CGAL/Qt/utility.h>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QStyleOption>
#include <CGAL/intersection_2.h>
class QGraphicsSceneMouseEvent;
namespace CGAL {
namespace Qt {
template <typename DT>
class PeriodicTriangulationVoronoiGraphicsItem : public GraphicsItem
{
public:
PeriodicTriangulationVoronoiGraphicsItem(DT * dt_);
QRectF
boundingRect() const;
void
paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void
modelChanged();
const QPen& edgesPen() const
{
return edges_pen;
}
void setEdgesPen(const QPen& pen)
{
edges_pen = pen;
}
private:
DT * dt;
QPen edges_pen;
};
template <typename DT>
PeriodicTriangulationVoronoiGraphicsItem<DT>::PeriodicTriangulationVoronoiGraphicsItem(DT * dt_)
: dt(dt_)
{
setZValue(3);
}
template <typename DT>
QRectF
PeriodicTriangulationVoronoiGraphicsItem<DT>::boundingRect() const
{
QRectF rect = CGAL::Qt::viewportsBbox(scene());
return rect;
}
template <typename DT>
void
PeriodicTriangulationVoronoiGraphicsItem<DT>::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * /*w*/)
{
QRectF rect = option->exposedRect;
PainterOstream<typename DT::Geom_traits> pos(painter, rect);
painter->setPen(edgesPen());
// TODO(NGHK): Not yet implement
// for(typename DT::Finite_edges_iterator eit = dt->finite_edges_begin();
// eit != dt->finite_edges_end();
// eit++){
// CGAL::Object o = dt->dual(eit);
// typename DT::Segment s;
// typename DT::Geom_traits::Ray_2 r;
// typename DT::Geom_traits::Line_2 l;
// if(CGAL::assign(s,o)){
// pos << s;
// } else if(CGAL::assign(r,o)) {
// pos << r;
// }else if(CGAL::assign(l,o)) {
// pos << l;
// }
// }
}
template <typename T>
void
PeriodicTriangulationVoronoiGraphicsItem<T>::modelChanged()
{
update();
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_PERIODIC_VORONOI_GRAPHICS_ITEM_H