2013-11-25 09:28:26 +04:00
|
|
|
#include "polyset-utils.h"
|
|
|
|
#include "polyset.h"
|
|
|
|
#include "Polygon2d.h"
|
2013-12-16 06:53:24 +04:00
|
|
|
#include "printutils.h"
|
2015-01-16 20:45:35 +03:00
|
|
|
#include "GeometryUtils.h"
|
2014-12-10 00:42:02 +03:00
|
|
|
#ifdef ENABLE_CGAL
|
2014-12-01 08:54:01 +03:00
|
|
|
#include "cgalutils.h"
|
2014-12-10 00:42:02 +03:00
|
|
|
#endif
|
2013-11-25 09:28:26 +04:00
|
|
|
|
|
|
|
#include <boost/foreach.hpp>
|
|
|
|
|
|
|
|
namespace PolysetUtils {
|
|
|
|
|
2013-11-26 10:31:55 +04:00
|
|
|
// Project all polygons (also back-facing) into a Polygon2d instance.
|
|
|
|
// It's important to select all faces, since filtering by normal vector here
|
|
|
|
// will trigger floating point incertainties and cause problems later.
|
2013-12-24 11:22:50 +04:00
|
|
|
Polygon2d *project(const PolySet &ps) {
|
2013-11-25 09:28:26 +04:00
|
|
|
Polygon2d *poly = new Polygon2d;
|
|
|
|
|
2014-11-26 23:22:15 +03:00
|
|
|
BOOST_FOREACH(const Polygon &p, ps.polygons) {
|
2013-11-25 09:28:26 +04:00
|
|
|
Outline2d outline;
|
|
|
|
BOOST_FOREACH(const Vector3d &v, p) {
|
2013-12-27 08:05:11 +04:00
|
|
|
outline.vertices.push_back(Vector2d(v[0], v[1]));
|
2013-11-25 09:28:26 +04:00
|
|
|
}
|
|
|
|
poly->addOutline(outline);
|
|
|
|
}
|
|
|
|
return poly;
|
|
|
|
}
|
|
|
|
|
2013-12-16 06:53:24 +04:00
|
|
|
/* Tessellation of 3d PolySet faces
|
|
|
|
|
|
|
|
This code is for tessellating the faces of a 3d PolySet, assuming that
|
|
|
|
the faces are near-planar polygons.
|
|
|
|
|
|
|
|
The purpose of this code is originally to fix github issue 349. Our CGAL
|
|
|
|
kernel does not accept polygons for Nef_Polyhedron_3 if each of the
|
|
|
|
points is not exactly coplanar. "Near-planar" or "Almost planar" polygons
|
|
|
|
often occur due to rounding issues on, for example, polyhedron() input.
|
|
|
|
By tessellating the 3d polygon into individual smaller tiles that
|
|
|
|
are perfectly coplanar (triangles, for example), we can get CGAL to accept
|
|
|
|
the polyhedron() input.
|
|
|
|
*/
|
|
|
|
|
2014-10-02 09:38:05 +04:00
|
|
|
/* Given a 3D PolySet with near planar polygonal faces, tessellate the
|
|
|
|
faces. As of writing, our only tessellation method is triangulation
|
2013-12-16 06:53:24 +04:00
|
|
|
using CGAL's Constrained Delaunay algorithm. This code assumes the input
|
2014-10-02 09:38:05 +04:00
|
|
|
polyset has simple polygon faces with no holes.
|
2014-12-01 08:54:01 +03:00
|
|
|
The tessellation will be robust wrt. degenerate and self-intersecting
|
2014-10-02 09:38:05 +04:00
|
|
|
*/
|
2013-12-16 06:53:24 +04:00
|
|
|
void tessellate_faces(const PolySet &inps, PolySet &outps) {
|
2014-09-04 22:40:03 +04:00
|
|
|
int degeneratePolygons = 0;
|
2013-12-16 06:53:24 +04:00
|
|
|
for (size_t i = 0; i < inps.polygons.size(); i++) {
|
2015-01-16 20:45:35 +03:00
|
|
|
const Polygon &pgon = inps.polygons[i];
|
2014-09-04 22:40:03 +04:00
|
|
|
if (pgon.size() < 3) {
|
|
|
|
degeneratePolygons++;
|
2014-09-16 04:51:41 +04:00
|
|
|
}
|
|
|
|
else {
|
2015-01-16 20:45:35 +03:00
|
|
|
Polygons triangles;
|
|
|
|
bool err = GeometryUtils::tessellatePolygon(pgon, triangles);
|
2015-02-05 20:08:08 +03:00
|
|
|
// Empty triangles tend to happen quite often,
|
|
|
|
// probably due to previous floating point conversion, so
|
|
|
|
// we don't issue any warnings.
|
|
|
|
if (!triangles.empty()) {
|
2015-01-16 20:45:35 +03:00
|
|
|
// ..and pass to the output polyhedron
|
|
|
|
BOOST_FOREACH(const Polygon &t, triangles) {
|
|
|
|
outps.append_poly();
|
|
|
|
outps.append_vertex(t[0]);
|
|
|
|
outps.append_vertex(t[1]);
|
|
|
|
outps.append_vertex(t[2]);
|
|
|
|
}
|
2014-10-02 09:38:05 +04:00
|
|
|
}
|
2014-09-16 04:51:41 +04:00
|
|
|
}
|
2013-12-16 06:53:24 +04:00
|
|
|
}
|
2014-09-04 22:40:03 +04:00
|
|
|
if (degeneratePolygons > 0) PRINT("WARNING: PolySet has degenerate polygons");
|
2013-12-16 06:53:24 +04:00
|
|
|
}
|
2014-12-10 00:42:02 +03:00
|
|
|
|
|
|
|
bool is_approximately_convex(const PolySet &ps) {
|
|
|
|
#ifdef ENABLE_CGAL
|
|
|
|
return CGALUtils::is_approximately_convex(ps);
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-11-25 09:28:26 +04:00
|
|
|
}
|