This commit is contained in:
Ahmed Essam 2020-08-20 15:07:04 +02:00
parent 4e3c64f488
commit 2a9238fa33
29 changed files with 951 additions and 961 deletions

View File

@ -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 <alextsui05@gmail.com>
#ifndef CGAL_ARRANGEMENTS_ARR_TRAITS_ADAPTOR_H
#define CGAL_ARRANGEMENTS_ARR_TRAITS_ADAPTOR_H
#include <CGAL/Cartesian.h>
namespace CGAL
{
template <typename Kernel_>
class Arr_segment_traits_2;
template <typename Kernel_>
class Arr_linear_traits_2;
template <typename SegmentTraits_2>
class Arr_polyline_traits_2;
template <class Rat_kernel_, class Alg_kernel_, class Nt_traits_>
class Arr_conic_traits_2;
template <
typename RatKernel_, typename AlgKernel_, typename NtTraits_,
typename BoundingTraits_>
class Arr_Bezier_curve_traits_2;
template <class Coefficient_>
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 <typename ArrTraits>
class ArrTraitsAdaptor
{
};
template <typename Kernel_>
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 <typename Kernel_>
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 <typename SegmentTraits>
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 <typename RatKernel, typename AlgKernel, typename NtTraits>
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 <
typename RatKernel, typename AlgKernel, typename NtTraits,
typename BoundingTraits>
class ArrTraitsAdaptor<CGAL::Arr_Bezier_curve_traits_2<
RatKernel, AlgKernel, NtTraits, BoundingTraits>>
{
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 <typename Coefficient_>
class ArrTraitsAdaptor<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>
{
public:
typedef Coefficient_ Coefficient;
typedef typename CGAL::Arr_algebraic_segment_traits_2<Coefficient> ArrTraits;
typedef typename ArrTraits::Point_2 Point_2; // CKvA_2
typedef typename ArrTraits::Algebraic_real_1 CoordinateType;
typedef CGAL::Cartesian<typename ArrTraits::Bound> Kernel;
};
#endif

View File

@ -12,7 +12,6 @@
#ifndef ARRANGEMENT_CURVE_INPUT_CALLBACK_H
#define ARRANGEMENT_CURVE_INPUT_CALLBACK_H
#include <CGAL/Qt/GraphicsViewInput.h>
#include "GraphicsViewCurveInput.h"
template <typename Arr_>
@ -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<Arrangement> 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:

View File

@ -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<CGAL::Qt::Callback*>(this->activeCallback);
if (callback) { callback->reset(); }
else
{
auto curveInput = dynamic_cast<CGAL::Qt::GraphicsViewCurveInputBase*>(
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<QObject*>(this->deleteCurveCallback.get()))
static_cast<CGAL::Qt::Callback*>(this->deleteCurveCallback.get()))
{
auto deleteMode = this->deleteCurveCallback->getDeleteMode();
if (deleteMode == DeleteMode::DeleteOriginatingCuve)
@ -448,7 +414,7 @@ static const auto& getXyCurves()
template <class Arr_>
CGAL::Bbox_2
findOtherInterestingPoints(const std::unique_ptr<Arr_>& arr)
findOtherInterestingPoints(const std::unique_ptr<Arr_>&)
{
return {};
}
@ -493,7 +459,7 @@ static CGAL::Bbox_2 curvesBbox(const std::unique_ptr<Arr>& arr)
}
template <>
CGAL::Bbox_2 curvesBbox(const std::unique_ptr<demo_types::Bezier_arr>& arr)
CGAL::Bbox_2 curvesBbox(const std::unique_ptr<demo_types::Bezier_arr>&)
{
return {};
}

View File

@ -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<FillFaceCallbackBase> fillFaceCallback;
std::unique_ptr<PointSnapperBase> snapper;
QObject* activeCallback;
CGAL::Qt::Callback* activeCallback;
CGAL::Qt::ArrangementGraphicsItemBase* arrangementGraphicsItem;
GridGraphicsItem* gridGraphicsItem;
}; // class ArrangementDemoTabBase

View File

@ -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 <CGAL/IO/Arr_with_history_text_formatter.h>
#include <CGAL/Arr_default_overlay_traits.h>
#include <CGAL/Arr_overlay_2.h>
#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

View File

@ -80,13 +80,13 @@ paint(QPainter* painter,
const QStyleOptionGraphicsItem* /* option */,
QWidget* /*widget*/)
{
this->paint( painter, Traits( ) );
this->paint( painter, arr->traits() );
}
template <typename Arr_>
template <typename TTraits>
void ArrangementGraphicsItem<Arr_>::paint(
QPainter* painter, TTraits /* traits */)
QPainter* painter, const TTraits* /* traits */)
{
this->paintFaces(painter);
@ -106,7 +106,7 @@ void ArrangementGraphicsItem<Arr_>::paint(
template <typename Arr_>
template <typename Coefficient_>
void ArrangementGraphicsItem<Arr_>::paint(
QPainter* painter, CGAL::Arr_algebraic_segment_traits_2<Coefficient_> traits)
QPainter* painter, const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>*)
{
auto windowRect = painter->window();
auto width = windowRect.width();
@ -156,10 +156,10 @@ void ArrangementGraphicsItem<Arr_>::paint(
template <typename Arr_>
void ArrangementGraphicsItem<Arr_>::paintFaces(QPainter* painter, QImage& image)
{
QRgb* st = reinterpret_cast<QRgb*>(tempImage.bits());
QRgb* st = reinterpret_cast<QRgb*>(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<Arr_>::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<double>::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 <typename Arr_>
template <typename RatK, typename AlgK, typename Nt, typename BoundingTratits>
void ArrangementGraphicsItem<Arr_>::updateBoundingBox(
CGAL::Arr_Bezier_curve_traits_2<RatK, AlgK, Nt, BoundingTratits> /* traits */)
const CGAL::Arr_Bezier_curve_traits_2<RatK, AlgK, Nt, BoundingTratits>*)
{
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 <typename Arr_>
template <typename Kernel_>
void ArrangementGraphicsItem<Arr_>::updateBoundingBox(
CGAL::Arr_linear_traits_2<Kernel_>)
const CGAL::Arr_linear_traits_2<Kernel_>*)
{
this->prepareGeometryChange( );
constexpr double max_double = std::numeric_limits<double>::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 <typename Arr_>
template <typename Kernel_>
void ArrangementGraphicsItem<Arr_>::paintFace(
Face_handle f, QPainter* painter, const CGAL::Arr_polyline_traits_2<Kernel_>*)
{
if (!f->is_unbounded())
{
@ -450,7 +452,7 @@ template < typename Arr_ >
template <typename Coefficient_>
void ArrangementGraphicsItem<Arr_>::paintFace(
Face_handle f, QPainter* painter,
CGAL::Arr_algebraic_segment_traits_2<Coefficient_> /* traits */)
const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>* /* traits */)
{
if (f->is_unbounded()) return;
@ -550,7 +552,7 @@ template <typename Arr_>
template <typename RatKernel, typename AlgKernel, typename NtTraits>
void ArrangementGraphicsItem<Arr_>::paintFace(
Face_handle f, QPainter* painter,
CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>)
const CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>*)
{
if (!f->is_unbounded()) // f is not the unbounded face
{
@ -647,8 +649,8 @@ template <
typename BoundingTraits>
void ArrangementGraphicsItem<Arr_>::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 <typename Arr_>
template <typename Kernel_>
void ArrangementGraphicsItem<Arr_>::paintFace(
Face_handle f, QPainter* painter,
CGAL::Arr_linear_traits_2<Kernel_> /* traits */)
const CGAL::Arr_linear_traits_2<Kernel_>* /* traits */)
{
QVector<QPointF> pts; // holds the points of the polygon
QColor color = f->color();

View File

@ -97,22 +97,23 @@ protected:
void updatePointsItem();
template <typename TTraits>
void paint(QPainter*, TTraits);
void paint(QPainter*, const TTraits*);
template <typename Coefficient_>
void paint(QPainter*, CGAL::Arr_algebraic_segment_traits_2<Coefficient_>);
void
paint(QPainter*, const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>*);
void updateBoundingBox();
template <typename TTraits>
void updateBoundingBox(TTraits);
void updateBoundingBox(const TTraits*);
template <typename RatK, typename AlgK, typename Nt, typename BoundingTratits>
void updateBoundingBox(
CGAL::Arr_Bezier_curve_traits_2<RatK, AlgK, Nt, BoundingTratits>);
const CGAL::Arr_Bezier_curve_traits_2<RatK, AlgK, Nt, BoundingTratits>*);
template <typename Kernel_>
void updateBoundingBox(CGAL::Arr_linear_traits_2<Kernel_>);
void updateBoundingBox(const CGAL::Arr_linear_traits_2<Kernel_>*);
void paintFaces(QPainter* painter);
@ -132,34 +133,36 @@ protected:
template <typename Kernel_>
void paintFace(
Face_handle f, QPainter* painter, CGAL::Arr_segment_traits_2<Kernel_>);
Face_handle f, QPainter* painter,
const CGAL::Arr_segment_traits_2<Kernel_>*);
template <typename Kernel_>
void paintFace(
Face_handle f, QPainter* painter, CGAL::Arr_polyline_traits_2<Kernel_>);
Face_handle f, QPainter* painter,
const CGAL::Arr_polyline_traits_2<Kernel_>*);
template <typename RatKernel, typename AlgKernel, typename NtTraits>
void paintFace(
Face_handle f, QPainter* painter,
CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>);
const CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>*);
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 <typename Coefficient_>
void paintFace(
Face_handle f, QPainter* painter,
CGAL::Arr_algebraic_segment_traits_2<Coefficient_> /* traits */);
const CGAL::Arr_algebraic_segment_traits_2<Coefficient_>*);
template <typename Kernel_>
void paintFace(
Face_handle f, QPainter* painter,
CGAL::Arr_linear_traits_2<Kernel_> /* traits */);
const CGAL::Arr_linear_traits_2<Kernel_>*);
protected:
Arrangement* arr;

View File

@ -1,7 +1,4 @@
#include "ArrangementPainterOstream.h"
#include <CGAL/Kernel/global_functions.h>
#include <CGAL/Qt/Converter.h>
#include <CGAL/Curved_kernel_via_analysis_2/Curve_renderer_facade.h>
namespace CGAL {

View File

@ -15,7 +15,6 @@
#include <vector>
#include <CGAL/Qt/PainterOstream.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arr_polyline_traits_2.h>
#include <CGAL/Arr_conic_traits_2.h>

View File

@ -12,8 +12,6 @@
#ifndef ARRANGEMENT_DEMO_TYPES_H
#define ARRANGEMENT_DEMO_TYPES_H
#include <CGAL/basic.h>
#include <CGAL/Arrangement_with_history_2.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Arr_default_dcel.h>
@ -76,12 +74,12 @@ public:
// less specializations, and makes PointSnapper untemplated
#ifdef CGAL_USE_CORE
typedef CORE::BigRat Rational;
typedef CGAL::Cartesian<Rational> Rat_kernel;
#else
typedef CGAL::Exact_rational Rational;
typedef CGAL::Cartesian<CGAL::Exact_rational> Rat_kernel;
#endif
typedef CGAL::Cartesian<Rational> Rat_kernel;
// Segments:
typedef CGAL::Arr_segment_traits_2<Rat_kernel> Seg_traits;
typedef Dcel<Seg_traits> Seg_dcel;

View File

@ -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()

View File

@ -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( ) { }

View File

@ -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:

View File

@ -14,8 +14,6 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <list>
#include <string>
#include <CGAL/Bbox_2.h>

View File

@ -41,10 +41,9 @@ void CurveGraphicsItem<ArrTraits>::paint(
template <class ArrTraits>
QRectF CurveGraphicsItem<ArrTraits>::boundingRect() const
{
typedef typename ArrTraitsAdaptor<Traits>::Kernel Kernel;
CGAL::Qt::Converter<Kernel> convert;
QRectF boundingRectangle = convert(this->boundingBox);
return boundingRectangle;
return {
QPointF{this->boundingBox.xmin(), this->boundingBox.ymin()},
QPointF{this->boundingBox.xmax(), this->boundingBox.ymax()}};
}
template <class ArrTraits>

View File

@ -0,0 +1,416 @@
#include "CurveInputMethods.h"
#include <QEvent>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
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<size_t>(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<QPointF>&) {
}
void CurveInputMethod::updateVisualGuideMouseMoved(
const std::vector<QPointF>&, 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<QPointF>& 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<QPointF>& clickedPoints, const QPointF& movePoint)
{
this->lastLine.setLine(QLineF{clickedPoints.back(), movePoint});
}
void PolylineInputMethod::updateVisualGuideNewPoint(
const std::vector<QPointF>& 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<QPointF>& 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<QPointF>& 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<QPointF>& 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<QPointF>& 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<QPointF>& control_points, std::vector<QPointF>& 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<QPointF>& 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<QPointF>& controlPoints, std::vector<QPointF>& 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<int>(pixel_len / PIXEL_DIV));
painterPath.moveTo(controlPoints[0]);
for (int i = 0; i < num_segs; i++)
painterPath.lineTo(
evalBezier(controlPoints, cache, static_cast<float>(i + 1) / num_segs));
}
void BezierInputMethod::updateVisualGuideMouseMoved(
const std::vector<QPointF>& 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<QPointF>& clickedPoints)
{
updateBezierPainterPath(
clickedPoints, this->cache, this->getView()->transform(),
this->painterOldPath);
this->bezierOldGuide.setPath(this->painterPath);
}
} // namespace Qt
} // namespace CGAL

View File

@ -0,0 +1,217 @@
#ifndef ARRANGEMENT_DEMO_CURVE_INPUT_METHODS_H
#define ARRANGEMENT_DEMO_CURVE_INPUT_METHODS_H
#include <QGraphicsLineItem>
#include <vector>
#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<Point_2>& 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<QPointF>&);
virtual void
updateVisualGuideMouseMoved(const std::vector<QPointF>&, const QPointF&);
void appendGraphicsItem(QGraphicsItem* item);
protected:
QColor color;
private:
const int numPoints;
std::vector<QPointF> clickedPoints;
std::vector<Point_2> clickedBigPoints;
PointsGraphicsItem pointsGraphicsItem;
CurveInputMethodCallback* callback;
const CurveType type;
std::vector<QGraphicsItem*> items;
bool itemsAdded;
PointSnapperBase* snapper;
};
class SegmentInputMethod : public CurveInputMethod
{
public:
SegmentInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
private:
QGraphicsLineItem segmentGuide;
};
class RayInputMethod : public CurveInputMethod
{
public:
RayInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
private:
QGraphicsLineItem rayGuide;
};
class LineInputMethod : public CurveInputMethod
{
public:
LineInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
private:
QGraphicsLineItem lineGuide;
};
class PolylineInputMethod : public CurveInputMethod
{
public:
PolylineInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
void updateVisualGuideNewPoint(const std::vector<QPointF>&) override;
private:
QGraphicsPathItem polylineGuide;
QGraphicsLineItem lastLine;
QPainterPath painterPath;
};
class CircleInputMethod : public CurveInputMethod
{
public:
CircleInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
private:
QGraphicsEllipseItem circleGuide;
};
class EllipseInputMethod : public CurveInputMethod
{
public:
EllipseInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& 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<QPointF>&) override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
private:
QGraphicsPathItem bezierOldGuide;
QGraphicsPathItem bezierGuide;
QPainterPath painterOldPath;
QPainterPath painterPath;
std::vector<QPointF> controlPoints;
std::vector<QPointF> cache;
};
} // namespace Qt
} // namespace CGAL
#endif

