Hollowing: randomize hole mesh translations before unification.

To prevent self intersections in the output mesh.
This commit is contained in:
tamasmeszaros 2020-02-07 16:33:04 +01:00
parent f512892f6b
commit eb4b24e136
4 changed files with 25 additions and 17 deletions

View file

@ -113,6 +113,9 @@ struct CGALMesh { _EpicMesh m; };
template<class _Mesh> void triangle_mesh_to_cgal(const TriangleMesh &M, _Mesh &out) template<class _Mesh> void triangle_mesh_to_cgal(const TriangleMesh &M, _Mesh &out)
{ {
using Index3 = std::array<size_t, 3>; using Index3 = std::array<size_t, 3>;
if (M.empty()) return;
std::vector<typename _Mesh::Point> points; std::vector<typename _Mesh::Point> points;
std::vector<Index3> indices; std::vector<Index3> indices;
points.reserve(M.its.vertices.size()); points.reserve(M.its.vertices.size());

View file

@ -25,7 +25,6 @@ void self_union(TriangleMesh& mesh);
namespace cgal { namespace cgal {
struct CGALMesh; struct CGALMesh;
struct CGALMeshDeleter { void operator()(CGALMesh *ptr); }; struct CGALMeshDeleter { void operator()(CGALMesh *ptr); };
std::unique_ptr<CGALMesh, CGALMeshDeleter> triangle_mesh_to_cgal(const TriangleMesh &M); std::unique_ptr<CGALMesh, CGALMeshDeleter> triangle_mesh_to_cgal(const TriangleMesh &M);

View file

@ -49,7 +49,7 @@ std::string OBJ_STEP_LABELS(size_t idx)
} }
assert(false); assert(false);
return "Out of bounds!"; return "Out of bounds!";
}; }
const std::array<unsigned, slapsCount> PRINT_STEP_LEVELS = { const std::array<unsigned, slapsCount> PRINT_STEP_LEVELS = {
10, // slapsMergeSlicesAndEval 10, // slapsMergeSlicesAndEval
@ -64,12 +64,13 @@ std::string PRINT_STEP_LABELS(size_t idx)
default:; default:;
} }
assert(false); return "Out of bounds!"; assert(false); return "Out of bounds!";
}; }
} }
SLAPrint::Steps::Steps(SLAPrint *print) SLAPrint::Steps::Steps(SLAPrint *print)
: m_print{print} : m_print{print}
, m_rng{std::random_device{}()}
, objcount{m_print->m_objects.size()} , objcount{m_print->m_objects.size()}
, ilhd{m_print->m_material_config.initial_layer_height.getFloat()} , ilhd{m_print->m_material_config.initial_layer_height.getFloat()}
, ilh{float(ilhd)} , ilh{float(ilhd)}
@ -137,28 +138,30 @@ void SLAPrint::Steps::drill_holes(SLAPrintObject &po)
BOOST_LOG_TRIVIAL(info) << "Drilling drainage holes."; BOOST_LOG_TRIVIAL(info) << "Drilling drainage holes.";
sla::DrainHoles drainholes = po.transformed_drainhole_points(); sla::DrainHoles drainholes = po.transformed_drainhole_points();
TriangleMesh holes_mesh; std::uniform_real_distribution<float> dist(1., float(EPSILON));
auto holes_mesh_cgal = MeshBoolean::cgal::triangle_mesh_to_cgal({});
for (const sla::DrainHole &holept : drainholes) for (const sla::DrainHole &holept : drainholes) {
holes_mesh.merge(sla::to_triangle_mesh(holept.to_mesh())); auto &&m = sla::to_triangle_mesh(holept.to_mesh());
float t = dist(m_rng);
holes_mesh.require_shared_vertices(); m.translate(t, t, t);
if (!holes_mesh.is_manifold() || MeshBoolean::cgal::does_self_intersect(holes_mesh)) { m.require_shared_vertices();
MeshBoolean::self_union(holes_mesh); auto cgal_m = MeshBoolean::cgal::triangle_mesh_to_cgal(m);
MeshBoolean::cgal::plus(*holes_mesh_cgal, *cgal_m);
if (MeshBoolean::cgal::does_self_intersect(holes_mesh))
throw std::runtime_error(L("Too much overlapping holes."));
} }
if (MeshBoolean::cgal::does_self_intersect(*holes_mesh_cgal))
throw std::runtime_error(L("Too much overlapping holes."));
auto hollowed_mesh_cgal = MeshBoolean::cgal::triangle_mesh_to_cgal(hollowed_mesh);
try { try {
MeshBoolean::cgal::minus(hollowed_mesh, holes_mesh); MeshBoolean::cgal::minus(*hollowed_mesh_cgal, *holes_mesh_cgal);
hollowed_mesh = MeshBoolean::cgal::cgal_to_triangle_mesh(*hollowed_mesh_cgal);
} catch (const std::runtime_error &) { } catch (const std::runtime_error &) {
throw std::runtime_error(L( throw std::runtime_error(L(
"Drilling holes into the mesh failed. " "Drilling holes into the mesh failed. "
"This is usually caused by broken model. Try to fix it first.")); "This is usually caused by broken model. Try to fix it first."));
} }
hollowed_mesh.require_shared_vertices();
} }
// The slicing will be performed on an imaginary 1D grid which starts from // The slicing will be performed on an imaginary 1D grid which starts from

View file

@ -1,6 +1,8 @@
#ifndef SLAPRINTSTEPS_HPP #ifndef SLAPRINTSTEPS_HPP
#define SLAPRINTSTEPS_HPP #define SLAPRINTSTEPS_HPP
#include <random>
#include <libslic3r/SLAPrint.hpp> #include <libslic3r/SLAPrint.hpp>
#include <libslic3r/SLA/Hollowing.hpp> #include <libslic3r/SLA/Hollowing.hpp>
@ -12,6 +14,7 @@ class SLAPrint::Steps
{ {
private: private:
SLAPrint *m_print = nullptr; SLAPrint *m_print = nullptr;
std::mt19937 m_rng;
public: public:
// where the per object operations start and end // where the per object operations start and end