1 /*! \file bezier_traits_adapter.cpp
2  * Using the traits adaptor to generate a traits class for Bezier polygons.
3  */
4 
5 #include <CGAL/config.h>
6 
7 #ifndef CGAL_USE_CORE
8 #include <iostream>
main()9 int main()
10 {
11   std::cout << "Sorry, this example needs CORE ..." << std::endl;
12   return (0);
13 }
14 #else
15 
16 #include <CGAL/Cartesian.h>
17 #include <CGAL/CORE_algebraic_number_traits.h>
18 #include <CGAL/Arr_Bezier_curve_traits_2.h>
19 #include <CGAL/Gps_traits_2.h>
20 #include <CGAL/Boolean_set_operations_2.h>
21 #include <CGAL/General_polygon_set_2.h>
22 #include <CGAL/Timer.h>
23 
24 #include <fstream>
25 
26 typedef CGAL::CORE_algebraic_number_traits            Nt_traits;
27 typedef Nt_traits::Rational                           Rational;
28 typedef Nt_traits::Algebraic                          Algebraic;
29 
30 typedef CGAL::Cartesian<Rational>                     Rat_kernel;
31 typedef CGAL::Cartesian<Algebraic>                    Alg_kernel;
32 typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
33                                                       Traits_2;
34 
35 typedef Rat_kernel::Point_2                           Bezier_rat_point;
36 typedef Traits_2::Curve_2                             Bezier_curve;
37 typedef Traits_2::X_monotone_curve_2                  Bezier_X_monotone_curve;
38 typedef CGAL::Gps_traits_2<Traits_2>                  Bezier_traits;
39 typedef Bezier_traits::General_polygon_2              Bezier_polygon;
40 typedef Bezier_traits::General_polygon_with_holes_2   Bezier_polygon_with_holes;
41 typedef CGAL::General_polygon_set_2<Bezier_traits>    Bezier_polygon_set;
42 typedef std::vector<Bezier_polygon>                   Bezier_polygon_vector;
43 
read_bezier_curve(std::istream & is,bool aDoubleFormat)44 Bezier_curve read_bezier_curve(std::istream& is, bool aDoubleFormat)
45 {
46   // Read the number of control points.
47   unsigned int  n;
48 
49   is >> n;
50 
51   // Read the control points.
52   std::vector<Bezier_rat_point> ctrl_pts;
53   for (unsigned int k = 0; k < n; ++k) {
54     Bezier_rat_point p;
55     if (aDoubleFormat) {
56       double x, y;
57       is >> x >> y;
58       p = Bezier_rat_point(x,y);
59     }
60     else
61       is >> p;
62 
63     if ((k == 0) || (ctrl_pts[k-1] != p))
64       ctrl_pts.push_back(p);
65   }
66 
67   return Bezier_curve(ctrl_pts.begin(), ctrl_pts.end());
68 }
69 
read_bezier(char const * aFileName,Bezier_polygon_set & rSet)70 bool read_bezier(char const* aFileName, Bezier_polygon_set& rSet)
71 {
72 
73   bool rOK = false;
74 
75   std::ifstream in_file(aFileName);
76 
77   if (in_file) {
78     try {
79       std::cout << "Reading " << aFileName << std::endl;
80 
81       std::string format;
82       std::getline(in_file, format);
83 
84       bool lDoubleFormat =
85         ((format.length() >= 6) && (format.substr(0,6) == "DOUBLE"));
86 
87       // Red the number of bezier polygon with holes
88       unsigned int n_regions;
89       in_file >> n_regions;
90 
91       for (unsigned int r = 0; r < n_regions; ++r) {
92         Bezier_polygon_vector  polygons;
93 
94         // Read the number of bezier curves.
95         unsigned int n_boundaries;
96         in_file >> n_boundaries;
97 
98         for (unsigned int b = 0; b < n_boundaries; ++b) {
99           // Read the number of bezier curves.
100           unsigned int n_curves;
101           in_file >> n_curves;
102 
103           // Read the curves one by one, and construct the general polygon these
104           // curve form (the outer boundary and the holes inside it).
105 
106           std::list<Bezier_X_monotone_curve> xcvs;
107 
108           for (unsigned int k = 0; k < n_curves; ++k) {
109             // Read the current curve and subdivide it into x-monotone subcurves.
110 
111             std::list<CGAL::Object>                 x_objs;
112             std::list<CGAL::Object>::const_iterator xoit;
113             Bezier_X_monotone_curve                 xcv;
114             Bezier_traits                           traits;
115             Bezier_traits::Make_x_monotone_2        make_x_monotone =
116               traits.make_x_monotone_2_object();
117 
118             Bezier_curve B = read_bezier_curve(in_file, lDoubleFormat);
119             if (B.number_of_control_points() >= 2) {
120 
121               make_x_monotone(B, std::back_inserter(x_objs));
122 
123               for (xoit = x_objs.begin(); xoit != x_objs.end(); ++xoit) {
124                 if (CGAL::assign(xcv, *xoit))
125                   xcvs.push_back(xcv);
126               }
127             }
128           }
129 
130           Bezier_polygon  pgn(xcvs.begin(), xcvs.end());
131 
132           CGAL::Orientation  orient = pgn.orientation();
133           std::cout << "  Orientation: " << orient << std::endl;
134 
135           if (((b == 0) && (orient == CGAL::CLOCKWISE)) ||
136               ((b > 0) && (orient == CGAL::COUNTERCLOCKWISE)))
137           {
138             std::cout << "    Reversing orientation: " << std::endl;
139             pgn.reverse_orientation();
140           }
141 
142           polygons.push_back(pgn);
143         }
144 
145         if (polygons.size() > 0) {
146           Bezier_polygon_with_holes pwh(polygons.front());
147 
148           if (polygons.size() > 1) {
149             Bezier_polygon_vector::const_iterator it;
150             for (it = std::next(polygons.begin());
151                  it != polygons.end(); ++it)
152               pwh.add_hole(*it);
153           }
154 
155           if (is_valid_polygon_with_holes(pwh, rSet.traits())) {
156             std::cout << "  Inserting Bezier polygon with holes comprising "
157                       << polygons.size() << " boundaries in total into set."
158                       << std::endl;
159             rSet.join(pwh);
160             std::cout << "    Done." << std::endl;
161           }
162           else
163             std::cout << "  **** Bezier polygon with holes is NOT VALID ****"
164                       << std::endl;
165         }
166 
167         rOK = true;
168       }
169     }
170     catch(std::exception const& x) {
171       std::cout << "An exception ocurred during reading of Bezier polygon set:"
172                 << x.what() << std::endl;
173     }
174     catch(...) {
175       std::cout << "An exception ocurred during reading of Bezier polygon set."
176                 << std::endl;
177     }
178   }
179 
180   return rOK;
181 }
182 
183 // The main program.
main(int argc,char * argv[])184 int main(int argc, char* argv[])
185 {
186   const char* filename1 = (argc > 1) ? argv[1] : "char_g.bps";
187   const char* filename2 = (argc > 2) ? argv[2] : "char_m.bps";
188   const char* bop       = (argc > 3) ? argv[3] : "i";
189 
190   // Read the general polygons from the input files.
191   CGAL::Timer timer;
192   Bezier_polygon_set S1, S2;
193 
194   timer.start();
195 
196 
197   if (! read_bezier(filename1, S1)) {
198     std::cerr << "Failed to read " << filename1 << " ..." << std::endl;
199     return 1;
200   }
201 
202   if (! read_bezier(filename2, S2)) {
203     std::cerr << "Failed to read " << filename2 << " ..." << std::endl;
204     return 1;
205   }
206 
207   timer.stop();
208   std::cout << "Constructed the input polygons in " << timer.time()
209             << " seconds." << std::endl << std::endl;
210 
211   std::cout << "Starting boolean operation..." << std::endl;
212   timer.reset();
213   timer.start();
214   try {
215     switch (bop[0]) {
216       case 'i': S1.intersection(S2); break;
217       case 'u': S1.join(S2); break;
218     }
219   }
220   catch(std::exception const& x) {
221     std::cout << "An exception occurred during the Boolean operation:"
222               << x.what() << std::endl;
223   }
224   catch(...) {
225     std::cout << "An exception occurred during the Boolean operation."
226               << std::endl;
227   }
228   timer.stop();
229 
230   std::cout << "The " << ( bop[0] == 'i' ? "intersection" : "union" )
231             << " computation took "
232             << timer.time() << " seconds." << std::endl;
233 
234   return 0;
235 }
236 
237 #endif
238