2011-09-08 00:04:59 +04:00
|
|
|
#ifdef ENABLE_CGAL
|
|
|
|
|
|
|
|
#include "cgalutils.h"
|
|
|
|
#include "polyset.h"
|
|
|
|
#include "printutils.h"
|
|
|
|
|
|
|
|
#include "cgal.h"
|
|
|
|
#include <CGAL/assertions_behaviour.h>
|
|
|
|
#include <CGAL/exceptions.h>
|
|
|
|
|
|
|
|
PolySet *createPolySetFromPolyhedron(const CGAL_Polyhedron &p)
|
|
|
|
{
|
|
|
|
PolySet *ps = new PolySet();
|
|
|
|
|
|
|
|
typedef CGAL_Polyhedron::Vertex Vertex;
|
|
|
|
typedef CGAL_Polyhedron::Vertex_const_iterator VCI;
|
|
|
|
typedef CGAL_Polyhedron::Facet_const_iterator FCI;
|
|
|
|
typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC;
|
|
|
|
|
|
|
|
for (FCI fi = p.facets_begin(); fi != p.facets_end(); ++fi) {
|
|
|
|
HFCC hc = fi->facet_begin();
|
|
|
|
HFCC hc_end = hc;
|
|
|
|
Vertex v1, v2, v3;
|
|
|
|
v1 = *VCI((hc++)->vertex());
|
|
|
|
v3 = *VCI((hc++)->vertex());
|
|
|
|
do {
|
|
|
|
v2 = v3;
|
|
|
|
v3 = *VCI((hc++)->vertex());
|
|
|
|
double x1 = CGAL::to_double(v1.point().x());
|
|
|
|
double y1 = CGAL::to_double(v1.point().y());
|
|
|
|
double z1 = CGAL::to_double(v1.point().z());
|
|
|
|
double x2 = CGAL::to_double(v2.point().x());
|
|
|
|
double y2 = CGAL::to_double(v2.point().y());
|
|
|
|
double z2 = CGAL::to_double(v2.point().z());
|
|
|
|
double x3 = CGAL::to_double(v3.point().x());
|
|
|
|
double y3 = CGAL::to_double(v3.point().y());
|
|
|
|
double z3 = CGAL::to_double(v3.point().z());
|
|
|
|
ps->append_poly();
|
|
|
|
ps->append_vertex(x1, y1, z1);
|
|
|
|
ps->append_vertex(x2, y2, z2);
|
|
|
|
ps->append_vertex(x3, y3, z3);
|
|
|
|
} while (hc != hc_end);
|
|
|
|
}
|
|
|
|
return ps;
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef GEN_SURFACE_DEBUG
|
|
|
|
|
|
|
|
class CGAL_Build_PolySet : public CGAL::Modifier_base<CGAL_HDS>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef CGAL_HDS::Vertex::Point CGALPoint;
|
|
|
|
|
|
|
|
const PolySet &ps;
|
|
|
|
CGAL_Build_PolySet(const PolySet &ps) : ps(ps) { }
|
|
|
|
|
|
|
|
void operator()(CGAL_HDS& hds)
|
|
|
|
{
|
|
|
|
CGAL_Polybuilder B(hds, true);
|
|
|
|
|
|
|
|
std::vector<CGALPoint> vertices;
|
|
|
|
Grid3d<int> vertices_idx(GRID_FINE);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < ps.polygons.size(); i++) {
|
|
|
|
const PolySet::Polygon *poly = &ps.polygons[i];
|
|
|
|
for (size_t j = 0; j < poly->size(); j++) {
|
|
|
|
const Vector3d &p = poly->at(j);
|
|
|
|
if (!vertices_idx.has(p[0], p[1], p[2])) {
|
|
|
|
vertices_idx.data(p[0], p[1], p[2]) = vertices.size();
|
|
|
|
vertices.push_back(CGALPoint(p[0], p[1], p[2]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
B.begin_surface(vertices.size(), ps.polygons.size());
|
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
|
|
|
printf("=== CGAL Surface ===\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
for (size_t i = 0; i < vertices.size(); i++) {
|
|
|
|
const CGALPoint &p = vertices[i];
|
|
|
|
B.add_vertex(p);
|
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
|
|
|
printf("%d: %f %f %f\n", i, p[0], p[1], p[2]);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
for (size_t i = 0; i < ps.polygons.size(); i++) {
|
|
|
|
const PolySet::Polygon *poly = &ps.polygons[i];
|
|
|
|
QHash<int,int> fc;
|
|
|
|
bool facet_is_degenerated = false;
|
|
|
|
for (size_t j = 0; j < poly->size(); j++) {
|
|
|
|
const Vector3d &p = poly->at(j);
|
|
|
|
int v = vertices_idx.data(p[0], p[1], p[2]);
|
|
|
|
if (fc[v]++ > 0)
|
|
|
|
facet_is_degenerated = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!facet_is_degenerated)
|
|
|
|
B.begin_facet();
|
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
|
|
|
printf("F:");
|
|
|
|
#endif
|
|
|
|
for (size_t j = 0; j < poly->size(); j++) {
|
|
|
|
const Vector3d &p = poly->at(j);
|
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
|
|
|
printf(" %d (%f,%f,%f)", vertices_idx.data(p[0], p[1], p[2]), p[0], p[1], p[2]);
|
|
|
|
#endif
|
|
|
|
if (!facet_is_degenerated)
|
|
|
|
B.add_vertex_to_facet(vertices_idx.data(p[0], p[1], p[2]));
|
|
|
|
}
|
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
|
|
|
if (facet_is_degenerated)
|
|
|
|
printf(" (degenerated)");
|
|
|
|
printf("\n");
|
|
|
|
#endif
|
|
|
|
if (!facet_is_degenerated)
|
|
|
|
B.end_facet();
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef GEN_SURFACE_DEBUG
|
|
|
|
printf("====================\n");
|
|
|
|
#endif
|
|
|
|
B.end_surface();
|
|
|
|
|
|
|
|
#undef PointKey
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
CGAL_Polyhedron *createPolyhedronFromPolySet(const PolySet &ps)
|
|
|
|
{
|
|
|
|
CGAL_Polyhedron *P = NULL;
|
|
|
|
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
|
|
|
|
try {
|
|
|
|
P = new CGAL_Polyhedron;
|
|
|
|
CGAL_Build_PolySet builder(ps);
|
|
|
|
P->delegate(builder);
|
|
|
|
}
|
|
|
|
catch (CGAL::Assertion_exception e) {
|
2011-09-08 08:55:12 +04:00
|
|
|
PRINTF("CGAL error in CGAL_Build_PolySet: %s", e.what());
|
2011-09-08 00:04:59 +04:00
|
|
|
CGAL::set_error_behaviour(old_behaviour);
|
|
|
|
}
|
|
|
|
return P;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* ENABLE_CGAL */
|
|
|
|
|