View File

@ -11,21 +11,10 @@
#include "GraphicsViewCurveInput.h"
#include "ArrangementTypes.h"
#include <CGAL/Arr_Bezier_curve_traits_2.h>
#include <CGAL/Arr_algebraic_segment_traits_2.h>
#include <CGAL/Arr_conic_traits_2.h>
#include <CGAL/Arr_linear_traits_2.h>
#include <CGAL/Arr_polyline_traits_2.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/CORE/BigRat.h>
#include <CGAL/CORE_algebraic_number_traits.h>
#include <CGAL/Qt/Converter.h>
#include <QEvent>
#include "QtMetaTypes.h"
#include <QGraphicsView>
// TODO(Ahmed Essam): move these somewhere else!
// TODO: move these somewhere else!
template <std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
for_each(std::tuple<Tp...>&, 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<size_t>(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<QPointF>&) {
}
void CurveInputMethod::updateVisualGuideMouseMoved(
const std::vector<QPointF>&, 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<QPointF>& 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<QPointF>& clickedPoints, const QPointF& movePoint)
{
this->lastLine.setLine(QLineF{clickedPoints.back(), movePoint});
}
void PolylineInputMethod::updateVisualGuideNewPoint(
const std::vector<QPointF>& 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<QPointF>& 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<QPointF>& 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<QPointF>& 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<QPointF>& 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<QPointF>& control_points, std::vector<QPointF>& 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<QPointF>& 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<QPointF>& controlPoints, std::vector<QPointF>& 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<int>(pixel_len / PIXEL_DIV));
painterPath.moveTo(controlPoints[0]);
for (int i = 0; i < num_segs; i++)
painterPath.lineTo(
evalBezier(controlPoints, cache, static_cast<float>(i + 1) / num_segs));
}
void BezierInputMethod::updateVisualGuideMouseMoved(
const std::vector<QPointF>& 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<QPointF>& clickedPoints)
{
updateBezierPainterPath(
clickedPoints, this->cache, this->getView()->transform(),
this->painterOldPath);
this->bezierOldGuide.setPath(this->painterPath);
}
template <typename ArrTraits>
GraphicsViewCurveInput<ArrTraits>::GraphicsViewCurveInput(
QObject* parent, QGraphicsScene* scene) :
@ -533,7 +120,6 @@ void GraphicsViewCurveInput<ArrTraits>::setPointSnapper(
for_each(inputMethods, [&](auto&& it) { it.setPointSnapper(snapper_); });
}
template <typename ArrTraits>
template <typename>
void GraphicsViewCurveInput<ArrTraits>::setDefaultInputMethod(std::true_type)

