File: bezier_traits_adapter2.cpp

package info (click to toggle)
cgal 6.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 144,952 kB
  • sloc: cpp: 811,597; ansic: 208,576; sh: 493; python: 411; makefile: 286; javascript: 174
file content (229 lines) | stat: -rw-r--r-- 6,945 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/*! \file bezier_traits_adapter.cpp
 * Using the traits adaptor to generate a traits class for Bezier polygons.
 */

#include <CGAL/config.h>
#include <CGAL/iterator.h>

#ifndef CGAL_USE_CORE
#include <iostream>
int main()
{
  std::cout << "Sorry, this example needs CORE ..." << std::endl;
  return (0);
}
#else

#include <CGAL/Cartesian.h>
#include <CGAL/CORE_algebraic_number_traits.h>
#include <CGAL/Arr_Bezier_curve_traits_2.h>
#include <CGAL/Gps_traits_2.h>
#include <CGAL/Boolean_set_operations_2.h>
#include <CGAL/General_polygon_set_2.h>
#include <CGAL/Timer.h>

#include <fstream>

typedef CGAL::CORE_algebraic_number_traits            Nt_traits;
typedef Nt_traits::Rational                           Rational;
typedef Nt_traits::Algebraic                          Algebraic;

typedef CGAL::Cartesian<Rational>                     Rat_kernel;
typedef CGAL::Cartesian<Algebraic>                    Alg_kernel;
typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
                                                      Traits_2;

typedef Rat_kernel::Point_2                           Bezier_rat_point;
typedef Traits_2::Curve_2                             Bezier_curve;
typedef Traits_2::X_monotone_curve_2                  Bezier_X_monotone_curve;
typedef CGAL::Gps_traits_2<Traits_2>                  Bezier_traits;
typedef Bezier_traits::General_polygon_2              Bezier_polygon;
typedef Bezier_traits::General_polygon_with_holes_2   Bezier_polygon_with_holes;
typedef CGAL::General_polygon_set_2<Bezier_traits>    Bezier_polygon_set;
typedef std::vector<Bezier_polygon>                   Bezier_polygon_vector;

Bezier_curve read_bezier_curve(std::istream& is, bool aDoubleFormat)
{
  // Read the number of control points.
  unsigned int  n;

  is >> n;

  // Read the control points.
  std::vector<Bezier_rat_point> ctrl_pts;
  for (unsigned int k = 0; k < n; ++k) {
    Bezier_rat_point p;
    if (aDoubleFormat) {
      double x, y;
      is >> x >> y;
      p = Bezier_rat_point(x,y);
    }
    else
      is >> p;

    if ((k == 0) || (ctrl_pts[k-1] != p))
      ctrl_pts.push_back(p);
  }

  return Bezier_curve(ctrl_pts.begin(), ctrl_pts.end());
}

bool read_bezier(char const* aFileName, Bezier_polygon_set& rSet)
{

  bool rOK = false;

  std::ifstream in_file(aFileName);

  if (in_file) {
    try {
      std::cout << "Reading " << aFileName << std::endl;

      std::string format;
      std::getline(in_file, format);

      bool lDoubleFormat =
        ((format.length() >= 6) && (format.substr(0,6) == "DOUBLE"));

      // Red the number of bezier polygon with holes
      unsigned int n_regions;
      in_file >> n_regions;

      for (unsigned int r = 0; r < n_regions; ++r) {
        Bezier_polygon_vector  polygons;

        // Read the number of bezier curves.
        unsigned int n_boundaries;
        in_file >> n_boundaries;

        for (unsigned int b = 0; b < n_boundaries; ++b) {
          // Read the number of bezier curves.
          unsigned int n_curves;
          in_file >> n_curves;

          // Read the curves one by one, and construct the general polygon these
          // curve form (the outer boundary and the holes inside it).

          std::list<Bezier_X_monotone_curve> xcvs;

          for (unsigned int k = 0; k < n_curves; ++k) {
            // Read the current curve and subdivide it into x-monotone subcurves.

            Bezier_traits                           traits;
            Bezier_traits::Make_x_monotone_2        make_x_monotone =
              traits.make_x_monotone_2_object();

            Bezier_curve B = read_bezier_curve(in_file, lDoubleFormat);
            if (B.number_of_control_points() >= 2) {
              make_x_monotone(B, CGAL::dispatch_or_drop_output<Bezier_X_monotone_curve>(std::back_inserter(xcvs)));
            }
          }

          Bezier_polygon  pgn(xcvs.begin(), xcvs.end());

          CGAL::Orientation  orient = pgn.orientation();
          std::cout << "  Orientation: " << orient << std::endl;

          if (((b == 0) && (orient == CGAL::CLOCKWISE)) ||
              ((b > 0) && (orient == CGAL::COUNTERCLOCKWISE)))
          {
            std::cout << "    Reversing orientation: " << std::endl;
            pgn.reverse_orientation();
          }

          polygons.push_back(pgn);
        }

        if (polygons.size() > 0) {
          Bezier_polygon_with_holes pwh(polygons.front());

          if (polygons.size() > 1) {
            Bezier_polygon_vector::const_iterator it;
            for (it = std::next(polygons.begin());
                 it != polygons.end(); ++it)
              pwh.add_hole(*it);
          }

          if (is_valid_polygon_with_holes(pwh, rSet.traits())) {
            std::cout << "  Inserting Bezier polygon with holes comprising "
                      << polygons.size() << " boundaries in total into set."
                      << std::endl;
            rSet.join(pwh);
            std::cout << "    Done." << std::endl;
          }
          else
            std::cout << "  **** Bezier polygon with holes is NOT VALID ****"
                      << std::endl;
        }

        rOK = true;
      }
    }
    catch(std::exception const& x) {
      std::cout << "An exception occurred during reading of Bezier polygon set:"
                << x.what() << std::endl;
    }
    catch(...) {
      std::cout << "An exception occurred during reading of Bezier polygon set."
                << std::endl;
    }
  }

  return rOK;
}

// The main program.
int main(int argc, char* argv[])
{
  const char* filename1 = (argc > 1) ? argv[1] : "char_g.bps";
  const char* filename2 = (argc > 2) ? argv[2] : "char_m.bps";
  const char* bop       = (argc > 3) ? argv[3] : "i";

  // Read the general polygons from the input files.
  CGAL::Timer timer;
  Bezier_polygon_set S1, S2;

  timer.start();


  if (! read_bezier(filename1, S1)) {
    std::cerr << "Failed to read " << filename1 << " ..." << std::endl;
    return 1;
  }

  if (! read_bezier(filename2, S2)) {
    std::cerr << "Failed to read " << filename2 << " ..." << std::endl;
    return 1;
  }

  timer.stop();
  std::cout << "Constructed the input polygons in " << timer.time()
            << " seconds." << std::endl << std::endl;

  std::cout << "Starting boolean operation..." << std::endl;
  timer.reset();
  timer.start();
  try {
    switch (bop[0]) {
      case 'i': S1.intersection(S2); break;
      case 'u': S1.join(S2); break;
    }
  }
  catch(std::exception const& x) {
    std::cout << "An exception occurred during the Boolean operation:"
              << x.what() << std::endl;
  }
  catch(...) {
    std::cout << "An exception occurred during the Boolean operation."
              << std::endl;
  }
  timer.stop();

  std::cout << "The " << ( bop[0] == 'i' ? "intersection" : "union" )
            << " computation took "
            << timer.time() << " seconds." << std::endl;

  return 0;
}

#endif