1 // Copyright (c) 2008, 2012, 2020 GeometryFactory Sarl (France). 2 // All rights reserved. 3 // 4 // This file is part of CGAL (www.cgal.org). 5 // 6 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial 7 // 8 // Author(s): Ahmed Essam <theartful.ae@gmail.com> 9 10 #ifndef CGAL_QT_GRAPHICS_VIEW_CURVE_INPUT_TYPED_H 11 #define CGAL_QT_GRAPHICS_VIEW_CURVE_INPUT_TYPED_H 12 13 #include <CGAL/Object.h> 14 #include <boost/optional/optional_fwd.hpp> 15 #include <tuple> 16 #include <type_traits> 17 #include <vector> 18 19 #include "Callback.h" 20 #include "CurveInputMethods.h" 21 #include "ForwardDeclarations.h" 22 #include "GraphicsSceneMixin.h" 23 #include "GraphicsViewCurveInput.h" 24 #include "PointSnapper.h" 25 26 class QEvent; 27 28 namespace demo_types 29 { 30 enum class TraitsType : int; 31 } 32 33 namespace CGAL 34 { 35 namespace Qt 36 { 37 38 template <typename ArrTraits_> 39 class CurveGeneratorBase 40 { 41 public: 42 using ArrTraits = ArrTraits_; 43 using Curve_2 = typename ArrTraits::Curve_2; 44 using Point_2 = CGAL::Qt::CurveInputMethod::Point_2; 45 46 void setTraits(const ArrTraits* traits_); 47 48 boost::optional<Curve_2> 49 generate(const std::vector<Point_2>& clickedPoints, CurveType type); 50 51 virtual boost::optional<Curve_2> generateSegment(const std::vector<Point_2> &)52 generateSegment(const std::vector<Point_2>&) { return {}; } 53 virtual boost::optional<Curve_2> generateRay(const std::vector<Point_2> &)54 generateRay(const std::vector<Point_2>&) { return {}; } 55 virtual boost::optional<Curve_2> generateLine(const std::vector<Point_2> &)56 generateLine(const std::vector<Point_2>&) { return {}; } 57 virtual boost::optional<Curve_2> generatePolyline(const std::vector<Point_2> &)58 generatePolyline(const std::vector<Point_2>&) { return {}; } 59 virtual boost::optional<Curve_2> generateCircle(const std::vector<Point_2> &)60 generateCircle(const std::vector<Point_2>&) { return {}; } 61 virtual boost::optional<Curve_2> generateEllipse(const std::vector<Point_2> &)62 generateEllipse(const std::vector<Point_2>&) { return {}; } 63 virtual boost::optional<Curve_2> generateThreePointCircularArc(const std::vector<Point_2> &)64 generateThreePointCircularArc(const std::vector<Point_2>&) { return {}; } 65 virtual boost::optional<Curve_2> generateFivePointConicArc(const std::vector<Point_2> &)66 generateFivePointConicArc(const std::vector<Point_2>&) { return {}; } 67 virtual boost::optional<Curve_2> generateBezier(const std::vector<Point_2> &)68 generateBezier(const std::vector<Point_2>&) { return {}; } 69 70 const ArrTraits* traits; 71 }; 72 73 template <typename ArrTraits_> 74 struct CurveGenerator : public CurveGeneratorBase<ArrTraits_> 75 { 76 }; 77 78 template <typename Kernel_> 79 struct CurveGenerator<CGAL::Arr_segment_traits_2<Kernel_>> : 80 public CurveGeneratorBase<CGAL::Arr_segment_traits_2<Kernel_>> 81 { 82 using ArrTraits = CGAL::Arr_segment_traits_2<Kernel_>; 83 using Curve_2 = typename ArrTraits::Curve_2; 84 using Kernel = Kernel_; 85 using Super = CurveGeneratorBase<ArrTraits>; 86 using Point_2 = typename Super::Point_2; 87 88 boost::optional<Curve_2> 89 generateSegment(const std::vector<Point_2>&) override; 90 }; 91 92 template <typename SegmentTraits> 93 struct CurveGenerator<CGAL::Arr_polyline_traits_2<SegmentTraits>> : 94 public CurveGeneratorBase<CGAL::Arr_polyline_traits_2<SegmentTraits>> 95 { 96 using ArrTraits = CGAL::Arr_polyline_traits_2<SegmentTraits>; 97 using Curve_2 = typename ArrTraits::Curve_2; 98 using Super = CurveGeneratorBase<ArrTraits>; 99 using Point_2 = typename Super::Point_2; 100 101 boost::optional<Curve_2> 102 generatePolyline(const std::vector<Point_2>&) override; 103 }; 104 105 template <typename RatKernel, typename AlgKernel, typename NtTraits> 106 struct CurveGenerator<Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>> : 107 public CurveGeneratorBase< 108 Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>> 109 { 110 using ArrTraits = Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>; 111 using Curve_2 = typename ArrTraits::Curve_2; 112 using Kernel = AlgKernel; 113 using Segment_2 = typename Kernel::Segment_2; 114 using Rat_FT = typename RatKernel::FT; 115 using Rat_point_2 = typename RatKernel::Point_2; 116 using Rat_segment_2 = typename RatKernel::Segment_2; 117 using Rat_circle_2 = typename RatKernel::Circle_2; 118 using Super = CurveGeneratorBase<ArrTraits>; 119 using Point_2 = typename Super::Point_2; 120 121 boost::optional<Curve_2> 122 generateSegment(const std::vector<Point_2>&) override; 123 boost::optional<Curve_2> generateCircle(const std::vector<Point_2>&) override; 124 boost::optional<Curve_2> 125 generateEllipse(const std::vector<Point_2>&) override; 126 boost::optional<Curve_2> 127 generateThreePointCircularArc(const std::vector<Point_2>&) override; 128 boost::optional<Curve_2> 129 generateFivePointConicArc(const std::vector<Point_2>&) override; 130 }; 131 132 template <typename Kernel_> 133 struct CurveGenerator<CGAL::Arr_linear_traits_2<Kernel_>> : 134 public CurveGeneratorBase<CGAL::Arr_linear_traits_2<Kernel_>> 135 { 136 using Kernel = Kernel_; 137 using KernelPoint = typename Kernel::Point_2; 138 using ArrTraits = CGAL::Arr_linear_traits_2<Kernel>; 139 using Curve_2 = typename ArrTraits::Curve_2; 140 using Segment_2 = typename Kernel::Segment_2; 141 using Ray_2 = typename Kernel::Ray_2; 142 using Line_2 = typename Kernel::Line_2; 143 using Super = CurveGeneratorBase<ArrTraits>; 144 using Point_2 = typename Super::Point_2; 145 146 boost::optional<Curve_2> 147 generateSegment(const std::vector<Point_2>&) override; 148 boost::optional<Curve_2> generateRay(const std::vector<Point_2>&) override; 149 boost::optional<Curve_2> generateLine(const std::vector<Point_2>&) override; 150 }; 151 152 template <typename Coefficient_> 153 struct CurveGenerator<CGAL::Arr_algebraic_segment_traits_2<Coefficient_>> : 154 public CurveGeneratorBase< 155 CGAL::Arr_algebraic_segment_traits_2<Coefficient_>> 156 { 157 using Coefficient = Coefficient_; 158 using ArrTraits = CGAL::Arr_algebraic_segment_traits_2<Coefficient>; 159 using X_monotone_curve_2 = typename ArrTraits::X_monotone_curve_2; 160 using Polynomial_2 = typename ArrTraits::Polynomial_2; 161 using Curve_2 = typename ArrTraits::Curve_2; 162 using Algebraic_real_1 = typename ArrTraits::Algebraic_real_1; 163 using Rational = typename Algebraic_real_1::Rational; 164 using RationalTraits = Rational_traits<Rational>; 165 using Super = CurveGeneratorBase<ArrTraits>; 166 using Point_2 = typename Super::Point_2; 167 168 boost::optional<Curve_2> generateLine(const std::vector<Point_2>&) override; 169 boost::optional<Curve_2> generateCircle(const std::vector<Point_2>&) override; 170 boost::optional<Curve_2> 171 generateEllipse(const std::vector<Point_2>&) override; 172 173 private: 174 boost::optional<Curve_2> generateEllipse_(const Point_2&, Rational, Rational); 175 }; 176 177 template < 178 typename RatKernel, typename AlgKernel, typename NtTraits, 179 typename BoundingTraits> 180 struct CurveGenerator< 181 Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits, BoundingTraits>> : 182 public CurveGeneratorBase< 183 Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits, BoundingTraits>> 184 { 185 using ArrTraits = 186 Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits, BoundingTraits>; 187 using Super = CurveGeneratorBase<ArrTraits>; 188 using Point_2 = typename Super::Point_2; 189 using Curve_2 = typename ArrTraits::Curve_2; 190 191 boost::optional<Curve_2> generateBezier(const std::vector<Point_2>&) override; 192 }; 193 194 template <typename ArrTraits> 195 struct GraphicsViewCurveInputTypeHelper 196 { 197 using InputMethodTuple = std::tuple<>; 198 }; 199 200 template <typename Kernel_> 201 struct GraphicsViewCurveInputTypeHelper<CGAL::Arr_segment_traits_2<Kernel_>> 202 { 203 using InputMethodTuple = std::tuple<SegmentInputMethod>; 204 }; 205 206 template <typename SegmentTraits> 207 struct GraphicsViewCurveInputTypeHelper< 208 CGAL::Arr_polyline_traits_2<SegmentTraits>> 209 { 210 using InputMethodTuple = std::tuple<PolylineInputMethod>; 211 }; 212 213 template <typename Kernel_> 214 struct GraphicsViewCurveInputTypeHelper<CGAL::Arr_linear_traits_2<Kernel_>> 215 { 216 using InputMethodTuple = 217 std::tuple<SegmentInputMethod, RayInputMethod, LineInputMethod>; 218 }; 219 220 template <typename RatKernel, typename AlgKernel, typename NtTraits> 221 struct GraphicsViewCurveInputTypeHelper< 222 CGAL::Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits>> 223 { 224 using InputMethodTuple = std::tuple< 225 SegmentInputMethod, CircleInputMethod, EllipseInputMethod, 226 ThreePointCircularInputMethod, FivePointConicInputMethod>; 227 }; 228 229 template <typename Coefficient_> 230 struct GraphicsViewCurveInputTypeHelper< 231 CGAL::Arr_algebraic_segment_traits_2<Coefficient_>> 232 { 233 using InputMethodTuple = 234 std::tuple<LineInputMethod, CircleInputMethod, EllipseInputMethod>; 235 }; 236 237 template < 238 typename RatKernel, typename AlgKernel, typename NtTraits, 239 typename BoundingTraits> 240 struct GraphicsViewCurveInputTypeHelper<CGAL::Arr_Bezier_curve_traits_2< 241 RatKernel, AlgKernel, NtTraits, BoundingTraits>> 242 { 243 using InputMethodTuple = std::tuple<BezierInputMethod>; 244 }; 245 246 template <typename Arr_> 247 class GraphicsViewCurveInput : 248 public GraphicsViewCurveInputBase, 249 public CurveInputMethodCallback 250 { 251 using Self = GraphicsViewCurveInput<Arr_>; 252 using Arrangement = Arr_; 253 using ArrTraits = typename Arrangement::Geometry_traits_2; 254 using Curve_2 = typename Arrangement::Curve_2; 255 using InputMethodTuple = 256 typename GraphicsViewCurveInputTypeHelper<ArrTraits>::InputMethodTuple; 257 using Point_2 = CGAL::Qt::CurveInputMethod::Point_2; 258 259 public: 260 GraphicsViewCurveInput( 261 Arrangement* arrangement_, QObject* parent, QGraphicsScene* scene); 262 void setCurveType(CurveType type) override; 263 void setPointSnapper(PointSnapperBase*) override; 264 void generate(CGAL::Object o) override; 265 void curveInputDoneEvent( 266 const std::vector<Point_2>& clickedPoints, CurveType type) override; 267 268 private: 269 template <typename = ArrTraits> 270 void setDefaultInputMethod(std::true_type); 271 void setDefaultInputMethod(std::false_type); 272 273 Arrangement* arrangement; 274 InputMethodTuple inputMethods; 275 CurveGenerator<ArrTraits> curveGenerator; 276 }; 277 278 } // namespace Qt 279 } // namespace CGAL 280 281 #endif // CGAL_QT_GRAPHICS_VIEW_SEGMENT_INPUT_H 282