View File

@ -13,13 +13,13 @@
#ifndef CGAL_QT_GRAPHICS_VIEW_CURVE_INPUT_H
#define CGAL_QT_GRAPHICS_VIEW_CURVE_INPUT_H
#include <CGAL/Qt/GraphicsViewInput.h>
#include <QGraphicsLineItem>
#include <QGraphicsSceneMouseEvent>
#include <tuple>
#include <type_traits>
#include <vector>
#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<Point_2>& clickedPoints, CurveType type) = 0;
};
class CurveGeneratorBase : public QObject, public CurveInputMethodCallback
{
@ -190,181 +167,10 @@ struct CurveGenerator<
CGAL::Object generateBezier(const std::vector<Point_2>&) 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<QPointF>&);
virtual void
updateVisualGuideMouseMoved(const std::vector<QPointF>&, const QPointF&);
void appendGraphicsItem(QGraphicsItem* item);
protected:
QColor color;
private:
const int numPoints;
std::vector<QPointF> clickedPoints;
std::vector<Point_2> clickedBigPoints;
PointsGraphicsItem pointsGraphicsItem;
CurveInputMethodCallback* callback;
const CurveType type;
std::vector<QGraphicsItem*> items;
bool itemsAdded;
PointSnapperBase* snapper;
};
class SegmentInputMethod : public CurveInputMethod
{
public:
SegmentInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
private:
QGraphicsLineItem segmentGuide;
};
class RayInputMethod : public CurveInputMethod
{
public:
RayInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
private:
QGraphicsLineItem rayGuide;
};
class LineInputMethod : public CurveInputMethod
{
public:
LineInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
private:
QGraphicsLineItem lineGuide;
};
class PolylineInputMethod : public CurveInputMethod
{
public:
PolylineInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
void updateVisualGuideNewPoint(const std::vector<QPointF>&) override;
private:
QGraphicsPathItem polylineGuide;
QGraphicsLineItem lastLine;
QPainterPath painterPath;
};
class CircleInputMethod : public CurveInputMethod
{
public:
CircleInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
private:
QGraphicsEllipseItem circleGuide;
};
class EllipseInputMethod : public CurveInputMethod
{
public:
EllipseInputMethod();
void beginInput() override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& 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<QPointF>&) override;
void updateVisualGuideMouseMoved(
const std::vector<QPointF>& clickedPoints,
const QPointF& movePoint) override;
private:
QGraphicsPathItem bezierOldGuide;
QGraphicsPathItem bezierGuide;
QPainterPath painterOldPath;
QPainterPath painterPath;
std::vector<QPointF> controlPoints;
std::vector<QPointF> 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);

