From 0e192bd07e2f97499f8fd0440007181fbf4e44a3 Mon Sep 17 00:00:00 2001 From: Fernando Cacciola Date: Mon, 28 Sep 2009 16:20:14 +0000 Subject: [PATCH] Updates to Boolean_operations_2 Qt4 demo (entering beziers) --- .../boolean_operations_2.cpp | 20 +- .../CGAL/Qt/GraphicsViewBezierBoundaryInput.h | 441 ------------- .../CGAL/Qt/GraphicsViewBezierRegionInput.h | 606 +++++++++++++----- 3 files changed, 467 insertions(+), 600 deletions(-) diff --git a/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/boolean_operations_2.cpp b/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/boolean_operations_2.cpp index c0acbb3fb71..ed53fd7dac3 100644 --- a/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/boolean_operations_2.cpp +++ b/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/boolean_operations_2.cpp @@ -82,7 +82,7 @@ void trace( std::string s ) #include #include -#include +#include #include #include #include @@ -438,11 +438,11 @@ class MainWindow : private: - QGraphicsScene mScene; - bool mCircular_active ; - bool mBlue_active ; - Curve_set_vector mCurve_sets ; - CGAL::Qt::GraphicsViewBezierBoundaryInput* mBezierInput ; + QGraphicsScene mScene; + bool mCircular_active ; + bool mBlue_active ; + Curve_set_vector mCurve_sets ; + CGAL::Qt::GraphicsViewBezierRegionInput* mBezierInput ; public: @@ -591,7 +591,7 @@ MainWindow::MainWindow() this->addRecentFiles(this->menuFile, this->actionQuit); - mBezierInput = new CGAL::Qt::GraphicsViewBezierBoundaryInput(this, &mScene); + mBezierInput = new CGAL::Qt::GraphicsViewBezierRegionInput(this, &mScene); QObject::connect(mBezierInput, SIGNAL(generate(CGAL::Object)), this, SLOT(processInput(CGAL::Object))); @@ -998,11 +998,11 @@ void MainWindow::on_actionInsertPWH_toggled(bool aChecked) void MainWindow::processInput(CGAL::Object o ) { - Bezier_polygon lBP ; - if(CGAL::assign(lBP, o)) + Bezier_polygon_with_holes lBPWH ; + if(CGAL::assign(lBPWH, o)) { if ( ensure_bezier_mode() ) - active_set().bezier().join( lBP ) ; + active_set().bezier().join( lBPWH ) ; } modelChanged(); } diff --git a/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/include/CGAL/Qt/GraphicsViewBezierBoundaryInput.h b/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/include/CGAL/Qt/GraphicsViewBezierBoundaryInput.h index af2879e93c6..e69de29bb2d 100644 --- a/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/include/CGAL/Qt/GraphicsViewBezierBoundaryInput.h +++ b/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/include/CGAL/Qt/GraphicsViewBezierBoundaryInput.h @@ -1,441 +0,0 @@ -// Copyright (c) 2009 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you may redistribute it under -// the terms of the Q Public License version 1.0. -// See the file LICENSE.QPL distributed with CGAL. -// -// 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) : Fernando Cacciola -// - -#ifndef CGAL_QT_GRAPHICS_VIEW_BEZIER_BOUNDARY_INPUT_H -#define CGAL_QT_GRAPHICS_VIEW_BEZIER_BOUNDARY_INPUT_H - -#include - -#include -#include -#include - -#include -#include -#include - -namespace CGAL { - -namespace Qt { - - template - class GraphicsViewBezierBoundaryInput : public GraphicsViewInput - { - public: - - typedef Traits_ Traits ; - - typedef CGAL::Gps_traits_2 Bezier_gps_traits; - - typedef typename Traits::Curve_2 Curve; - typedef typename Traits::X_monotone_curve_2 X_monotone_curve; - typedef typename Bezier_gps_traits::General_polygon_2 Bezier_Boundary; - typedef typename Traits::Rat_kernel::Vector_2 Vector ; - typedef typename Traits::Rat_kernel::Point_2 Point ; - - typedef std::vector Curve_vector ; - - struct Boundary - { - Boundary() : mIsClosed(false) {} - - Curve_vector mPieces ; - bool mIsClosed ; - } ; - - typedef boost::shared_ptr Boundary_ptr ; - - typedef std::vector Boundary_vector ; - - typedef typename Curve_vector::const_iterator const_curve_terator ; - - typedef Bezier_boundary_pieces_graphics_item GI ; - - GraphicsViewBezierBoundaryInput(QObject* aParent, QGraphicsScene* aScene) - : - GraphicsViewInput( aParent ) - , mScene ( aScene ) - , mState ( Start ) - , mBoundaryPen ( QColor(0,255,0) ) - , mOngoingCurvePen ( QColor(255,0,0) ) - , mHandlePen ( QColor(0,0,255) ) - , mCurrBoundary ( new Boundary() ) - , mCurrBoundaryGI ( 0 ) - { - mOngoingPieceGI = new GI(&mOngoingPieceCtr) ; - mHandle0GI = new QGraphicsLineItem(); - mHandle1GI = new QGraphicsLineItem(); - - mOngoingPieceGI->setPen(mOngoingCurvePen); - mHandle0GI ->setPen(mHandlePen); - mHandle1GI ->setPen(mHandlePen); - - mHandle0GI->setLine(0,0,1,1); - mHandle1GI->setLine(0,0,1,1); - mHandle0GI->hide(); - mHandle1GI->hide(); - - mScene->addItem(mOngoingPieceGI); - mScene->addItem(mHandle0GI); - mScene->addItem(mHandle1GI); - - SetupCurrBoundary(); - } - - ~GraphicsViewBezierBoundaryInput() - { - //mScene->removeItem(mGI); - //delete mGI ; - //RemoveHandleItems(); - } - - bool eventFilter(QObject *obj, QEvent *aEvent) - { - bool rHandled = false ; - - if (aEvent->type() == QEvent::GraphicsSceneMousePress) - { - rHandled = mousePressEvent( static_cast(aEvent) ) ; - } - else if (aEvent->type() == QEvent::GraphicsSceneMouseRelease) - { - rHandled = mouseReleaseEvent( static_cast(aEvent) ) ; - } - else if (aEvent->type() == QEvent::GraphicsSceneMouseMove) - { - rHandled = mouseMoveEvent( static_cast(aEvent) ) ; - } - else if (aEvent->type() == QEvent::KeyPress) - { - rHandled = keyPressEvent( static_cast(aEvent) ) ; - } - - if ( !rHandled ) - rHandled = QObject::eventFilter(obj, aEvent); - - return rHandled ; - } - - protected: - - enum State { Start, PieceOrHandleStarted, PieceOngoing, HandleOngoing, PieceEnded, CurveEnded } ; - - Point cvt ( QPointF const& aP ) const { return Point(aP.x(),aP.y()) ; } - - bool mousePressEvent(QGraphicsSceneMouseEvent *aEvent) - { - bool rHandled = false ; - - Point lP = cvt(aEvent->scenePos()); - - if ( aEvent->button() == ::Qt::LeftButton ) - { - switch (mState) - { - case Start: - mP0 = lP; - mState = PieceOrHandleStarted; - rHandled = true; - break; - - case PieceOngoing: - mP1 = lP; - mState = HandleOngoing; - rHandled = true; - break; - } - } - - return rHandled ; - } - - bool mouseReleaseEvent(QGraphicsSceneMouseEvent *aEvent) - { - bool rHandled = false ; - - Point lP = cvt(aEvent->scenePos()); - - if ( aEvent->button() == ::Qt::LeftButton ) - { - switch (mState) - { - case PieceOrHandleStarted: - mState = PieceOngoing; - rHandled = true; - break; - - case HandleOngoing: - UpdateHandles(lP); - CommitOngoingPiece(lP); - mState = PieceEnded; - rHandled = true; - break; - } - } - else if ( aEvent->button() == ::Qt::RightButton ) - { - switch (mState) - { - case PieceOngoing: - CommitCurrBoundary(); - mState = Start ; - rHandled = true; - break; - } - } - - return rHandled ; - } - - bool mouseMoveEvent(QGraphicsSceneMouseEvent *aEvent) - { - bool rHandled = false ; - - Point lP = cvt(aEvent->scenePos()); - - switch (mState) - { - case PieceOngoing: - mP1 = lP; - UpdateOngoingPiece(); - rHandled = true ; - break; - - case HandleOngoing: - - UpdateHandles(lP); - UpdateOngoingPiece(); - rHandled = true ; - break; - - case PieceEnded: - mState = PieceOngoing; - rHandled = true; - break; - } - - return rHandled ; - } - - bool keyPressEvent(QKeyEvent *aEvent) - { - bool rHandled = false ; - - if (aEvent->text() == "c" ) - { - CloseCurrBundary(); - CommitCurrBoundary(); - mState = Start ; - rHandled = true; - } - - return rHandled ; - } - - - virtual void generate_boundary() - { -/* - Traits traits ; - Traits::Make_x_monotone_2 make_x_monotone = traits.make_x_monotone_2_object(); - - std::vector xcvs; - - for ( const_curve_terator it = mCurrBdryPieces.begin() ; it != mCurrBdryPieces.end() ; ++ it ) - { - std::vector x_objs; - std::vector::const_iterator xoit; - - make_x_monotone ( *it, std::back_inserter (x_objs)); - - for (xoit = x_objs.begin(); xoit != x_objs.end(); ++xoit) - { - X_monotone_curve xcv; - if (CGAL::assign (xcv, *xoit)) - xcvs.push_back (xcv); - } - } - emit(generate(CGAL::make_object( Boundary(xcvs.begin(), xcvs.begin()) ))); -*/ - } - - private: - - Curve const* ongoing_piece() const { return mOngoingPieceCtr.size() == 1 ? &mOngoingPieceCtr[0] : NULL ; } - - void HideHandles() - { - mHandle0GI->hide(); - mHandle1GI->hide(); - } - - Curve CreatePiece() - { - if ( mPrevH0 && mH1 && *mPrevH0 != *mH1 && *mPrevH0 != mP0 && *mH1 != mP1 ) - { - Point lControlPoints[4] = { mP0 - , *mPrevH0 - , *mH1 - , mP1 - } ; - return Curve( lControlPoints, lControlPoints + 4 ) ; - } - else if ( mPrevH0 && !mH1 && *mPrevH0 != mP0 && *mPrevH0 != mP1 ) - { - Point lControlPoints[3] = { mP0 - , *mPrevH0 - , mP1 - } ; - return Curve( lControlPoints, lControlPoints + 3 ) ; - } - else if ( !mPrevH0 && mH1 && *mH1 != mP0 && *mH1 != mP1 ) - { - Point lControlPoints[3] = { mP0 - , *mH1 - , mP1 - } ; - return Curve( lControlPoints, lControlPoints + 3 ) ; - } - else - { - Point lControlPoints[2] = { mP0 - , mP1 - } ; - return Curve( lControlPoints, lControlPoints + 2 ) ; - } - } - - void UpdateOngoingPiece() - { - if ( mOngoingPieceCtr.size() > 0 ) - mOngoingPieceCtr.clear(); - mOngoingPieceCtr.push_back(CreatePiece()); - mOngoingPieceGI->modelChanged(); - } - - void CommitOngoingPiece( Point const& aP ) - { - mCurrBoundary->mPieces.push_back( *ongoing_piece() ) ; - mCurrBoundaryGI->modelChanged(); - mOngoingPieceCtr.clear(); - mOngoingPieceGI->modelChanged(); - mP0 = mP1 ; - mP1 = aP ; - mPrevH0 = mH0 ; - mH0 = mH1 = boost::optional(); - } - - void UpdateHandles(Point const& aP) - { - if ( squared_distance(mP1,aP) >= 9 ) - { - if ( ongoing_piece() ) - { - mH0 = aP ; - mH1 = mP1 - (aP - mP1); - - mHandle0GI->setLine( to_double(mP1.x()), to_double(mP1.y()), to_double(mH0->x()), to_double(mH0->y())); - mHandle1GI->setLine( to_double(mP1.x()), to_double(mP1.y()), to_double(mH1->x()), to_double(mH1->y())); - mHandle0GI->show(); - mHandle1GI->show(); - } - } - else - { - HideHandles(); - mH0 = mH1 = boost::optional(); - } - - } - - void CloseCurrBundary() - { - if ( mCurrBoundary->mPieces.size() > 0 && ongoing_piece()!= NULL ) - { - std::vector lControlPoints(ongoing_piece()->control_points_begin(),ongoing_piece()->control_points_end()); - - lControlPoints.back() = mCurrBoundary->mPieces.front().control_point(0); - - mCurrBoundary->mPieces.push_back( Curve( lControlPoints.begin(), lControlPoints.end() ) ) ; - - mCurrBoundary->mIsClosed = true ; - } - } - - void CommitCurrBoundary() - { - mOngoingPieceCtr.clear(); - mOngoingPieceGI->modelChanged(); - - if ( mCurrBoundary->mPieces.size() > 0 ) - { - mComittedBoundaries.push_back(mCurrBoundary) ; - - mCommittedBoundariesGI.push_back(mCurrBoundaryGI); - } - - SetupCurrBoundary(); - - HideHandles(); - } - - void SetupCurrBoundary() - { - mCurrBoundary = Boundary_ptr( new Boundary() ) ; - - mCurrBoundaryGI = new GI(&mCurrBoundary->mPieces) ; - - mCurrBoundaryGI->setPen(mBoundaryPen); - - mScene->addItem(mCurrBoundaryGI); - } - - private: - - QGraphicsScene* mScene ; - std::vector mCommittedBoundariesGI ; - GI* mCurrBoundaryGI ; - GI* mOngoingPieceGI ; - QGraphicsLineItem* mHandle0GI ; - QGraphicsLineItem* mHandle1GI ; - - QPen mBoundaryPen ; - QPen mOngoingCurvePen ; - QPen mHandlePen ; - - Boundary_vector mComittedBoundaries ; - Boundary_ptr mCurrBoundary ; - Curve_vector mOngoingPieceCtr ; - - int mState; - - Point mP0; - Point mP1; - - boost::optional mPrevH0; - boost::optional mH0; - boost::optional mH1; - - }; // end class GraphicsViewBezierBoundaryInput - -} // namespace Qt -} // namespace CGAL - -#endif // CGAL_QT_GRAPHICS_VIEW_BEZIER_BOUNDARY_INPUT_H diff --git a/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/include/CGAL/Qt/GraphicsViewBezierRegionInput.h b/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/include/CGAL/Qt/GraphicsViewBezierRegionInput.h index eac7d3a96c7..6751d0e82b3 100644 --- a/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/include/CGAL/Qt/GraphicsViewBezierRegionInput.h +++ b/Boolean_set_operations_2/demo/Boolean_set_operations_2_GraphicsView/include/CGAL/Qt/GraphicsViewBezierRegionInput.h @@ -16,184 +16,492 @@ // // // Author(s) : Fernando Cacciola +// #ifndef CGAL_QT_GRAPHICS_VIEW_BEZIER_REGION_INPUT_H #define CGAL_QT_GRAPHICS_VIEW_BEZIER_REGION_INPUT_H -#include +#include -#include -#include -#include -#include +#include +#include +#include -#include #include -#include -#include +#include +#include namespace CGAL { - namespace Qt { +namespace Qt { - template - class GraphicsViewBezierRegionInput : public GraphicsViewInput + template + class GraphicsViewBezierRegionInput : public GraphicsViewInput + { + public: + + typedef Traits_ Traits ; + + typedef CGAL::Gps_traits_2 Bezier_gps_traits; + + typedef typename Traits::Curve_2 Curve; + typedef typename Traits::X_monotone_curve_2 Output_X_monotone_curve; + typedef typename Bezier_gps_traits::General_polygon_2 Output_boundary; + typedef typename Bezier_gps_traits::General_polygon_with_holes_2 Output_region; + typedef typename Traits::Rat_kernel::Vector_2 Vector ; + typedef typename Traits::Rat_kernel::Point_2 Point ; + + typedef std::vector Curve_vector ; + + struct Boundary { - public: - - typedef Traits_ Traits ; + Boundary() : mIsClosed(false) {} - typedef CGAL::Gps_traits_2 Bezier_gps_traits; + Curve_vector mPieces ; + bool mIsClosed ; + } ; + + typedef boost::shared_ptr Boundary_ptr ; + + typedef std::vector Boundary_vector ; + + typedef typename Curve_vector::const_iterator const_curve_terator ; + typedef typename Boundary_vector::const_iterator const_boundary_terator ; + + typedef Bezier_boundary_pieces_graphics_item GI ; + + GraphicsViewBezierRegionInput(QObject* aParent, QGraphicsScene* aScene) + : + GraphicsViewInput( aParent ) + , mScene ( aScene ) + , mState ( Start ) + , mBoundaryPen ( QColor(0,255,0) ) + , mOngoingCurvePen ( QColor(255,0,0) ) + , mHandlePen ( QColor(0,0,255) ) + , mCurrBoundary ( new Boundary() ) + , mCurrBoundaryGI ( 0 ) + { + mOngoingPieceGI = new GI(&mOngoingPieceCtr) ; + mHandle0GI = new QGraphicsLineItem(); + mHandle1GI = new QGraphicsLineItem(); - typedef typename Traits::Curve_2 Curve; - typedef typename Traits::X_monotone_curve_2 X_monotone_curve; - typedef typename Traits::Point_2 Point; - typedef typename Bezier_gps_traits::General_polygon_2 Boundary; - typedef Bezier_region_ Bezier_region ; - - typedef typename Bezier_region::General_polygon_2 Bezier_boundary; - - typedef Point_2< Simple_cartesian > Linear_point ; - - GraphicsViewBezierRegionInput(QObject *parent, QGraphicsScene* s); - ~GraphicsViewBezierRegionInput(); - - public slots: - - void processInput(CGAL::Object o); - - - protected: - - virtual void keyPressEvent(QKeyEvent *event); - - bool eventFilter(QObject *obj, QEvent *event); - - private: - - Bezier_boundary bounday; - std::vector boundaries; - Bezier_region br; // this one collects the input polygons - - Bezier_region_graphics_item * brItem; - GraphicsViewBezierBoundaryInput * bi; - - bool polygon_input; - QGraphicsScene *scene_; - }; - - - template - GraphicsViewBezierRegionInput::GraphicsViewBezierRegionInput(QObject *parent, QGraphicsScene* s) - : GraphicsViewInput(parent), scene_(s), polygon_input(false) - { - brItem = new Bezier_region_graphics_item(&br); - brItem->setBrush(::Qt::yellow); - scene_->addItem(brItem); - brItem->hide(); - - bi = new GraphicsViewBezierBoundaryInput(parent,s); - QObject::connect(bi, SIGNAL(generate(CGAL::Object)), - this, SLOT(processInput(CGAL::Object))); - - QObject::connect(this, SIGNAL(modelChanged()), - brItem, SLOT(modelChanged())); - + mOngoingPieceGI->setPen(mOngoingCurvePen); + mHandle0GI ->setPen(mHandlePen); + mHandle1GI ->setPen(mHandlePen); + + mHandle0GI->setLine(0,0,1,1); + mHandle1GI->setLine(0,0,1,1); + mHandle0GI->hide(); + mHandle1GI->hide(); + + mScene->addItem(mOngoingPieceGI); + mScene->addItem(mHandle0GI); + mScene->addItem(mHandle1GI); + + SetupCurrBoundary(); } - - template - GraphicsViewBezierRegionInput::~GraphicsViewBezierRegionInput() + + ~GraphicsViewBezierRegionInput() { - //delete brItem; - //delete bi; + //mScene->removeItem(mGI); + //delete mGI ; + //RemoveHandleItems(); } - - - template - void GraphicsViewBezierRegionInput::processInput(CGAL::Object o) + + bool eventFilter(QObject *obj, QEvent *aEvent) { - std::vector points; - if(CGAL::assign(points, o)) + bool rHandled = false ; + + if (aEvent->type() == QEvent::GraphicsSceneMousePress) { - if((points.size() == 1)&& polygon.size()>0) - { - - } else - { - polygon.clear(); - if(points.front() == points.back()) - { - points.pop_back(); - } - polygon.insert(polygon.vertices_begin(), points.begin(), points.end()); - if(boundaries.empty()) - { - if(polygon.orientation() == CGAL::CLOCKWISE) - { - polygon.reverse_orientation(); - } - } else - { - if(polygon.orientation() == CGAL::COUNTERCLOCKWISE) - { - polygon.reverse_orientation(); - } - } - boundaries.push_back(polygon); - typename std::list::iterator it = boundaries.begin(); - it++; - pwh = Bezier_region(boundaries.front(), it, boundaries.end()); - } - emit(modelChanged()); - polygon_input = false; + rHandled = mousePressEvent( static_cast(aEvent) ) ; } + else if (aEvent->type() == QEvent::GraphicsSceneMouseRelease) + { + rHandled = mouseReleaseEvent( static_cast(aEvent) ) ; + } + else if (aEvent->type() == QEvent::GraphicsSceneMouseMove) + { + rHandled = mouseMoveEvent( static_cast(aEvent) ) ; + } + else if (aEvent->type() == QEvent::KeyPress) + { + rHandled = keyPressEvent( static_cast(aEvent) ) ; + } + + if ( !rHandled ) + rHandled = QObject::eventFilter(obj, aEvent); + + return rHandled ; } + + protected: + enum State { Start, PieceOrFirstHandleStarted, PieceOngoing, FirstHandleOngoing, HandleOngoing, PieceEnded, CurveEnded } ; + + Point cvt ( QPointF const& aP ) const { return Point(aP.x(),aP.y()) ; } - template - void GraphicsViewBezierRegionInput::keyPressEvent ( QKeyEvent * event ) + bool mousePressEvent(QGraphicsSceneMouseEvent *aEvent) { - } + bool rHandled = false ; + + Point lP = cvt(aEvent->scenePos()); + + if ( aEvent->button() == ::Qt::LeftButton ) + { + switch (mState) + { + case Start: + mP0 = lP; + mState = PieceOrFirstHandleStarted; + rHandled = true; + break; - - - template - bool - GraphicsViewBezierRegionInput::eventFilter(QObject *obj, QEvent *event) - { - if(polygon_input){ - return bi->eventFilter(obj, event); - } else { - if (event->type() == QEvent::GraphicsSceneMousePress) { - QGraphicsSceneMouseEvent *mouseEvent = static_cast(event); - - if(mouseEvent->modifiers() & ::Qt::ShiftModifier){ - return QObject::eventFilter(obj, event);; - } - if(mouseEvent->button() == ::Qt::LeftButton) { - polygon_input = true; - return bi->eventFilter(obj, event); - } else if(mouseEvent->button() == ::Qt::RightButton) { - emit(generate(CGAL::make_object(pwh))); - pwh.clear(); - boundaries.clear(); - polygon_input = false; - emit(modelChanged()); - } - return true; - } else if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - keyPressEvent(keyEvent); - return true; - } else{ - // standard event processing - return QObject::eventFilter(obj, event); + case PieceOngoing: + mP1 = lP; + mState = HandleOngoing; + rHandled = true; + break; } } - } + + return rHandled ; + } + - } // namespace Qt + bool mouseMoveEvent(QGraphicsSceneMouseEvent *aEvent) + { + bool rHandled = false ; + + Point lP = cvt(aEvent->scenePos()); + + switch (mState) + { + case PieceOrFirstHandleStarted: + mState = FirstHandleOngoing; + rHandled = true; + break; + + case PieceOngoing: + mP1 = lP; + UpdateOngoingPiece(); + rHandled = true ; + break; + case FirstHandleOngoing: + UpdateVeryFirstHandle(lP); + rHandled = true ; + break; + + case HandleOngoing: + + UpdateHandles(lP); + UpdateOngoingPiece(); + + rHandled = true ; + break; + + case PieceEnded: + mState = PieceOngoing; + rHandled = true; + break; + } + + return rHandled ; + } + + bool mouseReleaseEvent(QGraphicsSceneMouseEvent *aEvent) + { + bool rHandled = false ; + + Point lP = cvt(aEvent->scenePos()); + + if ( aEvent->button() == ::Qt::LeftButton ) + { + switch (mState) + { + case PieceOrFirstHandleStarted: + mState = PieceOngoing; + rHandled = true; + break; + + case FirstHandleOngoing: + UpdateVeryFirstHandle(lP); + mPrevH0 = mH1 ; + mH1 = boost::optional(); + mState = PieceOngoing; + rHandled = true; + break; + + case HandleOngoing: + UpdateHandles(lP); + CommitOngoingPiece(lP); + mState = PieceEnded; + rHandled = true; + break; + } + } + else if ( aEvent->button() == ::Qt::RightButton ) + { + switch (mState) + { + case PieceOngoing: + CloseCurrBundary(); + CommitCurrBoundary(); + mPrevH0 = mH0 = mH1 = boost::optional(); + mState = Start ; + rHandled = true; + break; + } + } + + return rHandled ; + } + + bool keyPressEvent(QKeyEvent *aEvent) + { + bool rHandled = false ; + + + return rHandled ; + } + + + virtual void generate_boundary() + { + Output_region* lRegion = NULL; + + for ( const_boundary_terator bit = mComittedBoundaries.begin() ; bit != mComittedBoundaries.end(); ++ bit ) + { + Boundary const& lBoundary = **bit ; + + Traits traits ; + Traits::Make_x_monotone_2 make_x_monotone = traits.make_x_monotone_2_object(); + + std::vector xcvs; + + for ( const_curve_terator it = lBoundary.mPieces.begin() ; it != lBoundary.mPieces.end() ; ++ it ) + { + std::vector x_objs; + std::vector::const_iterator xoit; + + make_x_monotone ( *it, std::back_inserter (x_objs)); + + for (xoit = x_objs.begin(); xoit != x_objs.end(); ++xoit) + { + Output_X_monotone_curve xcv; + if (CGAL::assign (xcv, *xoit)) + xcvs.push_back (xcv); + } + } + + Output_boundary lOB(xcvs.begin(), xcvs.begin()); + + if ( !lRegion ) + lRegion = new Output_region(lOB) ; + else lRegion->add_hole(lOB); + } + + if ( lRegion ) + emit(generate(CGAL::make_object( *lRegion ))); + + Clear(); + SetupCurrBoundary(); + mState = Start ; + } + + private: + + Curve const* ongoing_piece() const { return mOngoingPieceCtr.size() == 1 ? &mOngoingPieceCtr[0] : NULL ; } + + void HideHandles() + { + mHandle0GI->hide(); + mHandle1GI->hide(); + } + + Curve CreatePiece() + { + if ( mPrevH0 && mH1 && *mPrevH0 != *mH1 && *mPrevH0 != mP0 && *mH1 != mP1 ) + { + Point lControlPoints[4] = { mP0 + , *mPrevH0 + , *mH1 + , mP1 + } ; + return Curve( lControlPoints, lControlPoints + 4 ) ; + } + else if ( mPrevH0 && !mH1 && *mPrevH0 != mP0 && *mPrevH0 != mP1 ) + { + Point lControlPoints[3] = { mP0 + , *mPrevH0 + , mP1 + } ; + return Curve( lControlPoints, lControlPoints + 3 ) ; + } + else if ( !mPrevH0 && mH1 && *mH1 != mP0 && *mH1 != mP1 ) + { + Point lControlPoints[3] = { mP0 + , *mH1 + , mP1 + } ; + return Curve( lControlPoints, lControlPoints + 3 ) ; + } + else + { + Point lControlPoints[2] = { mP0 + , mP1 + } ; + return Curve( lControlPoints, lControlPoints + 2 ) ; + } + } + + void UpdateOngoingPiece() + { + if ( mOngoingPieceCtr.size() > 0 ) + mOngoingPieceCtr.clear(); + mOngoingPieceCtr.push_back(CreatePiece()); + mOngoingPieceGI->modelChanged(); + } + + void CommitOngoingPiece( Point const& aP ) + { + if ( ongoing_piece() ) + { + mCurrBoundary->mPieces.push_back( *ongoing_piece() ) ; + mCurrBoundaryGI->modelChanged(); + mOngoingPieceCtr.clear(); + mOngoingPieceGI->modelChanged(); + mP0 = mP1 ; + mP1 = aP ; + mPrevH0 = mH0 ; + mH0 = mH1 = boost::optional(); + } + } + + void UpdateVeryFirstHandle(Point const& aP) + { + if ( squared_distance(mP0,aP) >= 9 ) + { + mH1 = aP ; + mHandle1GI->setLine( to_double(mP0.x()), to_double(mP0.y()), to_double(mH1->x()), to_double(mH1->y())); + mHandle1GI->show(); + + mH0 = boost::optional(); + mHandle0GI->hide(); + } + else + { + HideHandles(); + mH0 = mH1 = boost::optional(); + } + } + + void UpdateHandles(Point const& aP) + { + if ( squared_distance(mP1,aP) >= 9 ) + { + mH0 = aP ; + mH1 = mP1 - (aP - mP1); + + mHandle0GI->setLine( to_double(mP1.x()), to_double(mP1.y()), to_double(mH0->x()), to_double(mH0->y())); + mHandle1GI->setLine( to_double(mP1.x()), to_double(mP1.y()), to_double(mH1->x()), to_double(mH1->y())); + mHandle0GI->show(); + mHandle1GI->show(); + } + else + { + HideHandles(); + mH0 = mH1 = boost::optional(); + } + } + + + void CloseCurrBundary() + { + if ( mCurrBoundary->mPieces.size() > 0 && ongoing_piece()!= NULL ) + { + std::vector lControlPoints(ongoing_piece()->control_points_begin(),ongoing_piece()->control_points_end()); + + lControlPoints.back() = mCurrBoundary->mPieces.front().control_point(0); + + mCurrBoundary->mPieces.push_back( Curve( lControlPoints.begin(), lControlPoints.end() ) ) ; + + mCurrBoundary->mIsClosed = true ; + + mCurrBoundaryGI->modelChanged() ; + } + } + + void CommitCurrBoundary() + { + mOngoingPieceCtr.clear(); + mOngoingPieceGI->modelChanged(); + + if ( mCurrBoundary->mPieces.size() > 0 ) + { + mComittedBoundaries.push_back(mCurrBoundary) ; + + mCommittedBoundariesGI.push_back(mCurrBoundaryGI); + } + + SetupCurrBoundary(); + + HideHandles(); + } + + void SetupCurrBoundary() + { + mCurrBoundary = Boundary_ptr( new Boundary() ) ; + + mCurrBoundaryGI = new GI(&mCurrBoundary->mPieces) ; + + mCurrBoundaryGI->setPen(mBoundaryPen); + + mScene->addItem(mCurrBoundaryGI); + } + + void Clear() + { + mOngoingPieceCtr.clear(); + mOngoingPieceGI->modelChanged(); + mScene->removeItem(mCurrBoundaryGI); + for ( std::vector::iterator it = mCommittedBoundariesGI.begin() ; it != mCommittedBoundariesGI.end(); ++ it ) + mScene->removeItem(*it); + mCommittedBoundariesGI.clear(); + mComittedBoundaries .clear(); + mPrevH0 = mH0 = mH1 = boost::optional(); + } + + private: + + QGraphicsScene* mScene ; + std::vector mCommittedBoundariesGI ; + GI* mCurrBoundaryGI ; + GI* mOngoingPieceGI ; + QGraphicsLineItem* mHandle0GI ; + QGraphicsLineItem* mHandle1GI ; + + QPen mBoundaryPen ; + QPen mOngoingCurvePen ; + QPen mHandlePen ; + + Boundary_vector mComittedBoundaries ; + Boundary_ptr mCurrBoundary ; + Curve_vector mOngoingPieceCtr ; + + int mState; + + Point mP0; + Point mP1; + + boost::optional mPrevH0; + boost::optional mH0; + boost::optional mH1; + + }; // end class GraphicsViewBezierRegionInput + +} // namespace Qt } // namespace CGAL #endif // CGAL_QT_GRAPHICS_VIEW_BEZIER_REGION_INPUT_H