1 // Copyright (c) 2020 GeometryFactory Sarl (France).
2 // All rights reserved.
3 //
4 // This file is part of CGAL (www.cgal.org).
5 //
6 // $URL$
7 // $Id$
8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 // Author(s): Ahmed Essam <theartful.ae@gmail.com>
11 
12 #include "ArrangementIO.h"
13 #include "ArrangementDemoTab.h"
14 #include "ArrangementTypes.h"
15 #include "ArrangementTypesUtils.h"
16 #include "Conic_reader.h"
17 
18 #include <CGAL/IO/Arr_text_formatter.h>
19 #include <CGAL/IO/Arr_with_history_iostream.h>
20 #include <CGAL/IO/Arr_with_history_text_formatter.h>
21 
22 template <
23   typename Arrangement,
24   typename Traits = typename Arrangement::Geometry_traits_2>
25 struct ArrReader
26 {
operator ()ArrReader27   Arrangement* operator()(std::ifstream& ifs)
28   {
29     using Text_formatter = CGAL::Arr_text_formatter<Arrangement>;
30     using ArrFormatter = CGAL::Arr_with_history_text_formatter<Text_formatter>;
31 
32     ArrFormatter arrFormatter;
33     auto arr = new Arrangement();
34     CGAL::IO::read(*arr, ifs, arrFormatter);
35     return arr;
36   }
37 };
38 
39 #ifdef CGAL_USE_CORE
40 template <
41   typename Arrangement, typename Rat_kernel_, typename Alg_kernel_,
42   typename Nt_traits_>
43 struct ArrReader<
44   Arrangement, CGAL::Arr_conic_traits_2<Rat_kernel_, Alg_kernel_, Nt_traits_>>
45 {
46   using Traits = typename Arrangement::Geometry_traits_2;
47   using Curve_2 = typename Arrangement::Curve_2;
48 
operator ()ArrReader49   Arrangement* operator()(std::ifstream& ifs)
50   {
51     Conic_reader<Traits> conicReader;
52     std::vector<Curve_2> curve_list;
53     CGAL::Bbox_2 bbox;
54     conicReader.read_data(ifs, std::back_inserter(curve_list), bbox);
55     auto arr = new Arrangement();
56     CGAL::insert(*arr, curve_list.begin(), curve_list.end());
57     return arr;
58   }
59 };
60 
61 template <
62   typename Arrangement, typename Rat_kernel_, typename Alg_kernel_,
63   typename Nt_traits_, typename Bounding_traits_>
64 struct ArrReader<
65   Arrangement, CGAL::Arr_Bezier_curve_traits_2<
66                  Rat_kernel_, Alg_kernel_, Nt_traits_, Bounding_traits_>>
67 {
operator ()ArrReader68   Arrangement* operator()(std::ifstream&) { return nullptr; }
69 };
70 
71 template <typename Arrangement, typename AlgebraicKernel_d_1_>
72 struct ArrReader<
73   Arrangement, CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1_>>
74 {
operator ()ArrReader75   Arrangement* operator()(std::ifstream&) { return nullptr; }
76 };
77 #endif
78 
79 std::pair<CGAL::Object, demo_types::TraitsType>
read(std::ifstream & ifs)80 ArrangementIO::read(std::ifstream& ifs)
81 {
82   // read type info
83   while (ifs.peek() == '#' || std::isspace(ifs.peek())) ifs.get();
84 
85   int tt_int;
86   ifs >> tt_int;
87   auto tt = static_cast<demo_types::TraitsType>(tt_int);
88 
89   std::pair<CGAL::Object, demo_types::TraitsType> res;
90   demo_types::visitArrangementType(tt, [&](auto type_holder) {
91     using Arrangement = typename decltype(type_holder)::type;
92     auto arr = ArrReader<Arrangement>{}(ifs);
93     res = {CGAL::make_object(arr), demo_types::enumFromArrType<Arrangement>()};
94   });
95   return res;
96 }
97 
98 template <
99   typename Arrangement,
100   typename Traits = typename Arrangement::Geometry_traits_2>
101 struct ArrWriter
102 {
operator ()ArrWriter103   void operator()(Arrangement* arr, std::ofstream& ofs)
104   {
105     using TextFormatter = CGAL::Arr_text_formatter<Arrangement>;
106     using ArrFormatter = CGAL::Arr_with_history_text_formatter<TextFormatter>;
107 
108     ArrFormatter arrFormatter;
109     CGAL::IO::write(*arr, ofs, arrFormatter);
110   }
111 };
112 
113 #ifdef CGAL_USE_CORE
114 template <
115   typename Arrangement, typename Rat_kernel_, typename Alg_kernel_,
116   typename Nt_traits_>
117 struct ArrWriter<
118   Arrangement, CGAL::Arr_conic_traits_2<Rat_kernel_, Alg_kernel_, Nt_traits_>>
119 {
120   using Traits = typename Arrangement::Geometry_traits_2;
121   using Curve_2 = typename Arrangement::Curve_2;
122 
operator ()ArrWriter123   void operator()(Arrangement* arr, std::ofstream& ofs)
124   {
125     Conic_reader<Traits> conicReader;
126     conicReader.write_data(ofs, arr->curves_begin(), arr->curves_end());
127   }
128 };
129 
130 template <
131   typename Arrangement, typename Rat_kernel_, typename Alg_kernel_,
132   typename Nt_traits_, typename Bounding_traits_>
133 struct ArrWriter<
134   Arrangement, CGAL::Arr_Bezier_curve_traits_2<
135                  Rat_kernel_, Alg_kernel_, Nt_traits_, Bounding_traits_>>
136 {
operator ()ArrWriter137   void operator()(Arrangement*, std::ofstream&) { }
138 };
139 
140 template <typename Arrangement, typename AlgebraicKernel_d_1_>
141 struct ArrWriter<
142   Arrangement, CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1_>>
143 {
operator ()ArrWriter144   void operator()(Arrangement*, std::ofstream&) { }
145 };
146 #endif
147 
write(const std::pair<CGAL::Object,demo_types::TraitsType> & arr_pair,std::ofstream & ofs)148 bool ArrangementIO::write(
149   const std::pair<CGAL::Object, demo_types::TraitsType>& arr_pair,
150   std::ofstream& ofs)
151 {
152   auto tt = arr_pair.second;
153   auto arr_obj = arr_pair.first;
154 
155   // write type info
156   ofs << "# " << static_cast<int>(tt) << std::endl;
157 
158   bool result = false;
159   demo_types::visitArrangementType(tt, [&](auto type_holder) {
160     using Arrangement = typename decltype(type_holder)::type;
161     Arrangement* arr;
162     if (CGAL::assign(arr, arr_obj))
163     {
164       ArrWriter<Arrangement>{}(arr, ofs);
165       result = true;
166     }
167   });
168   return result;
169 }
170