mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 08:47:52 -06:00
Hollowing: randomize hole mesh translations before unification.
To prevent self intersections in the output mesh.
This commit is contained in:
parent
f512892f6b
commit
eb4b24e136
4 changed files with 25 additions and 17 deletions
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue