From 2a9238fa335fa10dc6f99335fed82196f7e7b22f Mon Sep 17 00:00:00 2001 From: Ahmed Essam Date: Thu, 20 Aug 2020 15:07:04 +0200 Subject: [PATCH] Cleanups --- .../ArrTraitsAdaptor.h | 118 +++++ .../ArrangementCurveInputCallback.h | 20 +- .../ArrangementDemoTab.cpp | 46 +- .../ArrangementDemoTab.h | 5 +- .../ArrangementDemoWindow.cpp | 6 +- .../ArrangementGraphicsItem.cpp | 68 +-- .../ArrangementGraphicsItem.h | 27 +- .../ArrangementPainterOstream.cpp | 3 - .../ArrangementPainterOstream.h | 1 - .../ArrangementTypes.h | 6 +- .../Arrangement_on_surface_2/CMakeLists.txt | 147 +++--- .../Arrangement_on_surface_2/Callback.cpp | 3 +- .../demo/Arrangement_on_surface_2/Callback.h | 2 +- .../Arrangement_on_surface_2/Conic_reader.h | 2 - .../CurveGraphicsItem.cpp | 7 +- .../CurveInputMethods.cpp | 416 +++++++++++++++++ .../CurveInputMethods.h | 217 +++++++++ .../GraphicsViewCurveInput.cpp | 420 +----------------- .../GraphicsViewCurveInput.h | 203 +-------- .../MergeEdgeCallback.cpp | 3 +- .../MergeEdgeCallback.h | 1 - .../PointLocationFunctions.cpp | 23 +- .../PointLocationFunctions.h | 6 + .../Arrangement_on_surface_2/PointSnapper.cpp | 4 +- .../SplitEdgeCallback.cpp | 3 +- .../SplitEdgeCallback.h | 3 +- .../demo/Arrangement_on_surface_2/Utils.cpp | 18 +- .../demo/Arrangement_on_surface_2/Utils.h | 97 +--- .../VerticalRayShootCallback.cpp | 37 +- 29 files changed, 951 insertions(+), 961 deletions(-) create mode 100644 Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrTraitsAdaptor.h create mode 100644 Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveInputMethods.cpp create mode 100644 Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveInputMethods.h diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrTraitsAdaptor.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrTraitsAdaptor.h new file mode 100644 index 00000000000..a4e6ae7369a --- /dev/null +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrTraitsAdaptor.h @@ -0,0 +1,118 @@ +// Copyright (c) 2012 Tel-Aviv University (Israel). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s): Alex Tsui + +#ifndef CGAL_ARRANGEMENTS_ARR_TRAITS_ADAPTOR_H +#define CGAL_ARRANGEMENTS_ARR_TRAITS_ADAPTOR_H + +#include + +namespace CGAL +{ +template +class Arr_segment_traits_2; + +template +class Arr_linear_traits_2; + +template +class Arr_polyline_traits_2; + +template +class Arr_conic_traits_2; + +template < + typename RatKernel_, typename AlgKernel_, typename NtTraits_, + typename BoundingTraits_> +class Arr_Bezier_curve_traits_2; + +template +class Arr_algebraic_segment_traits_2; +} // namespace CGAL + +/** + * Support for new ArrTraits should specify types: + * + * Kernel - a not-necessarily-exact kernel to represent the arrangement + * graphically. We'll use the Point_2 type provided by this kernel for + * computing distances + * Point_2 - the point type used in the particular arrangement + * CoordinateType - the coordinate type used by the point type + */ +template +class ArrTraitsAdaptor +{ +}; + +template +class ArrTraitsAdaptor> +{ +public: + typedef Kernel_ Kernel; + typedef CGAL::Arr_segment_traits_2 ArrTraits; + typedef typename ArrTraits::Point_2 Point_2; + typedef typename Kernel::FT CoordinateType; +}; + +template +class ArrTraitsAdaptor> +{ +public: + typedef Kernel_ Kernel; + typedef CGAL::Arr_linear_traits_2 ArrTraits; + typedef typename ArrTraits::Point_2 Point_2; + typedef typename Kernel::FT CoordinateType; +}; + +template +class ArrTraitsAdaptor> +{ +public: + typedef CGAL::Arr_polyline_traits_2 ArrTraits; + typedef typename SegmentTraits::Kernel Kernel; + typedef typename ArrTraits::Point_2 Point_2; + typedef typename Kernel::FT CoordinateType; +}; + +template +class ArrTraitsAdaptor> +{ +public: + typedef CGAL::Arr_conic_traits_2 ArrTraits; + typedef AlgKernel Kernel; + typedef typename ArrTraits::Point_2 Point_2; + typedef typename Kernel::FT CoordinateType; +}; + +template < + typename RatKernel, typename AlgKernel, typename NtTraits, + typename BoundingTraits> +class ArrTraitsAdaptor> +{ +public: + typedef CGAL::Arr_Bezier_curve_traits_2< + RatKernel, AlgKernel, NtTraits, BoundingTraits> + ArrTraits; + typedef RatKernel Kernel; + typedef typename ArrTraits::Point_2 Point_2; + typedef typename Kernel::FT CoordinateType; +}; + +template +class ArrTraitsAdaptor> +{ +public: + typedef Coefficient_ Coefficient; + typedef typename CGAL::Arr_algebraic_segment_traits_2 ArrTraits; + typedef typename ArrTraits::Point_2 Point_2; // CKvA_2 + typedef typename ArrTraits::Algebraic_real_1 CoordinateType; + typedef CGAL::Cartesian Kernel; +}; + +#endif diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementCurveInputCallback.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementCurveInputCallback.h index d98bf7d0739..7f2f734aea4 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementCurveInputCallback.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementCurveInputCallback.h @@ -12,7 +12,6 @@ #ifndef ARRANGEMENT_CURVE_INPUT_CALLBACK_H #define ARRANGEMENT_CURVE_INPUT_CALLBACK_H -#include #include "GraphicsViewCurveInput.h" template @@ -24,15 +23,13 @@ public: typedef typename Arrangement::Geometry_traits_2 Traits; typedef CGAL::Qt::GraphicsViewCurveInput< Traits > Superclass; typedef typename Traits::Curve_2 Curve_2; + typedef ArrangementCurveInputCallback Self; ArrangementCurveInputCallback(Arrangement* arrangement_, QObject* parent, QGraphicsScene* scene): Superclass( parent, scene ), arrangement( arrangement_) { - this->setScene(scene); - - QObject::connect( this, SIGNAL( generate( CGAL::Object ) ), - this, SLOT( processInput( CGAL::Object ) ) ); + QObject::connect(this, &Superclass::generate, this, &Self::processInput); } void processInput( CGAL::Object o ) @@ -41,19 +38,8 @@ public: if ( CGAL::assign( curve, o ) ) { CGAL::insert( *( this->arrangement ), curve ); + Q_EMIT CGAL::Qt::GraphicsViewCurveInputBase::modelChanged( ); } - - Q_EMIT CGAL::Qt::GraphicsViewInput::modelChanged( ); - } - - void setScene( QGraphicsScene* scene ) - { - this->Superclass::setScene( scene ); - } - - void setArrangement( Arrangement* newArr ) - { - this->arrangement = newArr; } protected: diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.cpp index 35b05bfe970..f994fe5f05a 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.cpp @@ -61,7 +61,6 @@ void ArrangementDemoTabBase::setupUi( ) this->layout->addWidget( this->graphicsView, 0, 0 ); this->graphicsView->setScene( scene ); - // TODO: Find suitable values double xymin = -MAX_WIDTH / 2; double wh = MAX_WIDTH; scene->setSceneRect(xymin, xymin, wh, wh); @@ -122,10 +121,6 @@ ArrangementDemoTabBase::getCurveInputCallback( ) const return this->curveInputCallback.get(); } -//! eraser option i.e. to delete the selected curve. -/*! - \return the drawing after the selected curve has been removed -*/ CGAL::Qt::Callback* ArrangementDemoTabBase::getDeleteCurveCallback( ) const { return this->deleteCurveCallback.get(); @@ -136,47 +131,27 @@ CGAL::Qt::Callback* ArrangementDemoTabBase::getPointLocationCallback( ) const return this->pointLocationCallback.get(); } -//! Vertical ray offshoot feedback -/*! - \return the ray in the direction closest to the edge of the screen -*/ VerticalRayShootCallbackBase* ArrangementDemoTabBase::getVerticalRayShootCallback( ) const { return this->verticalRayShootCallback.get(); } -//! Merging the segments -/*! - \return the curves after merging them back together -*/ CGAL::Qt::Callback* ArrangementDemoTabBase::getMergeEdgeCallback( ) const { return this->mergeEdgeCallback.get(); } -//! Splitting the curves drawn in the screen with points. -/*! - \return the points of splitting -*/ SplitEdgeCallbackBase* ArrangementDemoTabBase::getSplitEdgeCallback( ) const { return this->splitEdgeCallback.get(); } -//! feedback after the envelope call. -/*! - \return result of the envelope call -*/ EnvelopeCallbackBase* ArrangementDemoTabBase::getEnvelopeCallback( ) const { return this->envelopeCallback.get(); } -//! member function to fill the viewport -/*! - \return result after calling the fill color option -*/ FillFaceCallbackBase* ArrangementDemoTabBase::getFillFaceCallback( ) const { return this->fillFaceCallback.get(); @@ -197,22 +172,13 @@ void ArrangementDemoTabBase::unhookCallbacks() { this->getScene()->removeEventFilter(this->activeCallback); - // TODO(Ahmed Essam): This is ugly. Fix it. - // GraphicsViewCurveInputBase should inherit from Callback - auto callback = dynamic_cast(this->activeCallback); - if (callback) { callback->reset(); } - else - { - auto curveInput = dynamic_cast( - this->activeCallback); - if (curveInput) curveInput->reset(); - } - + activeCallback->reset(); this->activeCallback = nullptr; } } -void ArrangementDemoTabBase::unhookAndInstallEventFilter(QObject* obj) +void ArrangementDemoTabBase::unhookAndInstallEventFilter( + CGAL::Qt::Callback* obj) { this->unhookCallbacks(); this->getScene()->installEventFilter(obj); @@ -224,7 +190,7 @@ void ArrangementDemoTabBase::activateDeleteCurveCallback() // TODO(Ahmed Essam): Create different button for modes of delete if ( this->activeCallback == - static_cast(this->deleteCurveCallback.get())) + static_cast(this->deleteCurveCallback.get())) { auto deleteMode = this->deleteCurveCallback->getDeleteMode(); if (deleteMode == DeleteMode::DeleteOriginatingCuve) @@ -448,7 +414,7 @@ static const auto& getXyCurves() template CGAL::Bbox_2 -findOtherInterestingPoints(const std::unique_ptr& arr) +findOtherInterestingPoints(const std::unique_ptr&) { return {}; } @@ -493,7 +459,7 @@ static CGAL::Bbox_2 curvesBbox(const std::unique_ptr& arr) } template <> -CGAL::Bbox_2 curvesBbox(const std::unique_ptr& arr) +CGAL::Bbox_2 curvesBbox(const std::unique_ptr&) { return {}; } diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h index e77f95365b1..9b4d5815817 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h @@ -88,7 +88,7 @@ protected Q_SLOTS: protected: virtual void setupUi( ); - void unhookAndInstallEventFilter(QObject*); + void unhookAndInstallEventFilter(CGAL::Qt::Callback*); ArrangementDemoGraphicsView* graphicsView; QGridLayout* layout; @@ -103,8 +103,7 @@ protected: std::unique_ptr fillFaceCallback; std::unique_ptr snapper; - QObject* activeCallback; - + CGAL::Qt::Callback* activeCallback; CGAL::Qt::ArrangementGraphicsItemBase* arrangementGraphicsItem; GridGraphicsItem* gridGraphicsItem; }; // class ArrangementDemoTabBase diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp index 4ba20aba801..009d53526ae 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp @@ -12,7 +12,6 @@ #include "AlgebraicCurveParser.h" #include "ArrangementDemoPropertiesDialog.h" #include "ArrangementDemoTab.h" -#include "Conic_reader.h" #include "NewTabDialog.h" #include "OverlayDialog.h" #include "DeleteCurveCallback.h" @@ -40,6 +39,7 @@ #include #include #include +#include "Conic_reader.h" #include "ui_ArrangementDemoWindow.h" #include "ui_AlgebraicCurveInputDialog.h" @@ -403,7 +403,7 @@ void ArrangementDemoWindow::on_actionNewTab_triggered() } } -void ArrangementDemoWindow::on_tabWidget_currentChanged(int index) +void ArrangementDemoWindow::on_tabWidget_currentChanged(int) { auto tabPair = this->getCurrentTab(); auto currentTab = tabPair.first; @@ -720,7 +720,7 @@ struct ArrWriter conicReader.write_data(ofs, arr->curves_begin(), arr->curves_end()); } - void operator()(demo_types::Bezier_arr* arr) + void operator()(demo_types::Bezier_arr*) { } #endif diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.cpp index 743510db9a8..82dd05a0a7b 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.cpp @@ -80,13 +80,13 @@ paint(QPainter* painter, const QStyleOptionGraphicsItem* /* option */, QWidget* /*widget*/) { - this->paint( painter, Traits( ) ); + this->paint( painter, arr->traits() ); } template template void ArrangementGraphicsItem::paint( - QPainter* painter, TTraits /* traits */) + QPainter* painter, const TTraits* /* traits */) { this->paintFaces(painter); @@ -106,7 +106,7 @@ void ArrangementGraphicsItem::paint( template template void ArrangementGraphicsItem::paint( - QPainter* painter, CGAL::Arr_algebraic_segment_traits_2 traits) + QPainter* painter, const CGAL::Arr_algebraic_segment_traits_2*) { auto windowRect = painter->window(); auto width = windowRect.width(); @@ -156,10 +156,10 @@ void ArrangementGraphicsItem::paint( template void ArrangementGraphicsItem::paintFaces(QPainter* painter, QImage& image) { - QRgb* st = reinterpret_cast(tempImage.bits()); + QRgb* st = reinterpret_cast(image.bits()); - uint16_t width = tempImage.width(); - uint16_t height = tempImage.height(); + uint16_t width = image.width(); + uint16_t height = image.height(); // same as QColorConstants::Transparent.rgb() static constexpr QRgb invalid_rgb = 0; @@ -212,13 +212,15 @@ void ArrangementGraphicsItem::paintFaces(QPainter* painter, QImage& image) template < typename Arr_ > void ArrangementGraphicsItem< Arr_ >::updateBoundingBox( ) { - this->updateBoundingBox( Traits( ) ); + this->updateBoundingBox( arr->traits() ); } +constexpr double max_double = std::numeric_limits::max(); + template < typename Arr_ > template < typename TTraits > void ArrangementGraphicsItem< Arr_ >:: -updateBoundingBox(TTraits /* traits */) +updateBoundingBox(const TTraits* /* traits */) { this->prepareGeometryChange( ); @@ -226,38 +228,40 @@ updateBoundingBox(TTraits /* traits */) for (auto it = this->arr->edges_begin(); it != this->arr->edges_end(); ++it) { // can throw CGAL::internal::Zero_resultant_exception with algebraic curves - try { + // also horizontal lines with algebraic curves throw + try + { this->bb += it->curve().bbox(); - } catch(...) {} + } + catch (const std::exception& ex) + { + std::cerr << ex.what() << '\n'; + // in case an exception is thrown, make bbox to be unbounded just in case + this->bb = {-max_double, -max_double, max_double, max_double}; + break; + } } } template template void ArrangementGraphicsItem::updateBoundingBox( - CGAL::Arr_Bezier_curve_traits_2 /* traits */) + const CGAL::Arr_Bezier_curve_traits_2*) { this->prepareGeometryChange( ); this->bb = {}; for (auto it = this->arr->edges_begin(); it != this->arr->edges_end(); ++it) - { - // FIXME: There is no method to find bounding box of bezier x monotone curve - // Look at Bezier_x_monotone_2.h Subcurve struct - try { - this->bb += it->curve().supporting_curve().bbox(); - } catch(...) {} - } + this->bb += it->curve().supporting_curve().bbox(); } template template void ArrangementGraphicsItem::updateBoundingBox( - CGAL::Arr_linear_traits_2) + const CGAL::Arr_linear_traits_2*) { this->prepareGeometryChange( ); - constexpr double max_double = std::numeric_limits::max(); this->bb = {}; for (auto it = this->arr->edges_begin(); it != this->arr->edges_end(); ++it) { @@ -321,7 +325,7 @@ paintFace( Face_handle f, QPainter* painter ) if (f->visited()) return; Holes_iterator hit; // holes iterator - this->paintFace(f, painter, Traits()); + this->paintFace(f, painter, arr->traits()); f->set_visited(true); for (hit = f->holes_begin(); hit != f->holes_end(); ++hit) @@ -345,7 +349,7 @@ template < typename Kernel_ > void ArrangementGraphicsItem< Arr_ >:: paintFace( Face_handle f, QPainter* painter, - CGAL::Arr_segment_traits_2< Kernel_ > ) + const CGAL::Arr_segment_traits_2< Kernel_ >* ) { if (!f->is_unbounded()) // f is not the unbounded face { @@ -378,12 +382,10 @@ paintFace( Face_handle f, QPainter* painter, } } -template < typename Arr_ > -template < typename Kernel_ > -void -ArrangementGraphicsItem< Arr_ >:: -paintFace( Face_handle f, QPainter* painter, - CGAL::Arr_polyline_traits_2< Kernel_ > ) +template +template +void ArrangementGraphicsItem::paintFace( + Face_handle f, QPainter* painter, const CGAL::Arr_polyline_traits_2*) { if (!f->is_unbounded()) { @@ -450,7 +452,7 @@ template < typename Arr_ > template void ArrangementGraphicsItem::paintFace( Face_handle f, QPainter* painter, - CGAL::Arr_algebraic_segment_traits_2 /* traits */) + const CGAL::Arr_algebraic_segment_traits_2* /* traits */) { if (f->is_unbounded()) return; @@ -550,7 +552,7 @@ template template void ArrangementGraphicsItem::paintFace( Face_handle f, QPainter* painter, - CGAL::Arr_conic_traits_2) + const CGAL::Arr_conic_traits_2*) { if (!f->is_unbounded()) // f is not the unbounded face { @@ -647,8 +649,8 @@ template < typename BoundingTraits> void ArrangementGraphicsItem::paintFace( Face_handle f, QPainter* painter, - CGAL::Arr_Bezier_curve_traits_2< - RatKernel, AlgKernel, NtTraits, BoundingTraits> traits) + const CGAL::Arr_Bezier_curve_traits_2< + RatKernel, AlgKernel, NtTraits, BoundingTraits>*) { if (!f->is_unbounded()) { @@ -691,7 +693,7 @@ template template void ArrangementGraphicsItem::paintFace( Face_handle f, QPainter* painter, - CGAL::Arr_linear_traits_2 /* traits */) + const CGAL::Arr_linear_traits_2* /* traits */) { QVector pts; // holds the points of the polygon QColor color = f->color(); diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.h index 39f2529e39f..aa7fea9b112 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.h @@ -97,22 +97,23 @@ protected: void updatePointsItem(); template - void paint(QPainter*, TTraits); + void paint(QPainter*, const TTraits*); template - void paint(QPainter*, CGAL::Arr_algebraic_segment_traits_2); + void + paint(QPainter*, const CGAL::Arr_algebraic_segment_traits_2*); void updateBoundingBox(); template - void updateBoundingBox(TTraits); + void updateBoundingBox(const TTraits*); template void updateBoundingBox( - CGAL::Arr_Bezier_curve_traits_2); + const CGAL::Arr_Bezier_curve_traits_2*); template - void updateBoundingBox(CGAL::Arr_linear_traits_2); + void updateBoundingBox(const CGAL::Arr_linear_traits_2*); void paintFaces(QPainter* painter); @@ -132,34 +133,36 @@ protected: template void paintFace( - Face_handle f, QPainter* painter, CGAL::Arr_segment_traits_2); + Face_handle f, QPainter* painter, + const CGAL::Arr_segment_traits_2*); template void paintFace( - Face_handle f, QPainter* painter, CGAL::Arr_polyline_traits_2); + Face_handle f, QPainter* painter, + const CGAL::Arr_polyline_traits_2*); template void paintFace( Face_handle f, QPainter* painter, - CGAL::Arr_conic_traits_2); + const CGAL::Arr_conic_traits_2*); template < typename RatKernel, typename AlgKernel, typename NtTraits, typename BoundingTraits> void paintFace( Face_handle f, QPainter* painter, - CGAL::Arr_Bezier_curve_traits_2< - RatKernel, AlgKernel, NtTraits, BoundingTraits>); + const CGAL::Arr_Bezier_curve_traits_2< + RatKernel, AlgKernel, NtTraits, BoundingTraits>*); template void paintFace( Face_handle f, QPainter* painter, - CGAL::Arr_algebraic_segment_traits_2 /* traits */); + const CGAL::Arr_algebraic_segment_traits_2*); template void paintFace( Face_handle f, QPainter* painter, - CGAL::Arr_linear_traits_2 /* traits */); + const CGAL::Arr_linear_traits_2*); protected: Arrangement* arr; diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.cpp index 72b242a6416..e4a47fd4cc5 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.cpp @@ -1,7 +1,4 @@ #include "ArrangementPainterOstream.h" - -#include -#include #include namespace CGAL { diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.h index eeca5fe73dd..ff21f62969b 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.h @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypes.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypes.h index 23d938f922f..cb650222352 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypes.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypes.h @@ -12,8 +12,6 @@ #ifndef ARRANGEMENT_DEMO_TYPES_H #define ARRANGEMENT_DEMO_TYPES_H -#include - #include #include #include @@ -76,12 +74,12 @@ public: // less specializations, and makes PointSnapper untemplated #ifdef CGAL_USE_CORE typedef CORE::BigRat Rational; - typedef CGAL::Cartesian Rat_kernel; #else typedef CGAL::Exact_rational Rational; - typedef CGAL::Cartesian Rat_kernel; #endif +typedef CGAL::Cartesian Rat_kernel; + // Segments: typedef CGAL::Arr_segment_traits_2 Seg_traits; typedef Dcel Seg_dcel; diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt index 4b20e3bb670..290a15e71f1 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt @@ -9,91 +9,82 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() -# set default build type -if (NOT CMAKE_BUILD_TYPE) - set (CMAKE_BUILD_TYPE "Release" CACHE STRING - "Choose the type of build, options are: Debug Release" FORCE) -endif() +find_package(Qt5 COMPONENTS Gui Widgets) +find_package(CGAL COMPONENTS Core Qt5 ) -find_package(Qt5 REQUIRED COMPONENTS Gui Widgets) -find_package(CGAL REQUIRED COMPONENTS Core Qt5) -include(${CGAL_USE_FILE}) +if (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND CGAL_Core_FOUND) + include(${CGAL_USE_FILE}) + add_definitions(-DQT_NO_KEYWORDS) + include_directories( ./ ) + # Arrangement package includes + include_directories(BEFORE ../../include) -add_definitions(-DQT_NO_KEYWORDS) + qt5_wrap_ui(arrangement_2_uis + ArrangementDemoWindow.ui + NewTabDialog.ui + OverlayDialog.ui + ArrangementDemoPropertiesDialog.ui + AlgebraicCurveInputDialog.ui) -include_directories( ./ ) -# Arrangement package includes -include_directories(BEFORE ../../include) + qt5_wrap_cpp(CGAL_Qt5_MOC_FILES + ArrangementDemoWindow.h + ArrangementDemoTab.h + GraphicsViewCurveInput.h + Callback.h + OverlayDialog.h + ArrangementDemoPropertiesDialog.h + AlgebraicCurveInputDialog.h + ColorItemEditor.h + DeleteCurveModeItemEditor.h + PropertyValueDelegate.h) -qt5_wrap_ui(arrangement_2_uis - ArrangementDemoWindow.ui - NewTabDialog.ui - OverlayDialog.ui - ArrangementDemoPropertiesDialog.ui - AlgebraicCurveInputDialog.ui) + qt5_add_resources(CGAL_Qt5_RESOURCE_FILES ArrangementDemoWindow.qrc) -qt5_wrap_cpp(CGAL_Qt5_MOC_FILES - ArrangementDemoWindow.h - ArrangementDemoTab.h - GraphicsViewCurveInput.h - Callback.h - OverlayDialog.h - ArrangementDemoPropertiesDialog.h - AlgebraicCurveInputDialog.h - ColorItemEditor.h - DeleteCurveModeItemEditor.h - PropertyValueDelegate.h) + add_executable(arrangement_2 + arrangement_2.cpp + ArrangementDemoWindow.cpp + ArrangementDemoTab.cpp + ArrangementDemoGraphicsView.cpp + ArrangementGraphicsItem.cpp + Callback.cpp + VerticalRayShootCallback.cpp + EnvelopeCallback.cpp + SplitEdgeCallback.cpp + FillFaceCallback.cpp + MergeEdgeCallback.cpp + PointLocationFunctions.cpp + PointLocationCallback.cpp + Utils.cpp + NewTabDialog.cpp + OverlayDialog.cpp + ArrangementDemoPropertiesDialog.cpp + AlgebraicCurveInputDialog.cpp + ColorItemEditor.cpp + PropertyValueDelegate.cpp + DeleteCurveMode.cpp + DeleteCurveModeItemEditor.cpp + PointsGraphicsItem.cpp + VerticalRayGraphicsItem.cpp + DeleteCurveCallback.cpp + CurveGraphicsItem.cpp + ArrangementPainterOstream.cpp + GraphicsViewCurveInput.cpp + AlgebraicCurveParser.cpp + GraphicsSceneMixin.cpp + GridGraphicsItem.cpp + PointSnapper.cpp + CurveInputMethods.cpp + ${CGAL_Qt5_MOC_FILES} + ${arrangement_2_uis} + ${CGAL_Qt5_RESOURCE_FILES}) -qt5_add_resources(CGAL_Qt5_RESOURCE_FILES ArrangementDemoWindow.qrc) + qt5_use_modules(arrangement_2 Core Gui Widgets) + target_link_libraries(arrangement_2 CGAL::CGAL CGAL::CGAL_Qt5 CGAL::CGAL_Core) + add_to_cached_list(CGAL_EXECUTABLE_TARGETS arrangement_2) -add_executable(arrangement_2 - arrangement_2.cpp - ArrangementDemoWindow.cpp - ArrangementDemoTab.cpp - ArrangementDemoGraphicsView.cpp - ArrangementGraphicsItem.cpp - Callback.cpp - VerticalRayShootCallback.cpp - EnvelopeCallback.cpp - SplitEdgeCallback.cpp - FillFaceCallback.cpp - MergeEdgeCallback.cpp - PointLocationFunctions.cpp - PointLocationCallback.cpp - Utils.cpp - NewTabDialog.cpp - OverlayDialog.cpp - ArrangementDemoPropertiesDialog.cpp - AlgebraicCurveInputDialog.cpp - ColorItemEditor.cpp - PropertyValueDelegate.cpp - DeleteCurveMode.cpp - DeleteCurveModeItemEditor.cpp - PointsGraphicsItem.cpp - VerticalRayGraphicsItem.cpp - DeleteCurveCallback.cpp - CurveGraphicsItem.cpp - ArrangementPainterOstream.cpp - GraphicsViewCurveInput.cpp - AlgebraicCurveParser.cpp - GraphicsSceneMixin.cpp - GridGraphicsItem.cpp - PointSnapper.cpp - ${CGAL_Qt5_MOC_FILES} - ${arrangement_2_uis} - ${CGAL_Qt5_RESOURCE_FILES}) + include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) + cgal_add_compilation_test(arrangement_2) -qt5_use_modules(arrangement_2 Core Gui Widgets) -target_link_libraries(arrangement_2 CGAL::CGAL CGAL::CGAL_Qt5 CGAL::CGAL_Core) -add_to_cached_list(CGAL_EXECUTABLE_TARGETS arrangement_2) - -include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) -cgal_add_compilation_test(arrangement_2) - -# compiler warnings -if(MSVC) - target_compile_options(arrangement_2 PRIVATE /W4 /WX) else() - target_compile_options(arrangement_2 PRIVATE -Wall) + message(STATUS "NOTICE: This demo requires CGAL, CGAL-Core and Qt5, and will not be compiled.") endif() - diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Callback.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Callback.cpp index 80562029782..6606d866c1e 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Callback.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Callback.cpp @@ -20,7 +20,8 @@ namespace CGAL { namespace Qt { -Callback::Callback( QObject* parent ) : QObject( parent ) { } +Callback::Callback(QObject* parent, QGraphicsScene* scene_) : + QObject(parent), GraphicsSceneMixin(scene_) { } void Callback::reset( ) { } diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Callback.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Callback.h index 10a342325bd..e65bdb3e6ba 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Callback.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Callback.h @@ -28,7 +28,7 @@ class Callback : public QObject, public GraphicsSceneMixin Q_OBJECT public: - Callback( QObject* parent ); + Callback( QObject* parent, QGraphicsScene* scene_ = nullptr ); virtual void reset( ); public Q_SLOTS: diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Conic_reader.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Conic_reader.h index b780165dc2a..c538d2db5d1 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Conic_reader.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Conic_reader.h @@ -14,8 +14,6 @@ #include #include -#include -#include #include #include diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveGraphicsItem.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveGraphicsItem.cpp index c5d1ea3599c..eeaf11192e1 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveGraphicsItem.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveGraphicsItem.cpp @@ -41,10 +41,9 @@ void CurveGraphicsItem::paint( template QRectF CurveGraphicsItem::boundingRect() const { - typedef typename ArrTraitsAdaptor::Kernel Kernel; - CGAL::Qt::Converter convert; - QRectF boundingRectangle = convert(this->boundingBox); - return boundingRectangle; + return { + QPointF{this->boundingBox.xmin(), this->boundingBox.ymin()}, + QPointF{this->boundingBox.xmax(), this->boundingBox.ymax()}}; } template diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveInputMethods.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveInputMethods.cpp new file mode 100644 index 00000000000..8e50cce8f69 --- /dev/null +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveInputMethods.cpp @@ -0,0 +1,416 @@ +#include "CurveInputMethods.h" +#include +#include +#include + +namespace CGAL +{ +namespace Qt +{ + +CurveInputMethod::CurveInputMethod(CurveType type_, int numPoints_) : + GraphicsSceneMixin(), numPoints{numPoints_}, callback{nullptr}, type{type_}, + itemsAdded{false} +{ + if (numPoints > 0) clickedPoints.reserve(numPoints); + this->pointsGraphicsItem.setZValue(100); +} + +void CurveInputMethod::setColor(QColor c) +{ + this->color = c; + this->pointsGraphicsItem.setColor(c); +} + +QColor CurveInputMethod::getColor() const +{ + return this->color; +} + +void CurveInputMethod::setCallback(CurveInputMethodCallback* callback_) +{ + this->callback = callback_; +} + +void CurveInputMethod::setPointSnapper(PointSnapperBase* snapper_) +{ + this->snapper = snapper_; +} + +CurveType CurveInputMethod::curveType() const { return type; } + + +void CurveInputMethod::mouseMoveEvent(QGraphicsSceneMouseEvent* event) +{ + if (this->clickedPoints.size() > 0) + this->updateVisualGuideMouseMoved( + this->clickedPoints, this->snapQPoint(event)); +} + +void CurveInputMethod::mousePressEvent(QGraphicsSceneMouseEvent* event) +{ + if (event->button() == ::Qt::LeftButton) + { + Point_2 big_point = this->snapPoint(event); + QPointF point = { + CGAL::to_double(big_point.x()), CGAL::to_double(big_point.y())}; + + // only accept unique consecutive points + if (!this->clickedPoints.empty() && this->clickedPoints.back() == point) + return; + this->clickedPoints.push_back(point); + this->clickedBigPoints.push_back(big_point); + + if (this->clickedPoints.size() < static_cast(this->numPoints)) + { + if (this->clickedPoints.size() == 1) this->beginInput_(); + this->pointsGraphicsItem.insert(point); + this->updateVisualGuideNewPoint(this->clickedPoints); + } + else + { + if (this->callback) + callback->curveInputDoneEvent(this->clickedBigPoints, this->type); + this->reset(); + } + } + else if (event->button() == ::Qt::RightButton) + { + if (this->numPoints == -1 && this->callback) + callback->curveInputDoneEvent(this->clickedBigPoints, this->type); + this->reset(); + } +} + +void CurveInputMethod::beginInput_() +{ + this->beginInput(); + this->itemsAdded = true; + this->getScene()->addItem(&(this->pointsGraphicsItem)); + for (auto& item : items) this->getScene()->addItem(item); +} + +void CurveInputMethod::reset() +{ + this->resetInput(); + this->clickedPoints.clear(); + this->clickedBigPoints.clear(); + this->pointsGraphicsItem.clear(); + if (this->itemsAdded) + { + this->getScene()->removeItem(&(this->pointsGraphicsItem)); + for (auto& item : items) this->getScene()->removeItem(item); + this->itemsAdded = false; + } +} + +void CurveInputMethod::resetInput() { } +void CurveInputMethod::beginInput() { } + +void CurveInputMethod::updateVisualGuideNewPoint(const std::vector&) { +} + +void CurveInputMethod::updateVisualGuideMouseMoved( + const std::vector&, const QPointF&) +{ +} + +auto CurveInputMethod::snapPoint(QGraphicsSceneMouseEvent* event) -> Point_2 +{ + return this->snapper->snapPoint(event->scenePos()); +} + +QPointF CurveInputMethod::snapQPoint(QGraphicsSceneMouseEvent* event) +{ + auto&& pt = this->snapPoint(event); + return QPointF{CGAL::to_double(pt.x()), CGAL::to_double(pt.y())}; +} + +void CurveInputMethod::appendGraphicsItem(QGraphicsItem* item) +{ + items.push_back(item); + item->setZValue(100); +} + +// SegmentInputMethod +SegmentInputMethod::SegmentInputMethod() : + CurveInputMethod(CurveType::Segment, 2) +{ + this->appendGraphicsItem(&(this->segmentGuide)); +} + +void SegmentInputMethod::beginInput() +{ + this->segmentGuide.setLine(0, 0, 0, 0); + QPen pen = this->segmentGuide.pen(); + pen.setColor(this->color); + pen.setCosmetic(true); + this->segmentGuide.setPen(pen); +} + +void SegmentInputMethod::updateVisualGuideMouseMoved( + const std::vector& clickedPoints, const QPointF& movePoint) +{ + QLineF segment{clickedPoints[0], movePoint}; + this->segmentGuide.setLine(segment); +} + +// PolylineInputMethod +PolylineInputMethod::PolylineInputMethod() : + CurveInputMethod(CurveType::Polyline, -1) +{ + this->appendGraphicsItem(&(this->polylineGuide)); + this->appendGraphicsItem(&(this->lastLine)); +} + +void PolylineInputMethod::beginInput() +{ + this->painterPath.clear(); + this->polylineGuide.setPath(this->painterPath); + this->lastLine.setLine(0, 0, 0, 0); + QPen pen = this->polylineGuide.pen(); + pen.setColor(this->color); + pen.setCosmetic(true); + this->polylineGuide.setPen(pen); + this->lastLine.setPen(pen); +} + +void PolylineInputMethod::updateVisualGuideMouseMoved( + const std::vector& clickedPoints, const QPointF& movePoint) +{ + this->lastLine.setLine(QLineF{clickedPoints.back(), movePoint}); +} + +void PolylineInputMethod::updateVisualGuideNewPoint( + const std::vector& points) +{ + if (points.size() == 1) + this->painterPath.moveTo(points.back()); + else + this->painterPath.lineTo(points.back()); + + this->polylineGuide.setPath(this->painterPath); +} + +// RayInputMethod +RayInputMethod::RayInputMethod() : CurveInputMethod(CurveType::Ray, 2) +{ + this->appendGraphicsItem(&(this->rayGuide)); +} + +void RayInputMethod::beginInput() +{ + this->rayGuide.setLine(0, 0, 0, 0); + QPen pen = this->rayGuide.pen(); + pen.setColor(this->color); + pen.setCosmetic(true); + this->rayGuide.setPen(pen); +} + +void RayInputMethod::updateVisualGuideMouseMoved( + const std::vector& clickedPoints, const QPointF& movePoint) +{ + float length = QLineF{clickedPoints[0], movePoint}.length(); + float dx = (movePoint.x() - clickedPoints[0].x()) / length; + float dy = (movePoint.y() - clickedPoints[0].y()) / length; + QRectF viewport = this->viewportRect(); + float r = std::sqrt( + viewport.width() * viewport.width() + + viewport.height() * viewport.height()); + QPointF endPoint = { + clickedPoints[0].x() + dx * r, clickedPoints[0].y() + dy * r}; + QLineF segment{clickedPoints[0], endPoint}; + this->rayGuide.setLine(segment); +} + +// LineInputMethod +LineInputMethod::LineInputMethod() : CurveInputMethod(CurveType::Line, 2) +{ + this->appendGraphicsItem(&(this->lineGuide)); +} + +void LineInputMethod::beginInput() +{ + this->lineGuide.setLine(0, 0, 0, 0); + QPen pen = this->lineGuide.pen(); + pen.setColor(this->color); + pen.setCosmetic(true); + this->lineGuide.setPen(pen); +} + +void LineInputMethod::updateVisualGuideMouseMoved( + const std::vector& clickedPoints, const QPointF& movePoint) +{ + float length = QLineF{clickedPoints[0], movePoint}.length(); + float dx = (clickedPoints[0].x() - movePoint.x()) / length; + float dy = (clickedPoints[0].y() - movePoint.y()) / length; + QRectF viewport = this->viewportRect(); + float r = std::sqrt( + viewport.width() * viewport.width() + + viewport.height() * viewport.height()); + QPointF endPoint = { + clickedPoints[0].x() + dx * r, clickedPoints[0].y() + dy * r}; + QPointF firstPoint = { + clickedPoints[0].x() - dx * r, clickedPoints[0].y() - dy * r}; + QLineF segment{firstPoint, endPoint}; + this->lineGuide.setLine(segment); +} + +// CircleInputMethod +CircleInputMethod::CircleInputMethod() : CurveInputMethod(CurveType::Circle, 2) +{ + this->appendGraphicsItem(&(this->circleGuide)); +} + +void CircleInputMethod::beginInput() +{ + this->circleGuide.setRect(0, 0, 0, 0); + QPen pen = this->circleGuide.pen(); + pen.setColor(this->color); + pen.setCosmetic(true); + this->circleGuide.setPen(pen); +} + +void CircleInputMethod::updateVisualGuideMouseMoved( + const std::vector& clickedPoints, const QPointF& movePoint) +{ + auto& center = clickedPoints.front(); + float radius = QLineF{center, movePoint}.length(); + this->circleGuide.setRect( + center.x() - radius, center.y() - radius, 2 * radius, 2 * radius); +} + +// EllipseInputMethod +EllipseInputMethod::EllipseInputMethod() : + CurveInputMethod(CurveType::Ellipse, 2) +{ + this->appendGraphicsItem(&(this->ellipseGuide)); +} + +void EllipseInputMethod::beginInput() +{ + this->ellipseGuide.setRect(0, 0, 0, 0); + QPen pen = this->ellipseGuide.pen(); + pen.setColor(this->color); + pen.setCosmetic(true); + this->ellipseGuide.setPen(pen); +} + +void EllipseInputMethod::updateVisualGuideMouseMoved( + const std::vector& clickedPoints, const QPointF& movePoint) +{ + this->ellipseGuide.setRect(QRectF{clickedPoints[0], movePoint}); +} + +// ThreePointCircularInputMethod +ThreePointCircularInputMethod::ThreePointCircularInputMethod() : + CurveInputMethod(CurveType::ThreePointCircularArc, 3) +{ +} + +// FivePointConicInputMethod +FivePointConicInputMethod::FivePointConicInputMethod() : + CurveInputMethod(CurveType::FivePointConicArc, 5) +{ +} + +// BezierInputMethod +BezierInputMethod::BezierInputMethod() : CurveInputMethod(CurveType::Bezier, -1) +{ + this->appendGraphicsItem(&(this->bezierGuide)); + this->appendGraphicsItem(&(this->bezierOldGuide)); +} + +void BezierInputMethod::beginInput() +{ + this->painterOldPath.clear(); + this->painterPath.clear(); + this->bezierGuide.setPath(this->painterPath); + this->bezierOldGuide.setPath(this->painterOldPath); + + QPen pen = this->bezierOldGuide.pen(); + pen.setColor(this->color); + pen.setCosmetic(true); + this->bezierOldGuide.setPen(pen); + + // TODO: set bezier guide color dynamically + pen = this->bezierGuide.pen(); + pen.setColor(QColorConstants::DarkGray); + pen.setCosmetic(true); + this->bezierGuide.setPen(pen); +} + +static QPointF evalBezier( + const std::vector& control_points, std::vector& cache, + float t) +{ + // iterative de Casteljau Algorithm + cache.clear(); + + for (size_t j = 0; j + 1 < control_points.size(); j++) + cache.push_back(control_points[j] * (1.0f - t) + control_points[j + 1] * t); + + for (size_t i = 1; i + 1 < control_points.size(); i++) + for (size_t j = 0; j + i + 1 < control_points.size(); j++) + cache[j] = cache[j] * (1.0f - t) + cache[j + 1] * t; + + return cache[0]; +} + +static float approx_pixel_length( + const std::vector& control_points, const QTransform& worldTransform) +{ + float l = 0; + for (size_t i = 0; i + 1 < control_points.size(); i++) + { + QPointF p1 = worldTransform.map(control_points[i]); + QPointF p2 = worldTransform.map(control_points[i + 1]); + l += QLineF{p1, p2}.length(); + } + return l; +} + +static void updateBezierPainterPath( + const std::vector& controlPoints, std::vector& cache, + const QTransform& worldTransform, QPainterPath& painterPath) +{ + painterPath.clear(); + if (controlPoints.size() < 2) return; + + float pixel_len = approx_pixel_length(controlPoints, worldTransform); + static constexpr int PIXEL_DIV = 4; + int num_segs = std::max(1, static_cast(pixel_len / PIXEL_DIV)); + + painterPath.moveTo(controlPoints[0]); + for (int i = 0; i < num_segs; i++) + painterPath.lineTo( + evalBezier(controlPoints, cache, static_cast(i + 1) / num_segs)); +} + +void BezierInputMethod::updateVisualGuideMouseMoved( + const std::vector& clickedPoints, const QPointF& movePoint) +{ + this->controlPoints.clear(); + std::copy( + clickedPoints.begin(), clickedPoints.end(), + std::back_inserter(this->controlPoints)); + this->controlPoints.push_back(movePoint); + + updateBezierPainterPath( + this->controlPoints, this->cache, this->getView()->transform(), + this->painterPath); + + this->bezierGuide.setPath(this->painterPath); +} + +void BezierInputMethod::updateVisualGuideNewPoint( + const std::vector& clickedPoints) +{ + updateBezierPainterPath( + clickedPoints, this->cache, this->getView()->transform(), + this->painterOldPath); + this->bezierOldGuide.setPath(this->painterPath); +} + +} // namespace Qt +} // namespace CGAL diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveInputMethods.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveInputMethods.h new file mode 100644 index 00000000000..6cac46905e7 --- /dev/null +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveInputMethods.h @@ -0,0 +1,217 @@ +#ifndef ARRANGEMENT_DEMO_CURVE_INPUT_METHODS_H +#define ARRANGEMENT_DEMO_CURVE_INPUT_METHODS_H + +#include +#include + +#include "GraphicsSceneMixin.h" +#include "PointSnapper.h" +#include "PointsGraphicsItem.h" + +class QEvent; +class QGraphicsSceneMouseEvent; + +namespace CGAL +{ + +namespace Qt +{ +enum class CurveType +{ + Segment, + Polyline, + Ray, + Line, + Circle, + Ellipse, + ThreePointCircularArc, + FivePointConicArc, + AlgebraicEquation, + Bezier, + None, +}; + +class CurveInputMethodCallback +{ +public: + using Point_2 = PointSnapperBase::Point_2; + + virtual void curveInputDoneEvent( + const std::vector& clickedPoints, CurveType type) = 0; +}; + +class CurveInputMethod : public GraphicsSceneMixin +{ +public: + using Point_2 = PointSnapperBase::Point_2; + + CurveInputMethod(CurveType, int numPoints_ = -1); + virtual ~CurveInputMethod() { } + + void setCallback(CurveInputMethodCallback*); + void setPointSnapper(PointSnapperBase*); + CurveType curveType() const; + + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent* event); + void reset(); + void beginInput_(); + + void setColor(QColor); + QColor getColor() const; + + Point_2 snapPoint(QGraphicsSceneMouseEvent* event); + QPointF snapQPoint(QGraphicsSceneMouseEvent* event); + +protected: + virtual void beginInput(); + virtual void resetInput(); + virtual void updateVisualGuideNewPoint(const std::vector&); + virtual void + updateVisualGuideMouseMoved(const std::vector&, const QPointF&); + void appendGraphicsItem(QGraphicsItem* item); + +protected: + QColor color; + +private: + const int numPoints; + std::vector clickedPoints; + std::vector clickedBigPoints; + PointsGraphicsItem pointsGraphicsItem; + CurveInputMethodCallback* callback; + const CurveType type; + std::vector items; + bool itemsAdded; + PointSnapperBase* snapper; +}; + +class SegmentInputMethod : public CurveInputMethod +{ +public: + SegmentInputMethod(); + + void beginInput() override; + + void updateVisualGuideMouseMoved( + const std::vector& clickedPoints, + const QPointF& movePoint) override; + +private: + QGraphicsLineItem segmentGuide; +}; + +class RayInputMethod : public CurveInputMethod +{ +public: + RayInputMethod(); + + void beginInput() override; + + void updateVisualGuideMouseMoved( + const std::vector& clickedPoints, + const QPointF& movePoint) override; + +private: + QGraphicsLineItem rayGuide; +}; + +class LineInputMethod : public CurveInputMethod +{ +public: + LineInputMethod(); + + void beginInput() override; + + void updateVisualGuideMouseMoved( + const std::vector& clickedPoints, + const QPointF& movePoint) override; + +private: + QGraphicsLineItem lineGuide; +}; + +class PolylineInputMethod : public CurveInputMethod +{ +public: + PolylineInputMethod(); + + void beginInput() override; + + void updateVisualGuideMouseMoved( + const std::vector& clickedPoints, + const QPointF& movePoint) override; + + void updateVisualGuideNewPoint(const std::vector&) override; + +private: + QGraphicsPathItem polylineGuide; + QGraphicsLineItem lastLine; + QPainterPath painterPath; +}; + +class CircleInputMethod : public CurveInputMethod +{ +public: + CircleInputMethod(); + + void beginInput() override; + + void updateVisualGuideMouseMoved( + const std::vector& clickedPoints, + const QPointF& movePoint) override; + +private: + QGraphicsEllipseItem circleGuide; +}; + +class EllipseInputMethod : public CurveInputMethod +{ +public: + EllipseInputMethod(); + + void beginInput() override; + + void updateVisualGuideMouseMoved( + const std::vector& clickedPoints, + const QPointF& movePoint) override; + +private: + QGraphicsEllipseItem ellipseGuide; +}; + +class ThreePointCircularInputMethod : public CurveInputMethod +{ +public: + ThreePointCircularInputMethod(); +}; + +class FivePointConicInputMethod : public CurveInputMethod +{ +public: + FivePointConicInputMethod(); +}; + +class BezierInputMethod : public CurveInputMethod +{ +public: + BezierInputMethod(); + void beginInput() override; + void updateVisualGuideNewPoint(const std::vector&) override; + void updateVisualGuideMouseMoved( + const std::vector& clickedPoints, + const QPointF& movePoint) override; + +private: + QGraphicsPathItem bezierOldGuide; + QGraphicsPathItem bezierGuide; + QPainterPath painterOldPath; + QPainterPath painterPath; + std::vector controlPoints; + std::vector cache; +}; + +} // namespace Qt +} // namespace CGAL + +#endif diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.cpp index 4b03cf5c96d..d90105b5f79 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.cpp @@ -11,21 +11,10 @@ #include "GraphicsViewCurveInput.h" #include "ArrangementTypes.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include "QtMetaTypes.h" -#include - -// TODO(Ahmed Essam): move these somewhere else! +// TODO: move these somewhere else! template inline typename std::enable_if::type for_each(std::tuple&, FuncT) @@ -47,8 +36,8 @@ namespace Qt GraphicsViewCurveInputBase::GraphicsViewCurveInputBase( QObject* parent, QGraphicsScene* scene) : - GraphicsViewInput(parent), - GraphicsSceneMixin(scene), inputMethod(nullptr) + Callback(parent, scene), + inputMethod(nullptr) { } @@ -97,408 +86,6 @@ void GraphicsViewCurveInputBase::setColor(QColor c) this->inputMethod->setColor(c); } -CurveInputMethod::CurveInputMethod(CurveType type_, int numPoints_) : - GraphicsSceneMixin(), numPoints{numPoints_}, type{type_}, itemsAdded{false} -{ - if (numPoints > 0) clickedPoints.reserve(numPoints); - this->pointsGraphicsItem.setZValue(100); -} - -void CurveInputMethod::setColor(QColor c) -{ - this->color = c; - this->pointsGraphicsItem.setColor(c); -} - -QColor CurveInputMethod::getColor() const -{ - return this->color; -} - -void CurveInputMethod::setCallback(CurveInputMethodCallback* callback_) -{ - this->callback = callback_; -} - -void CurveInputMethod::setPointSnapper(PointSnapperBase* snapper_) -{ - this->snapper = snapper_; -} - -CurveType CurveInputMethod::curveType() const { return type; } - - -void CurveInputMethod::mouseMoveEvent(QGraphicsSceneMouseEvent* event) -{ - if (this->clickedPoints.size() > 0) - this->updateVisualGuideMouseMoved( - this->clickedPoints, this->snapQPoint(event)); -} - -void CurveInputMethod::mousePressEvent(QGraphicsSceneMouseEvent* event) -{ - if (event->button() == ::Qt::LeftButton) - { - Point_2 big_point = this->snapPoint(event); - QPointF point = { - CGAL::to_double(big_point.x()), CGAL::to_double(big_point.y())}; - - // only accept unique consecutive points - if (!this->clickedPoints.empty() && this->clickedPoints.back() == point) - return; - this->clickedPoints.push_back(point); - this->clickedBigPoints.push_back(big_point); - - if (this->clickedPoints.size() < static_cast(this->numPoints)) - { - if (this->clickedPoints.size() == 1) this->beginInput_(); - this->pointsGraphicsItem.insert(point); - this->updateVisualGuideNewPoint(this->clickedPoints); - } - else - { - callback->curveInputDoneEvent(this->clickedBigPoints, this->type); - this->reset(); - } - } - else if (event->button() == ::Qt::RightButton) - { - if (this->numPoints == -1) - callback->curveInputDoneEvent(this->clickedBigPoints, this->type); - this->reset(); - } -} - -void CurveInputMethod::beginInput_() -{ - this->beginInput(); - this->itemsAdded = true; - this->getScene()->addItem(&(this->pointsGraphicsItem)); - for (auto& item : items) this->getScene()->addItem(item); -} - -void CurveInputMethod::reset() -{ - this->resetInput(); - this->clickedPoints.clear(); - this->clickedBigPoints.clear(); - this->pointsGraphicsItem.clear(); - if (this->itemsAdded) - { - this->getScene()->removeItem(&(this->pointsGraphicsItem)); - for (auto& item : items) this->getScene()->removeItem(item); - this->itemsAdded = false; - } -} - -void CurveInputMethod::resetInput() { } -void CurveInputMethod::beginInput() { } - -void CurveInputMethod::updateVisualGuideNewPoint(const std::vector&) { -} - -void CurveInputMethod::updateVisualGuideMouseMoved( - const std::vector&, const QPointF&) -{ -} - -auto CurveInputMethod::snapPoint(QGraphicsSceneMouseEvent* event) -> Point_2 -{ - return this->snapper->snapPoint(event->scenePos()); -} - -QPointF CurveInputMethod::snapQPoint(QGraphicsSceneMouseEvent* event) -{ - auto&& pt = this->snapPoint(event); - return QPointF{CGAL::to_double(pt.x()), CGAL::to_double(pt.y())}; -} - -void CurveInputMethod::appendGraphicsItem(QGraphicsItem* item) -{ - items.push_back(item); - item->setZValue(100); -} - -// SegmentInputMethod -SegmentInputMethod::SegmentInputMethod() : - CurveInputMethod(CurveType::Segment, 2) -{ - this->appendGraphicsItem(&(this->segmentGuide)); -} - -void SegmentInputMethod::beginInput() -{ - this->segmentGuide.setLine(0, 0, 0, 0); - QPen pen = this->segmentGuide.pen(); - pen.setColor(this->color); - pen.setCosmetic(true); - this->segmentGuide.setPen(pen); -} - -void SegmentInputMethod::updateVisualGuideMouseMoved( - const std::vector& clickedPoints, const QPointF& movePoint) -{ - QLineF segment{clickedPoints[0], movePoint}; - this->segmentGuide.setLine(segment); -} - -// PolylineInputMethod -PolylineInputMethod::PolylineInputMethod() : - CurveInputMethod(CurveType::Polyline, -1) -{ - this->appendGraphicsItem(&(this->polylineGuide)); - this->appendGraphicsItem(&(this->lastLine)); -} - -void PolylineInputMethod::beginInput() -{ - this->painterPath.clear(); - this->polylineGuide.setPath(this->painterPath); - this->lastLine.setLine(0, 0, 0, 0); - QPen pen = this->polylineGuide.pen(); - pen.setColor(this->color); - pen.setCosmetic(true); - this->polylineGuide.setPen(pen); - this->lastLine.setPen(pen); -} - -void PolylineInputMethod::updateVisualGuideMouseMoved( - const std::vector& clickedPoints, const QPointF& movePoint) -{ - this->lastLine.setLine(QLineF{clickedPoints.back(), movePoint}); -} - -void PolylineInputMethod::updateVisualGuideNewPoint( - const std::vector& points) -{ - if (points.size() == 1) - this->painterPath.moveTo(points.back()); - else - this->painterPath.lineTo(points.back()); - - this->polylineGuide.setPath(this->painterPath); -} - -// RayInputMethod -RayInputMethod::RayInputMethod() : CurveInputMethod(CurveType::Ray, 2) -{ - this->appendGraphicsItem(&(this->rayGuide)); -} - -void RayInputMethod::beginInput() -{ - this->rayGuide.setLine(0, 0, 0, 0); - QPen pen = this->rayGuide.pen(); - pen.setColor(this->color); - pen.setCosmetic(true); - this->rayGuide.setPen(pen); -} - -void RayInputMethod::updateVisualGuideMouseMoved( - const std::vector& clickedPoints, const QPointF& movePoint) -{ - float length = QLineF{clickedPoints[0], movePoint}.length(); - float dx = (movePoint.x() - clickedPoints[0].x()) / length; - float dy = (movePoint.y() - clickedPoints[0].y()) / length; - QRectF viewport = this->viewportRect(); - float r = std::sqrt( - viewport.width() * viewport.width() + - viewport.height() * viewport.height()); - QPointF endPoint = { - clickedPoints[0].x() + dx * r, clickedPoints[0].y() + dy * r}; - QLineF segment{clickedPoints[0], endPoint}; - this->rayGuide.setLine(segment); -} - -// LineInputMethod -LineInputMethod::LineInputMethod() : CurveInputMethod(CurveType::Line, 2) -{ - this->appendGraphicsItem(&(this->lineGuide)); -} - -void LineInputMethod::beginInput() -{ - this->lineGuide.setLine(0, 0, 0, 0); - QPen pen = this->lineGuide.pen(); - pen.setColor(this->color); - pen.setCosmetic(true); - this->lineGuide.setPen(pen); -} - -void LineInputMethod::updateVisualGuideMouseMoved( - const std::vector& clickedPoints, const QPointF& movePoint) -{ - float length = QLineF{clickedPoints[0], movePoint}.length(); - float dx = (clickedPoints[0].x() - movePoint.x()) / length; - float dy = (clickedPoints[0].y() - movePoint.y()) / length; - QRectF viewport = this->viewportRect(); - float r = std::sqrt( - viewport.width() * viewport.width() + - viewport.height() * viewport.height()); - QPointF endPoint = { - clickedPoints[0].x() + dx * r, clickedPoints[0].y() + dy * r}; - QPointF firstPoint = { - clickedPoints[0].x() - dx * r, clickedPoints[0].y() - dy * r}; - QLineF segment{firstPoint, endPoint}; - this->lineGuide.setLine(segment); -} - -// CircleInputMethod -CircleInputMethod::CircleInputMethod() : CurveInputMethod(CurveType::Circle, 2) -{ - this->appendGraphicsItem(&(this->circleGuide)); -} - -void CircleInputMethod::beginInput() -{ - this->circleGuide.setRect(0, 0, 0, 0); - QPen pen = this->circleGuide.pen(); - pen.setColor(this->color); - pen.setCosmetic(true); - this->circleGuide.setPen(pen); -} - -void CircleInputMethod::updateVisualGuideMouseMoved( - const std::vector& clickedPoints, const QPointF& movePoint) -{ - auto& center = clickedPoints.front(); - float radius = QLineF{center, movePoint}.length(); - this->circleGuide.setRect( - center.x() - radius, center.y() - radius, 2 * radius, 2 * radius); -} - -// EllipseInputMethod -EllipseInputMethod::EllipseInputMethod() : - CurveInputMethod(CurveType::Ellipse, 2) -{ - this->appendGraphicsItem(&(this->ellipseGuide)); -} - -void EllipseInputMethod::beginInput() -{ - this->ellipseGuide.setRect(0, 0, 0, 0); - QPen pen = this->ellipseGuide.pen(); - pen.setColor(this->color); - pen.setCosmetic(true); - this->ellipseGuide.setPen(pen); -} - -void EllipseInputMethod::updateVisualGuideMouseMoved( - const std::vector& clickedPoints, const QPointF& movePoint) -{ - this->ellipseGuide.setRect(QRectF{clickedPoints[0], movePoint}); -} - -// ThreePointCircularInputMethod -ThreePointCircularInputMethod::ThreePointCircularInputMethod() : - CurveInputMethod(CurveType::ThreePointCircularArc, 3) -{ -} - -// FivePointConicInputMethod -FivePointConicInputMethod::FivePointConicInputMethod() : - CurveInputMethod(CurveType::FivePointConicArc, 5) -{ -} - -// BezierInputMethod -BezierInputMethod::BezierInputMethod() : CurveInputMethod(CurveType::Bezier, -1) -{ - this->appendGraphicsItem(&(this->bezierGuide)); - this->appendGraphicsItem(&(this->bezierOldGuide)); -} - -void BezierInputMethod::beginInput() -{ - this->painterOldPath.clear(); - this->painterPath.clear(); - this->bezierGuide.setPath(this->painterPath); - this->bezierOldGuide.setPath(this->painterOldPath); - - QPen pen = this->bezierOldGuide.pen(); - pen.setColor(this->color); - pen.setCosmetic(true); - this->bezierOldGuide.setPen(pen); - - // TODO: set bezier guide color dynamically - pen = this->bezierGuide.pen(); - pen.setColor(QColorConstants::DarkGray); - pen.setCosmetic(true); - this->bezierGuide.setPen(pen); -} - -static QPointF evalBezier( - const std::vector& control_points, std::vector& cache, - float t) -{ - // iterative de Casteljau Algorithm - cache.clear(); - - for (size_t j = 0; j + 1 < control_points.size(); j++) - cache.push_back(control_points[j] * (1.0f - t) + control_points[j + 1] * t); - - for (size_t i = 1; i + 1 < control_points.size(); i++) - for (size_t j = 0; j + i + 1 < control_points.size(); j++) - cache[j] = cache[j] * (1.0f - t) + cache[j + 1] * t; - - return cache[0]; -} - -static float approx_pixel_length( - const std::vector& control_points, const QTransform& worldTransform) -{ - float l = 0; - for (size_t i = 0; i + 1 < control_points.size(); i++) - { - QPointF p1 = worldTransform.map(control_points[i]); - QPointF p2 = worldTransform.map(control_points[i + 1]); - l += QLineF{p1, p2}.length(); - } - return l; -} - -static void updateBezierPainterPath( - const std::vector& controlPoints, std::vector& cache, - const QTransform& worldTransform, QPainterPath& painterPath) -{ - painterPath.clear(); - if (controlPoints.size() < 2) return; - - float pixel_len = approx_pixel_length(controlPoints, worldTransform); - static constexpr int PIXEL_DIV = 4; - int num_segs = std::max(1, static_cast(pixel_len / PIXEL_DIV)); - - painterPath.moveTo(controlPoints[0]); - for (int i = 0; i < num_segs; i++) - painterPath.lineTo( - evalBezier(controlPoints, cache, static_cast(i + 1) / num_segs)); -} - -void BezierInputMethod::updateVisualGuideMouseMoved( - const std::vector& clickedPoints, const QPointF& movePoint) -{ - this->controlPoints.clear(); - std::copy( - clickedPoints.begin(), clickedPoints.end(), - std::back_inserter(this->controlPoints)); - this->controlPoints.push_back(movePoint); - - updateBezierPainterPath( - this->controlPoints, this->cache, this->getView()->transform(), - this->painterPath); - - this->bezierGuide.setPath(this->painterPath); -} - -void BezierInputMethod::updateVisualGuideNewPoint( - const std::vector& clickedPoints) -{ - updateBezierPainterPath( - clickedPoints, this->cache, this->getView()->transform(), - this->painterOldPath); - this->bezierOldGuide.setPath(this->painterPath); -} - template GraphicsViewCurveInput::GraphicsViewCurveInput( QObject* parent, QGraphicsScene* scene) : @@ -533,7 +120,6 @@ void GraphicsViewCurveInput::setPointSnapper( for_each(inputMethods, [&](auto&& it) { it.setPointSnapper(snapper_); }); } - template template void GraphicsViewCurveInput::setDefaultInputMethod(std::true_type) diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.h index 3edd8da01b2..ea485cce0e7 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.h @@ -13,13 +13,13 @@ #ifndef CGAL_QT_GRAPHICS_VIEW_CURVE_INPUT_H #define CGAL_QT_GRAPHICS_VIEW_CURVE_INPUT_H -#include #include #include #include #include #include +#include "CurveInputMethods.h" #include "Callback.h" #include "GraphicsSceneMixin.h" #include "PointsGraphicsItem.h" @@ -47,29 +47,6 @@ class Rational_traits; namespace Qt { -enum class CurveType -{ - Segment, - Polyline, - Ray, - Line, - Circle, - Ellipse, - ThreePointCircularArc, - FivePointConicArc, - AlgebraicEquation, - Bezier, - None, -}; - -class CurveInputMethodCallback -{ -public: - using Point_2 = PointSnapperBase::Point_2; - - virtual void curveInputDoneEvent( - const std::vector& clickedPoints, CurveType type) = 0; -}; class CurveGeneratorBase : public QObject, public CurveInputMethodCallback { @@ -190,181 +167,10 @@ struct CurveGenerator< CGAL::Object generateBezier(const std::vector&) override; }; -class CurveInputMethod : public GraphicsSceneMixin +class GraphicsViewCurveInputBase : public Callback { -public: - using Point_2 = PointSnapperBase::Point_2; + Q_OBJECT - CurveInputMethod(CurveType, int numPoints_ = -1); - virtual ~CurveInputMethod() { } - - void setCallback(CurveInputMethodCallback*); - void setPointSnapper(PointSnapperBase*); - CurveType curveType() const; - - virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event); - virtual void mousePressEvent(QGraphicsSceneMouseEvent* event); - void reset(); - void beginInput_(); - - void setColor(QColor); - QColor getColor() const; - - Point_2 snapPoint(QGraphicsSceneMouseEvent* event); - QPointF snapQPoint(QGraphicsSceneMouseEvent* event); - -protected: - virtual void beginInput(); - virtual void resetInput(); - virtual void updateVisualGuideNewPoint(const std::vector&); - virtual void - updateVisualGuideMouseMoved(const std::vector&, const QPointF&); - void appendGraphicsItem(QGraphicsItem* item); - -protected: - QColor color; - -private: - const int numPoints; - std::vector clickedPoints; - std::vector clickedBigPoints; - PointsGraphicsItem pointsGraphicsItem; - CurveInputMethodCallback* callback; - const CurveType type; - std::vector items; - bool itemsAdded; - PointSnapperBase* snapper; -}; - -class SegmentInputMethod : public CurveInputMethod -{ -public: - SegmentInputMethod(); - - void beginInput() override; - - void updateVisualGuideMouseMoved( - const std::vector& clickedPoints, - const QPointF& movePoint) override; - -private: - QGraphicsLineItem segmentGuide; -}; - -class RayInputMethod : public CurveInputMethod -{ -public: - RayInputMethod(); - - void beginInput() override; - - void updateVisualGuideMouseMoved( - const std::vector& clickedPoints, - const QPointF& movePoint) override; - -private: - QGraphicsLineItem rayGuide; -}; - -class LineInputMethod : public CurveInputMethod -{ -public: - LineInputMethod(); - - void beginInput() override; - - void updateVisualGuideMouseMoved( - const std::vector& clickedPoints, - const QPointF& movePoint) override; - -private: - QGraphicsLineItem lineGuide; -}; - -class PolylineInputMethod : public CurveInputMethod -{ -public: - PolylineInputMethod(); - - void beginInput() override; - - void updateVisualGuideMouseMoved( - const std::vector& clickedPoints, - const QPointF& movePoint) override; - - void updateVisualGuideNewPoint(const std::vector&) override; - -private: - QGraphicsPathItem polylineGuide; - QGraphicsLineItem lastLine; - QPainterPath painterPath; -}; - -class CircleInputMethod : public CurveInputMethod -{ -public: - CircleInputMethod(); - - void beginInput() override; - - void updateVisualGuideMouseMoved( - const std::vector& clickedPoints, - const QPointF& movePoint) override; - -private: - QGraphicsEllipseItem circleGuide; -}; - -class EllipseInputMethod : public CurveInputMethod -{ -public: - EllipseInputMethod(); - - void beginInput() override; - - void updateVisualGuideMouseMoved( - const std::vector& clickedPoints, - const QPointF& movePoint) override; - -private: - QGraphicsEllipseItem ellipseGuide; -}; - -class ThreePointCircularInputMethod : public CurveInputMethod -{ -public: - ThreePointCircularInputMethod(); -}; - -class FivePointConicInputMethod : public CurveInputMethod -{ -public: - FivePointConicInputMethod(); -}; - -class BezierInputMethod : public CurveInputMethod -{ -public: - BezierInputMethod(); - void beginInput() override; - void updateVisualGuideNewPoint(const std::vector&) override; - void updateVisualGuideMouseMoved( - const std::vector& clickedPoints, - const QPointF& movePoint) override; - -private: - QGraphicsPathItem bezierOldGuide; - QGraphicsPathItem bezierGuide; - QPainterPath painterOldPath; - QPainterPath painterPath; - std::vector controlPoints; - std::vector cache; -}; - -class GraphicsViewCurveInputBase : - public GraphicsViewInput, - public GraphicsSceneMixin -{ public: GraphicsViewCurveInputBase(QObject* parent, QGraphicsScene* scene); @@ -373,6 +179,9 @@ public: virtual void setCurveType(CurveType type) = 0; virtual void setPointSnapper(PointSnapperBase*) = 0; +Q_SIGNALS: + void generate(CGAL::Object); + protected: GraphicsViewCurveInputBase(QObject* parent); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event); diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.cpp index e58cd6b8172..d1422362d45 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.cpp @@ -1,8 +1,7 @@ #include "MergeEdgeCallback.h" #include "ArrangementTypes.h" #include "CurveGraphicsItem.h" -#include -#include +#include #include #include "Utils.h" diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.h index 6c05183b5ff..812d467e725 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.h @@ -13,7 +13,6 @@ #define MERGE_EDGE_CALLBACK_H #include "Callback.h" -#include namespace CGAL { diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointLocationFunctions.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointLocationFunctions.cpp index 2114a664e66..0bf5a288909 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointLocationFunctions.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointLocationFunctions.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include @@ -42,15 +43,15 @@ static auto toKernelPoint(const QPointF& pt) } template -CGAL::Object -PointLocationFunctions::locate(const Arrangement* arr, const QPointF& pt) +CGAL::Object PointLocationFunctions::locate( + const Arrangement* arr, const Kernel_point_2& pt) { using SupportsLandmarks = typename Supports_landmarks::Tag; using PointLocationStrategy = typename StrategyHelper::type; Arr_construct_point_2 toArrPoint; - auto arr_point = toArrPoint(toKernelPoint(pt)); + auto arr_point = toArrPoint(pt); PointLocationStrategy pointLocationStrategy{*arr}; return pointLocationStrategy.locate(arr_point); @@ -58,7 +59,7 @@ PointLocationFunctions::locate(const Arrangement* arr, const QPointF& pt) template auto PointLocationFunctions::getFace( - const Arrangement* arr, const QPointF& pt) -> Face_const_handle + const Arrangement* arr, const Kernel_point_2& pt) -> Face_const_handle { CGAL::Object obj = locate(arr, pt); @@ -77,6 +78,20 @@ auto PointLocationFunctions::getFace( return (eit->face()); } +template +CGAL::Object +PointLocationFunctions::locate(const Arrangement* arr, const QPointF& pt) +{ + return this->locate(arr, toKernelPoint(pt)); +} + +template +auto PointLocationFunctions::getFace( + const Arrangement* arr, const QPointF& pt) -> Face_const_handle +{ + return this->getFace(arr, toKernelPoint(pt)); +} + template CGAL::Object PointLocationFunctions::rayShootUp( const Arrangement* arr, const QPointF& pt) diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointLocationFunctions.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointLocationFunctions.h index fd0371e050c..fb2796977ec 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointLocationFunctions.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointLocationFunctions.h @@ -2,6 +2,7 @@ #define ARRANGEMENT_DEMO_POINT_LOCATION_FUNCTIONS #include +#include "ArrTraitsAdaptor.h" class QPointF; @@ -15,8 +16,13 @@ struct PointLocationFunctions using Vertex_const_handle = typename Arrangement::Vertex_const_handle; using Halfedge_around_vertex_const_circulator = typename Arrangement::Halfedge_around_vertex_const_circulator; + using Kernel = typename ArrTraitsAdaptor::Kernel; + using Kernel_point_2 = typename Kernel::Point_2; + // the QPointF versions are for convenience + CGAL::Object locate(const Arrangement*, const Kernel_point_2&); CGAL::Object locate(const Arrangement*, const QPointF&); + Face_const_handle getFace(const Arrangement*, const Kernel_point_2&); Face_const_handle getFace(const Arrangement*, const QPointF&); CGAL::Object rayShootUp(const Arrangement*, const QPointF&); CGAL::Object rayShootDown(const Arrangement*, const QPointF&); diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointSnapper.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointSnapper.cpp index 15d5a68436b..e09d01b80bb 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointSnapper.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/PointSnapper.cpp @@ -159,8 +159,8 @@ struct SnapToArrangement { using Point_2 = PointSnapperBase::Point_2; template - boost::optional operator()( - const QPointF& qpt, const QTransform& worldTransform, Arrangement* arr) + boost::optional + operator()(const QPointF& qpt, const QTransform&, Arrangement*) { return Point_2{qpt.x(), qpt.y()}; } diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.cpp index 811b43b4b3a..45f83306424 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.cpp @@ -15,8 +15,7 @@ #include #include -#include -#include + SplitEdgeCallbackBase::SplitEdgeCallbackBase( QObject* parent ) : CGAL::Qt::Callback( parent ) diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.h index 762e5e03b87..b51e5737a9a 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.h @@ -12,14 +12,13 @@ #ifndef SPLIT_EDGE_CALLBACK_H #define SPLIT_EDGE_CALLBACK_H -#include "Callback.h" #include "GraphicsViewCurveInput.h" -#include class QGraphicsSceneMouseEvent; class QGraphicsScene; class QGraphicsLineItem; class PointSnapperBase; +class QColor; namespace CGAL { diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.cpp index b29c3511fbc..11c3faed4ff 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.cpp @@ -12,10 +12,8 @@ #include "Utils.h" #include "ArrangementTypes.h" #include "ArrangementPainterOstream.h" +#include "PointLocationFunctions.h" -#include - -#include #include template @@ -249,13 +247,9 @@ template auto Find_nearest_edge::operator()(const Point_2& queryPt) -> Halfedge_const_handle { - typedef CGAL::Arr_walk_along_line_point_location - Point_location_strategy; + Face_const_handle face = + PointLocationFunctions{}.getFace(arr, queryPt); - typename ArrTraits::Point_2 pt = this->toArrPoint(queryPt); - Point_location_strategy pointLocationStrategy{*arr}; - CGAL::Object pointLocationResult = pointLocationStrategy.locate(pt); - Face_const_handle face = this->getFace(pointLocationResult); bool first = 1; X_monotone_curve_2 closestCurve; Halfedge_const_handle closestEdge; @@ -561,8 +555,7 @@ auto Arr_compute_y_at_x_2::operator()( template auto Arr_compute_y_at_x_2>:: -operator()( - const X_monotone_curve_2& curve, const CoordinateType& x, Point_2* out) +operator()(const X_monotone_curve_2& curve, const CoordinateType& x) -> CoordinateType { CGAL::Object o; @@ -575,7 +568,6 @@ operator()( { Point_2 p = res.first; CoordinateType coord = p.y(); - if (out) *out = p; return coord; } else @@ -627,7 +619,7 @@ static inline auto get_t_range(const Bezier_x_monotone_2& curve) template auto Arr_compute_y_at_x_2< CGAL::Arr_Bezier_curve_traits_2>:: -operator()(const X_monotone_curve_2& curve, const Rational& x, Point_2* out) +operator()(const X_monotone_curve_2& curve, const Rational& x) -> Algebraic { auto&& supp_curve = curve.supporting_curve(); diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.h index 8a366c74ac2..0efba2d9eda 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.h @@ -10,95 +10,12 @@ #ifndef CGAL_ARRANGEMENTS_DEMO_UTILS_H #define CGAL_ARRANGEMENTS_DEMO_UTILS_H -#include -#include -#include - #include "ArrangementDemoGraphicsView.h" #include "ArrangementTypes.h" #include "GraphicsSceneMixin.h" +#include "ArrTraitsAdaptor.h" class QGraphicsScene; -class QGraphicsSceneMouseEvent; - -/** - Support for new ArrTraits should specify types: - - * Kernel - a not-necessarily-exact kernel to represent the arrangement - graphically. We'll use the Point_2 type provided by this kernel for - computing distances - * Point_2 - the point type used in the particular arrangement - * CoordinateType - the coordinate type used by the point type - */ -template -class ArrTraitsAdaptor -{ }; - -template -class ArrTraitsAdaptor< CGAL::Arr_segment_traits_2< Kernel_ > > -{ -public: - typedef Kernel_ Kernel; - typedef CGAL::Arr_segment_traits_2< Kernel > ArrTraits; - typedef typename ArrTraits::Point_2 Point_2; - typedef typename Kernel::FT CoordinateType; -}; - -template -class ArrTraitsAdaptor< CGAL::Arr_linear_traits_2< Kernel_ > > -{ -public: - typedef Kernel_ Kernel; - typedef CGAL::Arr_linear_traits_2< Kernel > ArrTraits; - typedef typename ArrTraits::Point_2 Point_2; - typedef typename Kernel::FT CoordinateType; -}; - -template -class ArrTraitsAdaptor< CGAL::Arr_polyline_traits_2< SegmentTraits > > -{ -public: - typedef CGAL::Arr_polyline_traits_2< SegmentTraits > ArrTraits; - typedef typename SegmentTraits::Kernel Kernel; - typedef typename ArrTraits::Point_2 Point_2; - typedef typename Kernel::FT CoordinateType; -}; - -template -class ArrTraitsAdaptor< CGAL::Arr_conic_traits_2< RatKernel, AlgKernel, - NtTraits > > -{ -public: - typedef CGAL::Arr_conic_traits_2< RatKernel, AlgKernel, NtTraits > ArrTraits; - typedef AlgKernel Kernel; - typedef typename ArrTraits::Point_2 Point_2; - typedef typename Kernel::FT CoordinateType; -}; - -template -class ArrTraitsAdaptor< - CGAL::Arr_Bezier_curve_traits_2> -{ -public: - typedef CGAL::Arr_Bezier_curve_traits_2 - ArrTraits; - typedef RatKernel Kernel; - typedef typename ArrTraits::Point_2 Point_2; - typedef typename Kernel::FT CoordinateType; -}; - -template -class ArrTraitsAdaptor< CGAL::Arr_algebraic_segment_traits_2< Coefficient_ > > -{ -public: - typedef Coefficient_ Coefficient; - typedef typename CGAL::Arr_algebraic_segment_traits_2 - ArrTraits; - typedef typename ArrTraits::Point_2 Point_2; // CKvA_2 - typedef typename ArrTraits::Algebraic_real_1 CoordinateType; - typedef CGAL::Cartesian< typename ArrTraits::Bound > Kernel; - //typedef typename ArrTraits::CKvA_2 Kernel; -}; template class Arr_compute_y_at_x_2 : public GraphicsSceneMixin @@ -153,9 +70,8 @@ public: typedef typename Traits::Multiplicity Multiplicity; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; - CoordinateType operator()( - const X_monotone_curve_2& curve, const CoordinateType& x, - Point_2* out = nullptr); + CoordinateType + operator()(const X_monotone_curve_2& curve, const CoordinateType& x); double approx(const X_monotone_curve_2& curve, const CoordinateType& x); @@ -176,8 +92,7 @@ struct Arr_compute_y_at_x_2< typedef typename Traits::Algebraic Algebraic; typedef typename Traits::Point_2 Point_2; - Algebraic operator()( - const X_monotone_curve_2& curve, const Rational& x, Point_2* out = nullptr); + Algebraic operator()(const X_monotone_curve_2& curve, const Rational& x); Algebraic get_t(const X_monotone_curve_2& curve, const Rational& x); double approx(const X_monotone_curve_2& curve, const Rational& x); @@ -316,8 +231,8 @@ public: Multivariate_content; typedef typename Polynomial_traits_2::Substitute Substitute; typedef typename Polynomial_traits_2:: - Construct_innermost_coefficient_const_iterator_range - ConstructInnerCoeffIter; + Construct_innermost_coefficient_const_iterator_range + ConstructInnerCoeffIter; public: double operator()(const Point_2& p, const X_monotone_curve_2& c) const; diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/VerticalRayShootCallback.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/VerticalRayShootCallback.cpp index 20efb155281..5b3ae6edbd7 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/VerticalRayShootCallback.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/VerticalRayShootCallback.cpp @@ -14,9 +14,7 @@ #include "Utils.h" #include "PointLocationFunctions.h" -#include #include -#include #include #include @@ -123,18 +121,8 @@ template void VerticalRayShootCallback::highlightPointLocation( QGraphicsSceneMouseEvent* event) { - // minimizing #includes in in the header file - // Utils.h and ArrangementTypes.h are disasters - typedef typename ArrTraitsAdaptor< Traits >::Kernel Kernel; - typedef typename ArrTraitsAdaptor< Traits >::CoordinateType CoordinateType; - typedef typename Kernel::Point_2 Kernel_point_2; - typedef typename Traits::Point_2 Point_2; - typedef typename Kernel::Segment_2 Segment_2; - typedef typename Kernel::FT FT; - this->highlightedCurves->clear(); QPointF queryQPt = event->scenePos(); - Kernel_point_2 queryPt = CGAL::Qt::Converter{}(queryQPt); CGAL::Object pointLocationResult; if (this->shootingUp) @@ -147,24 +135,22 @@ void VerticalRayShootCallback::highlightPointLocation( if (pointLocationResult.is_empty()) { return; } QRectF viewportRect = this->viewportRect(); - FT y2; + qreal y2; if (this->shootingUp) { // +y in Qt is towards the bottom - y2 = FT(viewportRect.bottom()); + y2 = viewportRect.bottom(); } else { - y2 = FT(viewportRect.top()); + y2 = viewportRect.top(); } Face_const_handle unboundedFace; Halfedge_const_handle halfedge; Vertex_const_handle vertex; if (CGAL::assign(unboundedFace, pointLocationResult)) { - Kernel_point_2 p2(FT(queryPt.x()), y2); - Segment_2 lineSegment(queryPt, p2); - this->rayGraphicsItem.setSource(event->scenePos()); - this->rayGraphicsItem.setTargetY(CGAL::to_double(y2)); + this->rayGraphicsItem.setSource(queryQPt); + this->rayGraphicsItem.setTargetY(y2); this->rayGraphicsItem.setIsInfinite(true); } else if (CGAL::assign(halfedge, pointLocationResult)) @@ -174,21 +160,16 @@ void VerticalRayShootCallback::highlightPointLocation( // draw a ray from the clicked point to the hit curve Arr_compute_y_at_x_2 compute_y_at_x_2; compute_y_at_x_2.setScene(this->getScene()); - CoordinateType x(queryPt.x()); - double yApprox = - CGAL::to_double(compute_y_at_x_2.approx(halfedge->curve(), x)); - FT yInt(yApprox); - Kernel_point_2 p2(queryPt.x(), yInt); - Segment_2 seg(queryPt, p2); - this->rayGraphicsItem.setSource(event->scenePos()); - this->rayGraphicsItem.setTargetY(CGAL::to_double(yInt)); + double yApprox = compute_y_at_x_2.approx(halfedge->curve(), queryQPt.x()); + this->rayGraphicsItem.setSource(queryQPt); + this->rayGraphicsItem.setTargetY(yApprox); this->rayGraphicsItem.setIsInfinite(false); } else if (CGAL::assign(vertex, pointLocationResult)) { if (!vertex->is_at_open_boundary()) { - Point_2 pt = vertex->point(); + auto pt = vertex->point(); this->highlightedCurves->insert(pt); } }