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
|