View File

@ -1,8 +1,7 @@
#include "MergeEdgeCallback.h"
#include "ArrangementTypes.h"
#include "CurveGraphicsItem.h"
#include <CGAL/Arrangement_with_history_2.h>
#include <QEvent>
#include <CGAL/Qt/Converter.h>
#include <QGraphicsSceneMouseEvent>
#include "Utils.h"

View File

@ -13,7 +13,6 @@
#define MERGE_EDGE_CALLBACK_H
#include "Callback.h"
#include <CGAL/Qt/Converter.h>
namespace CGAL
{

View File

@ -2,6 +2,7 @@
#include <CGAL/Arr_simple_point_location.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_walk_along_line_point_location.h>
#include <CGAL/Qt/Converter.h>
#include <QPointF>
@ -42,15 +43,15 @@ static auto toKernelPoint(const QPointF& pt)
}
template <typename Arr_>
CGAL::Object
PointLocationFunctions<Arr_>::locate(const Arrangement* arr, const QPointF& pt)
CGAL::Object PointLocationFunctions<Arr_>::locate(
const Arrangement* arr, const Kernel_point_2& pt)
{
using SupportsLandmarks = typename Supports_landmarks<Arrangement>::Tag;
using PointLocationStrategy =
typename StrategyHelper<Arrangement, SupportsLandmarks>::type;
Arr_construct_point_2<Traits> toArrPoint;
auto arr_point = toArrPoint(toKernelPoint<Traits>(pt));
auto arr_point = toArrPoint(pt);
PointLocationStrategy pointLocationStrategy{*arr};
return pointLocationStrategy.locate(arr_point);
@ -58,7 +59,7 @@ PointLocationFunctions<Arr_>::locate(const Arrangement* arr, const QPointF& pt)
template <typename Arr_>
auto PointLocationFunctions<Arr_>::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<Arr_>::getFace(
return (eit->face());
}
template <typename Arr_>
CGAL::Object
PointLocationFunctions<Arr_>::locate(const Arrangement* arr, const QPointF& pt)
{
return this->locate(arr, toKernelPoint<Traits>(pt));
}
template <typename Arr_>
auto PointLocationFunctions<Arr_>::getFace(
const Arrangement* arr, const QPointF& pt) -> Face_const_handle
{
return this->getFace(arr, toKernelPoint<Traits>(pt));
}
template <typename Arr_>
CGAL::Object PointLocationFunctions<Arr_>::rayShootUp(
const Arrangement* arr, const QPointF& pt)

View File

@ -2,6 +2,7 @@
#define ARRANGEMENT_DEMO_POINT_LOCATION_FUNCTIONS
#include <CGAL/Object.h>
#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<Traits>::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&);

View File

@ -159,8 +159,8 @@ struct SnapToArrangement
{
using Point_2 = PointSnapperBase::Point_2;
template <typename Arrangement>
boost::optional<Point_2> operator()(
const QPointF& qpt, const QTransform& worldTransform, Arrangement* arr)
boost::optional<Point_2>
operator()(const QPointF& qpt, const QTransform&, Arrangement*)
{
return Point_2{qpt.x(), qpt.y()};
}

View File

@ -15,8 +15,7 @@
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsScene>
#include <QGraphicsLineItem>
#include <CGAL/Qt/Converter.h>
SplitEdgeCallbackBase::SplitEdgeCallbackBase( QObject* parent ) :
CGAL::Qt::Callback( parent )

View File

@ -12,14 +12,13 @@
#ifndef SPLIT_EDGE_CALLBACK_H
#define SPLIT_EDGE_CALLBACK_H
#include "Callback.h"
#include "GraphicsViewCurveInput.h"
#include <QColor>
class QGraphicsSceneMouseEvent;
class QGraphicsScene;
class QGraphicsLineItem;
class PointSnapperBase;
class QColor;
namespace CGAL
{

View File

@ -12,10 +12,8 @@
#include "Utils.h"
#include "ArrangementTypes.h"
#include "ArrangementPainterOstream.h"
#include "PointLocationFunctions.h"
#include <CGAL/Arr_walk_along_line_point_location.h>
#include <QGraphicsSceneMouseEvent>
#include <QScrollBar>
template <typename Kernel_>
@ -249,13 +247,9 @@ template <typename Arr_>
auto Find_nearest_edge<Arr_>::operator()(const Point_2& queryPt)
-> Halfedge_const_handle
{
typedef CGAL::Arr_walk_along_line_point_location<Arrangement>
Point_location_strategy;
Face_const_handle face =
PointLocationFunctions<Arrangement>{}.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<ArrTraits>::operator()(
template <typename Coefficient_>
auto Arr_compute_y_at_x_2<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>>::
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 <typename RatKernel, class AlgKernel, class NtTraits>
auto Arr_compute_y_at_x_2<
CGAL::Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits>>::
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();

View File

@ -10,95 +10,12 @@
#ifndef CGAL_ARRANGEMENTS_DEMO_UTILS_H
#define CGAL_ARRANGEMENTS_DEMO_UTILS_H
#include <CGAL/iterator.h>
#include <CGAL/Qt/Converter.h>
#include <QGraphicsSceneMouseEvent>
#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 <typename ArrTraits>
class ArrTraitsAdaptor
{ };
template <typename Kernel_>
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 <typename Kernel_>
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 <typename SegmentTraits>
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 <typename RatKernel, typename AlgKernel, typename NtTraits >
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 <typename RatKernel, typename AlgKernel, typename NtTraits>
class ArrTraitsAdaptor<
CGAL::Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits>>
{
public:
typedef CGAL::Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits>
ArrTraits;
typedef RatKernel Kernel;
typedef typename ArrTraits::Point_2 Point_2;
typedef typename Kernel::FT CoordinateType;
};
template <typename Coefficient_>
class ArrTraitsAdaptor< CGAL::Arr_algebraic_segment_traits_2< Coefficient_ > >
{
public:
typedef Coefficient_ Coefficient;
typedef typename CGAL::Arr_algebraic_segment_traits_2<Coefficient>
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 <typename ArrTraits >
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;

View File

@ -14,9 +14,7 @@
#include "Utils.h"
#include "PointLocationFunctions.h"
#include <CGAL/Qt/Converter.h>
#include <CGAL/Arrangement_with_history_2.h>
#include <CGAL/Arr_walk_along_line_point_location.h>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
@ -123,18 +121,8 @@ template <typename Arr_>
void VerticalRayShootCallback<Arr_>::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<Kernel>{}(queryQPt);
CGAL::Object pointLocationResult;
if (this->shootingUp)
@ -147,24 +135,22 @@ void VerticalRayShootCallback<Arr_>::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<Arr_>::highlightPointLocation(
// draw a ray from the clicked point to the hit curve
Arr_compute_y_at_x_2<Traits> 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);
}
}