#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <fstream>
typedef Polyhedron::Vertex Vertex;
typedef Polyhedron::Vertex_iterator Vertex_iterator;
typedef Polyhedron::Halfedge_handle Halfedge_handle;
typedef Polyhedron::Edge_iterator Edge_iterator;
typedef Polyhedron::Facet_iterator Facet_iterator;
typedef Polyhedron::Halfedge_around_vertex_const_circulator HV_circulator;
typedef Polyhedron::Halfedge_around_facet_circulator HF_circulator;
void create_center_vertex( Polyhedron& P, Facet_iterator f) {
Vector vec( 0.0, 0.0, 0.0);
std::size_t order = 0;
HF_circulator h = f->facet_begin();
do {
++ order;
} while ( ++h != f->facet_begin());
CGAL_assertion( order >= 3);
Point center =
CGAL::ORIGIN + (vec /
static_cast<double>(order));
Halfedge_handle new_center = P.create_center_vertex( f->halfedge());
new_center->vertex()->point() = center;
}
struct Smooth_old_vertex {
Point operator()( const Vertex& v) const {
double alpha = ( 4.0 - 2.0 * std::cos( 2.0 * CGAL_PI / degree)) / 9.0;
HV_circulator h = v.vertex_begin();
do {
vec = vec + ( h->opposite()->vertex()->point() -
CGAL::ORIGIN)
* alpha / static_cast<double>(degree);
++ h;
CGAL_assertion( h != v.vertex_begin());
++ h;
} while ( h != v.vertex_begin());
}
};
void flip_edge( Polyhedron& P, Halfedge_handle e) {
Halfedge_handle h = e->next();
P.join_facet( e);
P.split_facet( h, h->next()->next());
}
void subdiv( Polyhedron& P) {
if ( P.size_of_facets() == 0)
return;
std::size_t nv = P.size_of_vertices();
Vertex_iterator last_v = P.vertices_end();
-- last_v;
Edge_iterator last_e = P.edges_end();
-- last_e;
Facet_iterator last_f = P.facets_end();
-- last_f;
Facet_iterator f = P.facets_begin();
do {
create_center_vertex( P, f);
} while ( f++ != last_f);
std::vector<Point> pts;
pts.reserve( nv);
++ last_v;
Smooth_old_vertex());
std::copy( pts.begin(), pts.end(), P.points_begin());
Edge_iterator e = P.edges_begin();
++ last_e;
while ( e != last_e) {
Halfedge_handle h = e;
++e;
};
CGAL_postcondition( P.is_valid());
}
int main(int argc, char* argv[]) {
Polyhedron P;
std::ifstream in1((argc>1)?argv[1]:"data/cube.off");
in1 >> P;
P.normalize_border();
if ( P.size_of_border_edges() != 0) {
std::cerr << "The input object has border edges. Cannot subdivide."
<< std::endl;
std::exit(1);
}
subdiv( P);
std::cout << P;
return 0;
}