Rename EigenMesh3D to IndexedMesh and SupportConfig to SupportTreeConfig

This commit is contained in:
tamasmeszaros 2020-06-25 13:58:51 +02:00
parent 645fbed88b
commit 1eec6c473c
21 changed files with 269 additions and 263 deletions

View File

@ -236,8 +236,8 @@ add_library(libslic3r STATIC
SLA/SupportPointGenerator.cpp SLA/SupportPointGenerator.cpp
SLA/Contour3D.hpp SLA/Contour3D.hpp
SLA/Contour3D.cpp SLA/Contour3D.cpp
SLA/EigenMesh3D.hpp SLA/IndexedMesh.hpp
SLA/EigenMesh3D.cpp SLA/IndexedMesh.cpp
SLA/Clustering.hpp SLA/Clustering.hpp
SLA/Clustering.cpp SLA/Clustering.cpp
SLA/ReprojectPointsOnMesh.hpp SLA/ReprojectPointsOnMesh.hpp

View File

@ -1,5 +1,5 @@
#include <libslic3r/SLA/Contour3D.hpp> #include <libslic3r/SLA/Contour3D.hpp>
#include <libslic3r/SLA/EigenMesh3D.hpp> #include <libslic3r/SLA/IndexedMesh.hpp>
#include <libslic3r/Format/objparser.hpp> #include <libslic3r/Format/objparser.hpp>
@ -27,7 +27,7 @@ Contour3D::Contour3D(TriangleMesh &&trmesh)
faces3.swap(trmesh.its.indices); faces3.swap(trmesh.its.indices);
} }
Contour3D::Contour3D(const EigenMesh3D &emesh) { Contour3D::Contour3D(const IndexedMesh &emesh) {
points.reserve(emesh.vertices().size()); points.reserve(emesh.vertices().size());
faces3.reserve(emesh.indices().size()); faces3.reserve(emesh.indices().size());

View File

@ -10,7 +10,7 @@ using Vec4i = Eigen::Matrix<int, 4, 1, Eigen::DontAlign>;
namespace sla { namespace sla {
class EigenMesh3D; class IndexedMesh;
/// Dumb vertex mesh consisting of triangles (or) quads. Capable of merging with /// Dumb vertex mesh consisting of triangles (or) quads. Capable of merging with
/// other meshes of this type and converting to and from other mesh formats. /// other meshes of this type and converting to and from other mesh formats.
@ -22,7 +22,7 @@ struct Contour3D {
Contour3D() = default; Contour3D() = default;
Contour3D(const TriangleMesh &trmesh); Contour3D(const TriangleMesh &trmesh);
Contour3D(TriangleMesh &&trmesh); Contour3D(TriangleMesh &&trmesh);
Contour3D(const EigenMesh3D &emesh); Contour3D(const IndexedMesh &emesh);
Contour3D& merge(const Contour3D& ctr); Contour3D& merge(const Contour3D& ctr);
Contour3D& merge(const Pointf3s& triangles); Contour3D& merge(const Pointf3s& triangles);

View File

@ -3,7 +3,7 @@
#include <libslic3r/OpenVDBUtils.hpp> #include <libslic3r/OpenVDBUtils.hpp>
#include <libslic3r/TriangleMesh.hpp> #include <libslic3r/TriangleMesh.hpp>
#include <libslic3r/SLA/Hollowing.hpp> #include <libslic3r/SLA/Hollowing.hpp>
#include <libslic3r/SLA/EigenMesh3D.hpp> #include <libslic3r/SLA/IndexedMesh.hpp>
#include <libslic3r/ClipperUtils.hpp> #include <libslic3r/ClipperUtils.hpp>
#include <libslic3r/SimplifyMesh.hpp> #include <libslic3r/SimplifyMesh.hpp>
#include <libslic3r/SLA/SupportTreeMesher.hpp> #include <libslic3r/SLA/SupportTreeMesher.hpp>
@ -159,7 +159,7 @@ bool DrainHole::get_intersections(const Vec3f& s, const Vec3f& dir,
const Eigen::ParametrizedLine<float, 3> ray(s, dir.normalized()); const Eigen::ParametrizedLine<float, 3> ray(s, dir.normalized());
for (size_t i=0; i<2; ++i) for (size_t i=0; i<2; ++i)
out[i] = std::make_pair(sla::EigenMesh3D::hit_result::infty(), Vec3d::Zero()); out[i] = std::make_pair(sla::IndexedMesh::hit_result::infty(), Vec3d::Zero());
const float sqr_radius = pow(radius, 2.f); const float sqr_radius = pow(radius, 2.f);

View File

@ -1,4 +1,4 @@
#include "EigenMesh3D.hpp" #include "IndexedMesh.hpp"
#include "Concurrency.hpp" #include "Concurrency.hpp"
#include <libslic3r/AABBTreeIndirect.hpp> #include <libslic3r/AABBTreeIndirect.hpp>
@ -12,7 +12,7 @@
namespace Slic3r { namespace sla { namespace Slic3r { namespace sla {
class EigenMesh3D::AABBImpl { class IndexedMesh::AABBImpl {
private: private:
AABBTreeIndirect::Tree3f m_tree; AABBTreeIndirect::Tree3f m_tree;
@ -57,7 +57,7 @@ public:
static const constexpr double MESH_EPS = 1e-6; static const constexpr double MESH_EPS = 1e-6;
EigenMesh3D::EigenMesh3D(const TriangleMesh& tmesh) IndexedMesh::IndexedMesh(const TriangleMesh& tmesh)
: m_aabb(new AABBImpl()), m_tm(&tmesh) : m_aabb(new AABBImpl()), m_tm(&tmesh)
{ {
auto&& bb = tmesh.bounding_box(); auto&& bb = tmesh.bounding_box();
@ -67,61 +67,61 @@ EigenMesh3D::EigenMesh3D(const TriangleMesh& tmesh)
m_aabb->init(tmesh); m_aabb->init(tmesh);
} }
EigenMesh3D::~EigenMesh3D() {} IndexedMesh::~IndexedMesh() {}
EigenMesh3D::EigenMesh3D(const EigenMesh3D &other): IndexedMesh::IndexedMesh(const IndexedMesh &other):
m_tm(other.m_tm), m_ground_level(other.m_ground_level), m_tm(other.m_tm), m_ground_level(other.m_ground_level),
m_aabb( new AABBImpl(*other.m_aabb) ) {} m_aabb( new AABBImpl(*other.m_aabb) ) {}
EigenMesh3D &EigenMesh3D::operator=(const EigenMesh3D &other) IndexedMesh &IndexedMesh::operator=(const IndexedMesh &other)
{ {
m_tm = other.m_tm; m_tm = other.m_tm;
m_ground_level = other.m_ground_level; m_ground_level = other.m_ground_level;
m_aabb.reset(new AABBImpl(*other.m_aabb)); return *this; m_aabb.reset(new AABBImpl(*other.m_aabb)); return *this;
} }
EigenMesh3D &EigenMesh3D::operator=(EigenMesh3D &&other) = default; IndexedMesh &IndexedMesh::operator=(IndexedMesh &&other) = default;
EigenMesh3D::EigenMesh3D(EigenMesh3D &&other) = default; IndexedMesh::IndexedMesh(IndexedMesh &&other) = default;
const std::vector<Vec3f>& EigenMesh3D::vertices() const const std::vector<Vec3f>& IndexedMesh::vertices() const
{ {
return m_tm->its.vertices; return m_tm->its.vertices;
} }
const std::vector<Vec3i>& EigenMesh3D::indices() const const std::vector<Vec3i>& IndexedMesh::indices() const
{ {
return m_tm->its.indices; return m_tm->its.indices;
} }
const Vec3f& EigenMesh3D::vertices(size_t idx) const const Vec3f& IndexedMesh::vertices(size_t idx) const
{ {
return m_tm->its.vertices[idx]; return m_tm->its.vertices[idx];
} }
const Vec3i& EigenMesh3D::indices(size_t idx) const const Vec3i& IndexedMesh::indices(size_t idx) const
{ {
return m_tm->its.indices[idx]; return m_tm->its.indices[idx];
} }
Vec3d EigenMesh3D::normal_by_face_id(int face_id) const { Vec3d IndexedMesh::normal_by_face_id(int face_id) const {
return m_tm->stl.facet_start[face_id].normal.cast<double>(); return m_tm->stl.facet_start[face_id].normal.cast<double>();
} }
EigenMesh3D::hit_result IndexedMesh::hit_result
EigenMesh3D::query_ray_hit(const Vec3d &s, const Vec3d &dir) const IndexedMesh::query_ray_hit(const Vec3d &s, const Vec3d &dir) const
{ {
assert(is_approx(dir.norm(), 1.)); assert(is_approx(dir.norm(), 1.));
igl::Hit hit; igl::Hit hit;
@ -149,10 +149,10 @@ EigenMesh3D::query_ray_hit(const Vec3d &s, const Vec3d &dir) const
return ret; return ret;
} }
std::vector<EigenMesh3D::hit_result> std::vector<IndexedMesh::hit_result>
EigenMesh3D::query_ray_hits(const Vec3d &s, const Vec3d &dir) const IndexedMesh::query_ray_hits(const Vec3d &s, const Vec3d &dir) const
{ {
std::vector<EigenMesh3D::hit_result> outs; std::vector<IndexedMesh::hit_result> outs;
std::vector<igl::Hit> hits; std::vector<igl::Hit> hits;
m_aabb->intersect_ray(*m_tm, s, dir, hits); m_aabb->intersect_ray(*m_tm, s, dir, hits);
@ -170,7 +170,7 @@ EigenMesh3D::query_ray_hits(const Vec3d &s, const Vec3d &dir) const
// Convert the igl::Hit into hit_result // Convert the igl::Hit into hit_result
outs.reserve(hits.size()); outs.reserve(hits.size());
for (const igl::Hit& hit : hits) { for (const igl::Hit& hit : hits) {
outs.emplace_back(EigenMesh3D::hit_result(*this)); outs.emplace_back(IndexedMesh::hit_result(*this));
outs.back().m_t = double(hit.t); outs.back().m_t = double(hit.t);
outs.back().m_dir = dir; outs.back().m_dir = dir;
outs.back().m_source = s; outs.back().m_source = s;
@ -185,8 +185,8 @@ EigenMesh3D::query_ray_hits(const Vec3d &s, const Vec3d &dir) const
#ifdef SLIC3R_HOLE_RAYCASTER #ifdef SLIC3R_HOLE_RAYCASTER
EigenMesh3D::hit_result EigenMesh3D::filter_hits( IndexedMesh::hit_result IndexedMesh::filter_hits(
const std::vector<EigenMesh3D::hit_result>& object_hits) const const std::vector<IndexedMesh::hit_result>& object_hits) const
{ {
assert(! m_holes.empty()); assert(! m_holes.empty());
hit_result out(*this); hit_result out(*this);
@ -282,7 +282,7 @@ EigenMesh3D::hit_result EigenMesh3D::filter_hits(
#endif #endif
double EigenMesh3D::squared_distance(const Vec3d &p, int& i, Vec3d& c) const { double IndexedMesh::squared_distance(const Vec3d &p, int& i, Vec3d& c) const {
double sqdst = 0; double sqdst = 0;
Eigen::Matrix<double, 1, 3> pp = p; Eigen::Matrix<double, 1, 3> pp = p;
Eigen::Matrix<double, 1, 3> cc; Eigen::Matrix<double, 1, 3> cc;
@ -303,7 +303,7 @@ static bool point_on_edge(const Vec3d& p, const Vec3d& e1, const Vec3d& e2,
} }
PointSet normals(const PointSet& points, PointSet normals(const PointSet& points,
const EigenMesh3D& mesh, const IndexedMesh& mesh,
double eps, double eps,
std::function<void()> thr, // throw on cancel std::function<void()> thr, // throw on cancel
const std::vector<unsigned>& pt_indices) const std::vector<unsigned>& pt_indices)

View File

@ -1,5 +1,5 @@
#ifndef SLA_EIGENMESH3D_H #ifndef SLA_INDEXEDMESH_H
#define SLA_EIGENMESH3D_H #define SLA_INDEXEDMESH_H
#include <memory> #include <memory>
#include <vector> #include <vector>
@ -26,7 +26,7 @@ using PointSet = Eigen::MatrixXd;
/// An index-triangle structure for libIGL functions. Also serves as an /// An index-triangle structure for libIGL functions. Also serves as an
/// alternative (raw) input format for the SLASupportTree. /// alternative (raw) input format for the SLASupportTree.
// Implemented in libslic3r/SLA/Common.cpp // Implemented in libslic3r/SLA/Common.cpp
class EigenMesh3D { class IndexedMesh {
class AABBImpl; class AABBImpl;
const TriangleMesh* m_tm; const TriangleMesh* m_tm;
@ -42,15 +42,15 @@ class EigenMesh3D {
public: public:
explicit EigenMesh3D(const TriangleMesh&); explicit IndexedMesh(const TriangleMesh&);
EigenMesh3D(const EigenMesh3D& other); IndexedMesh(const IndexedMesh& other);
EigenMesh3D& operator=(const EigenMesh3D&); IndexedMesh& operator=(const IndexedMesh&);
EigenMesh3D(EigenMesh3D &&other); IndexedMesh(IndexedMesh &&other);
EigenMesh3D& operator=(EigenMesh3D &&other); IndexedMesh& operator=(IndexedMesh &&other);
~EigenMesh3D(); ~IndexedMesh();
inline double ground_level() const { return m_ground_level + m_gnd_offset; } inline double ground_level() const { return m_ground_level + m_gnd_offset; }
inline void ground_level_offset(double o) { m_gnd_offset = o; } inline void ground_level_offset(double o) { m_gnd_offset = o; }
@ -66,15 +66,15 @@ public:
// m_t holds a distance from m_source to the intersection. // m_t holds a distance from m_source to the intersection.
double m_t = infty(); double m_t = infty();
int m_face_id = -1; int m_face_id = -1;
const EigenMesh3D *m_mesh = nullptr; const IndexedMesh *m_mesh = nullptr;
Vec3d m_dir; Vec3d m_dir;
Vec3d m_source; Vec3d m_source;
Vec3d m_normal; Vec3d m_normal;
friend class EigenMesh3D; friend class IndexedMesh;
// A valid object of this class can only be obtained from // A valid object of this class can only be obtained from
// EigenMesh3D::query_ray_hit method. // IndexedMesh::query_ray_hit method.
explicit inline hit_result(const EigenMesh3D& em): m_mesh(&em) {} explicit inline hit_result(const IndexedMesh& em): m_mesh(&em) {}
public: public:
// This denotes no hit on the mesh. // This denotes no hit on the mesh.
static inline constexpr double infty() { return std::numeric_limits<double>::infinity(); } static inline constexpr double infty() { return std::numeric_limits<double>::infinity(); }
@ -111,7 +111,7 @@ public:
// This function is currently not used anywhere, it was written when the // This function is currently not used anywhere, it was written when the
// holes were subtracted on slices, that is, before we started using CGAL // holes were subtracted on slices, that is, before we started using CGAL
// to actually cut the holes into the mesh. // to actually cut the holes into the mesh.
hit_result filter_hits(const std::vector<EigenMesh3D::hit_result>& obj_hits) const; hit_result filter_hits(const std::vector<IndexedMesh::hit_result>& obj_hits) const;
#endif #endif
// Casting a ray on the mesh, returns the distance where the hit occures. // Casting a ray on the mesh, returns the distance where the hit occures.
@ -136,11 +136,11 @@ public:
// Calculate the normals for the selected points (from 'points' set) on the // Calculate the normals for the selected points (from 'points' set) on the
// mesh. This will call squared distance for each point. // mesh. This will call squared distance for each point.
PointSet normals(const PointSet& points, PointSet normals(const PointSet& points,
const EigenMesh3D& convert_mesh, const IndexedMesh& convert_mesh,
double eps = 0.05, // min distance from edges double eps = 0.05, // min distance from edges
std::function<void()> throw_on_cancel = [](){}, std::function<void()> throw_on_cancel = [](){},
const std::vector<unsigned>& selected_points = {}); const std::vector<unsigned>& selected_points = {});
}} // namespace Slic3r::sla }} // namespace Slic3r::sla
#endif // EIGENMESH3D_H #endif // INDEXEDMESH_H

View File

@ -4,7 +4,7 @@
#include "libslic3r/Point.hpp" #include "libslic3r/Point.hpp"
#include "SupportPoint.hpp" #include "SupportPoint.hpp"
#include "Hollowing.hpp" #include "Hollowing.hpp"
#include "EigenMesh3D.hpp" #include "IndexedMesh.hpp"
#include "libslic3r/Model.hpp" #include "libslic3r/Model.hpp"
#include <tbb/parallel_for.h> #include <tbb/parallel_for.h>
@ -15,7 +15,7 @@ template<class Pt> Vec3d pos(const Pt &p) { return p.pos.template cast<double>()
template<class Pt> void pos(Pt &p, const Vec3d &pp) { p.pos = pp.cast<float>(); } template<class Pt> void pos(Pt &p, const Vec3d &pp) { p.pos = pp.cast<float>(); }
template<class PointType> template<class PointType>
void reproject_support_points(const EigenMesh3D &mesh, std::vector<PointType> &pts) void reproject_support_points(const IndexedMesh &mesh, std::vector<PointType> &pts)
{ {
tbb::parallel_for(size_t(0), pts.size(), [&mesh, &pts](size_t idx) { tbb::parallel_for(size_t(0), pts.size(), [&mesh, &pts](size_t idx) {
int junk; int junk;
@ -40,7 +40,7 @@ inline void reproject_points_and_holes(ModelObject *object)
TriangleMesh rmsh = object->raw_mesh(); TriangleMesh rmsh = object->raw_mesh();
rmsh.require_shared_vertices(); rmsh.require_shared_vertices();
EigenMesh3D emesh{rmsh}; IndexedMesh emesh{rmsh};
if (has_sppoints) if (has_sppoints)
reproject_support_points(emesh, object->sla_support_points); reproject_support_points(emesh, object->sla_support_points);

View File

@ -50,7 +50,7 @@ float SupportPointGenerator::distance_limit(float angle) const
}*/ }*/
SupportPointGenerator::SupportPointGenerator( SupportPointGenerator::SupportPointGenerator(
const sla::EigenMesh3D &emesh, const sla::IndexedMesh &emesh,
const std::vector<ExPolygons> &slices, const std::vector<ExPolygons> &slices,
const std::vector<float> & heights, const std::vector<float> & heights,
const Config & config, const Config & config,
@ -64,7 +64,7 @@ SupportPointGenerator::SupportPointGenerator(
} }
SupportPointGenerator::SupportPointGenerator( SupportPointGenerator::SupportPointGenerator(
const EigenMesh3D &emesh, const IndexedMesh &emesh,
const SupportPointGenerator::Config &config, const SupportPointGenerator::Config &config,
std::function<void ()> throw_on_cancel, std::function<void ()> throw_on_cancel,
std::function<void (int)> statusfn) std::function<void (int)> statusfn)
@ -95,8 +95,8 @@ void SupportPointGenerator::project_onto_mesh(std::vector<sla::SupportPoint>& po
m_throw_on_cancel(); m_throw_on_cancel();
Vec3f& p = points[point_id].pos; Vec3f& p = points[point_id].pos;
// Project the point upward and downward and choose the closer intersection with the mesh. // Project the point upward and downward and choose the closer intersection with the mesh.
sla::EigenMesh3D::hit_result hit_up = m_emesh.query_ray_hit(p.cast<double>(), Vec3d(0., 0., 1.)); sla::IndexedMesh::hit_result hit_up = m_emesh.query_ray_hit(p.cast<double>(), Vec3d(0., 0., 1.));
sla::EigenMesh3D::hit_result hit_down = m_emesh.query_ray_hit(p.cast<double>(), Vec3d(0., 0., -1.)); sla::IndexedMesh::hit_result hit_down = m_emesh.query_ray_hit(p.cast<double>(), Vec3d(0., 0., -1.));
bool up = hit_up.is_hit(); bool up = hit_up.is_hit();
bool down = hit_down.is_hit(); bool down = hit_down.is_hit();
@ -104,7 +104,7 @@ void SupportPointGenerator::project_onto_mesh(std::vector<sla::SupportPoint>& po
if (!up && !down) if (!up && !down)
continue; continue;
sla::EigenMesh3D::hit_result& hit = (!down || (hit_up.distance() < hit_down.distance())) ? hit_up : hit_down; sla::IndexedMesh::hit_result& hit = (!down || (hit_up.distance() < hit_down.distance())) ? hit_up : hit_down;
p = p + (hit.distance() * hit.direction()).cast<float>(); p = p + (hit.distance() * hit.direction()).cast<float>();
} }
}); });

View File

@ -4,7 +4,7 @@
#include <random> #include <random>
#include <libslic3r/SLA/SupportPoint.hpp> #include <libslic3r/SLA/SupportPoint.hpp>
#include <libslic3r/SLA/EigenMesh3D.hpp> #include <libslic3r/SLA/IndexedMesh.hpp>
#include <libslic3r/BoundingBox.hpp> #include <libslic3r/BoundingBox.hpp>
#include <libslic3r/ClipperUtils.hpp> #include <libslic3r/ClipperUtils.hpp>
@ -27,10 +27,10 @@ public:
inline float tear_pressure() const { return 1.f; } // pressure that the display exerts (the force unit per mm2) inline float tear_pressure() const { return 1.f; } // pressure that the display exerts (the force unit per mm2)
}; };
SupportPointGenerator(const EigenMesh3D& emesh, const std::vector<ExPolygons>& slices, SupportPointGenerator(const IndexedMesh& emesh, const std::vector<ExPolygons>& slices,
const std::vector<float>& heights, const Config& config, std::function<void(void)> throw_on_cancel, std::function<void(int)> statusfn); const std::vector<float>& heights, const Config& config, std::function<void(void)> throw_on_cancel, std::function<void(int)> statusfn);
SupportPointGenerator(const EigenMesh3D& emesh, const Config& config, std::function<void(void)> throw_on_cancel, std::function<void(int)> statusfn); SupportPointGenerator(const IndexedMesh& emesh, const Config& config, std::function<void(void)> throw_on_cancel, std::function<void(int)> statusfn);
const std::vector<SupportPoint>& output() const { return m_output; } const std::vector<SupportPoint>& output() const { return m_output; }
std::vector<SupportPoint>& output() { return m_output; } std::vector<SupportPoint>& output() { return m_output; }
@ -206,7 +206,7 @@ private:
static void output_structures(const std::vector<Structure> &structures); static void output_structures(const std::vector<Structure> &structures);
#endif // SLA_SUPPORTPOINTGEN_DEBUG #endif // SLA_SUPPORTPOINTGEN_DEBUG
const EigenMesh3D& m_emesh; const IndexedMesh& m_emesh;
std::function<void(void)> m_throw_on_cancel; std::function<void(void)> m_throw_on_cancel;
std::function<void(int)> m_statusfn; std::function<void(int)> m_statusfn;

View File

@ -6,7 +6,7 @@
#include <Eigen/Geometry> #include <Eigen/Geometry>
#include <libslic3r/SLA/Pad.hpp> #include <libslic3r/SLA/Pad.hpp>
#include <libslic3r/SLA/EigenMesh3D.hpp> #include <libslic3r/SLA/IndexedMesh.hpp>
#include <libslic3r/SLA/SupportPoint.hpp> #include <libslic3r/SLA/SupportPoint.hpp>
#include <libslic3r/SLA/JobController.hpp> #include <libslic3r/SLA/JobController.hpp>
@ -31,7 +31,7 @@ enum class PillarConnectionMode
dynamic dynamic
}; };
struct SupportConfig struct SupportTreeConfig
{ {
bool enabled = true; bool enabled = true;
@ -107,23 +107,30 @@ struct SupportConfig
}; };
// TODO: Part of future refactor
//class SupportConfig {
// std::optional<SupportTreeConfig> tree_cfg {std::in_place_t{}}; // fill up
// std::optional<PadConfig> pad_cfg;
//};
enum class MeshType { Support, Pad }; enum class MeshType { Support, Pad };
struct SupportableMesh struct SupportableMesh
{ {
EigenMesh3D emesh; IndexedMesh emesh;
SupportPoints pts; SupportPoints pts;
SupportConfig cfg; SupportTreeConfig cfg;
PadConfig pad_cfg;
explicit SupportableMesh(const TriangleMesh & trmsh, explicit SupportableMesh(const TriangleMesh & trmsh,
const SupportPoints &sp, const SupportPoints &sp,
const SupportConfig &c) const SupportTreeConfig &c)
: emesh{trmsh}, pts{sp}, cfg{c} : emesh{trmsh}, pts{sp}, cfg{c}
{} {}
explicit SupportableMesh(const EigenMesh3D &em, explicit SupportableMesh(const IndexedMesh &em,
const SupportPoints &sp, const SupportPoints &sp,
const SupportConfig &c) const SupportTreeConfig &c)
: emesh{em}, pts{sp}, cfg{c} : emesh{em}, pts{sp}, cfg{c}
{} {}
}; };

View File

@ -14,7 +14,7 @@ using libnest2d::opt::StopCriteria;
using libnest2d::opt::GeneticOptimizer; using libnest2d::opt::GeneticOptimizer;
using libnest2d::opt::SubplexOptimizer; using libnest2d::opt::SubplexOptimizer;
template<class C, class Hit = EigenMesh3D::hit_result> template<class C, class Hit = IndexedMesh::hit_result>
static Hit min_hit(const C &hits) static Hit min_hit(const C &hits)
{ {
auto mit = std::min_element(hits.begin(), hits.end(), auto mit = std::min_element(hits.begin(), hits.end(),
@ -25,118 +25,118 @@ static Hit min_hit(const C &hits)
return *mit; return *mit;
} }
EigenMesh3D::hit_result query_hit(const SupportableMesh &msh, const Head &h) //IndexedMesh::hit_result query_hit(const SupportableMesh &msh, const Head &h)
{ //{
static const size_t SAMPLES = 8; // static const size_t SAMPLES = 8;
// Move away slightly from the touching point to avoid raycasting on the // // Move away slightly from the touching point to avoid raycasting on the
// inner surface of the mesh. // // inner surface of the mesh.
const double& sd = msh.cfg.safety_distance_mm; // const double& sd = msh.cfg.safety_distance_mm;
auto& m = msh.emesh; // auto& m = msh.emesh;
using HitResult = EigenMesh3D::hit_result; // using HitResult = IndexedMesh::hit_result;
// Hit results // // Hit results
std::array<HitResult, SAMPLES> hits; // std::array<HitResult, SAMPLES> hits;
Vec3d s1 = h.pos, s2 = h.junction_point(); // Vec3d s1 = h.pos, s2 = h.junction_point();
struct Rings { // struct Rings {
double rpin; // double rpin;
double rback; // double rback;
Vec3d spin; // Vec3d spin;
Vec3d sback; // Vec3d sback;
PointRing<SAMPLES> ring; // PointRing<SAMPLES> ring;
Vec3d backring(size_t idx) { return ring.get(idx, sback, rback); } // Vec3d backring(size_t idx) { return ring.get(idx, sback, rback); }
Vec3d pinring(size_t idx) { return ring.get(idx, spin, rpin); } // Vec3d pinring(size_t idx) { return ring.get(idx, spin, rpin); }
} rings {h.r_pin_mm + sd, h.r_back_mm + sd, s1, s2, h.dir}; // } rings {h.r_pin_mm + sd, h.r_back_mm + sd, s1, s2, h.dir};
// We will shoot multiple rays from the head pinpoint in the direction // // We will shoot multiple rays from the head pinpoint in the direction
// of the pinhead robe (side) surface. The result will be the smallest // // of the pinhead robe (side) surface. The result will be the smallest
// hit distance. // // hit distance.
auto hitfn = [&m, &rings, sd](HitResult &hit, size_t i) { // auto hitfn = [&m, &rings, sd](HitResult &hit, size_t i) {
// Point on the circle on the pin sphere // // Point on the circle on the pin sphere
Vec3d ps = rings.pinring(i); // Vec3d ps = rings.pinring(i);
// This is the point on the circle on the back sphere // // This is the point on the circle on the back sphere
Vec3d p = rings.backring(i); // Vec3d p = rings.backring(i);
// Point ps is not on mesh but can be inside or // // Point ps is not on mesh but can be inside or
// outside as well. This would cause many problems // // outside as well. This would cause many problems
// with ray-casting. To detect the position we will // // with ray-casting. To detect the position we will
// use the ray-casting result (which has an is_inside // // use the ray-casting result (which has an is_inside
// predicate). // // predicate).
Vec3d n = (p - ps).normalized(); // Vec3d n = (p - ps).normalized();
auto q = m.query_ray_hit(ps + sd * n, n); // auto q = m.query_ray_hit(ps + sd * n, n);
if (q.is_inside()) { // the hit is inside the model // if (q.is_inside()) { // the hit is inside the model
if (q.distance() > rings.rpin) { // if (q.distance() > rings.rpin) {
// If we are inside the model and the hit // // If we are inside the model and the hit
// distance is bigger than our pin circle // // distance is bigger than our pin circle
// diameter, it probably indicates that the // // diameter, it probably indicates that the
// support point was already inside the // // support point was already inside the
// model, or there is really no space // // model, or there is really no space
// around the point. We will assign a zero // // around the point. We will assign a zero
// hit distance to these cases which will // // hit distance to these cases which will
// enforce the function return value to be // // enforce the function return value to be
// an invalid ray with zero hit distance. // // an invalid ray with zero hit distance.
// (see min_element at the end) // // (see min_element at the end)
hit = HitResult(0.0); // hit = HitResult(0.0);
} else { // } else {
// re-cast the ray from the outside of the // // re-cast the ray from the outside of the
// object. The starting point has an offset // // object. The starting point has an offset
// of 2*safety_distance because the // // of 2*safety_distance because the
// original ray has also had an offset // // original ray has also had an offset
auto q2 = m.query_ray_hit(ps + (q.distance() + 2 * sd) * n, n); // auto q2 = m.query_ray_hit(ps + (q.distance() + 2 * sd) * n, n);
hit = q2; // hit = q2;
} // }
} else // } else
hit = q; // hit = q;
}; // };
ccr::enumerate(hits.begin(), hits.end(), hitfn); // ccr::enumerate(hits.begin(), hits.end(), hitfn);
return min_hit(hits); // return min_hit(hits);
} //}
EigenMesh3D::hit_result query_hit(const SupportableMesh &msh, const Bridge &br, double safety_d) //IndexedMesh::hit_result query_hit(const SupportableMesh &msh, const Bridge &br, double safety_d)
{ //{
static const size_t SAMPLES = 8; // static const size_t SAMPLES = 8;
Vec3d dir = (br.endp - br.startp).normalized(); // Vec3d dir = (br.endp - br.startp).normalized();
PointRing<SAMPLES> ring{dir}; // PointRing<SAMPLES> ring{dir};
using Hit = EigenMesh3D::hit_result; // using Hit = IndexedMesh::hit_result;
// Hit results // // Hit results
std::array<Hit, SAMPLES> hits; // std::array<Hit, SAMPLES> hits;
double sd = std::isnan(safety_d) ? msh.cfg.safety_distance_mm : safety_d; // double sd = std::isnan(safety_d) ? msh.cfg.safety_distance_mm : safety_d;
auto hitfn = [&msh, &br, &ring, dir, sd] (Hit &hit, size_t i) { // auto hitfn = [&msh, &br, &ring, dir, sd] (Hit &hit, size_t i) {
// Point on the circle on the pin sphere // // Point on the circle on the pin sphere
Vec3d p = ring.get(i, br.startp, br.r + sd); // Vec3d p = ring.get(i, br.startp, br.r + sd);
auto hr = msh.emesh.query_ray_hit(p + br.r * dir, dir); // auto hr = msh.emesh.query_ray_hit(p + br.r * dir, dir);
if(hr.is_inside()) { // if(hr.is_inside()) {
if(hr.distance() > 2 * br.r + sd) hit = Hit(0.0); // if(hr.distance() > 2 * br.r + sd) hit = Hit(0.0);
else { // else {
// re-cast the ray from the outside of the object // // re-cast the ray from the outside of the object
hit = msh.emesh.query_ray_hit(p + (hr.distance() + 2 * sd) * dir, dir); // hit = msh.emesh.query_ray_hit(p + (hr.distance() + 2 * sd) * dir, dir);
} // }
} else hit = hr; // } else hit = hr;
}; // };
ccr::enumerate(hits.begin(), hits.end(), hitfn); // ccr::enumerate(hits.begin(), hits.end(), hitfn);
return min_hit(hits); // return min_hit(hits);
} //}
SupportTreeBuildsteps::SupportTreeBuildsteps(SupportTreeBuilder & builder, SupportTreeBuildsteps::SupportTreeBuildsteps(SupportTreeBuilder & builder,
const SupportableMesh &sm) const SupportableMesh &sm)
@ -281,7 +281,7 @@ bool SupportTreeBuildsteps::execute(SupportTreeBuilder & builder,
return pc == ABORT; return pc == ABORT;
} }
EigenMesh3D::hit_result SupportTreeBuildsteps::pinhead_mesh_intersect( IndexedMesh::hit_result SupportTreeBuildsteps::pinhead_mesh_intersect(
const Vec3d &s, const Vec3d &dir, double r_pin, double r_back, double width) const Vec3d &s, const Vec3d &dir, double r_pin, double r_back, double width)
{ {
static const size_t SAMPLES = 8; static const size_t SAMPLES = 8;
@ -292,7 +292,7 @@ EigenMesh3D::hit_result SupportTreeBuildsteps::pinhead_mesh_intersect(
const double& sd = m_cfg.safety_distance_mm; const double& sd = m_cfg.safety_distance_mm;
auto& m = m_mesh; auto& m = m_mesh;
using HitResult = EigenMesh3D::hit_result; using HitResult = IndexedMesh::hit_result;
// Hit results // Hit results
std::array<HitResult, SAMPLES> hits; std::array<HitResult, SAMPLES> hits;
@ -357,13 +357,13 @@ EigenMesh3D::hit_result SupportTreeBuildsteps::pinhead_mesh_intersect(
return min_hit(hits); return min_hit(hits);
} }
EigenMesh3D::hit_result SupportTreeBuildsteps::bridge_mesh_intersect( IndexedMesh::hit_result SupportTreeBuildsteps::bridge_mesh_intersect(
const Vec3d &src, const Vec3d &dir, double r, double sd) const Vec3d &src, const Vec3d &dir, double r, double sd)
{ {
static const size_t SAMPLES = 8; static const size_t SAMPLES = 8;
PointRing<SAMPLES> ring{dir}; PointRing<SAMPLES> ring{dir};
using Hit = EigenMesh3D::hit_result; using Hit = IndexedMesh::hit_result;
// Hit results // Hit results
std::array<Hit, SAMPLES> hits; std::array<Hit, SAMPLES> hits;
@ -742,7 +742,7 @@ void SupportTreeBuildsteps::filter()
auto nn = spheric_to_dir(polar, azimuth).normalized(); auto nn = spheric_to_dir(polar, azimuth).normalized();
// check available distance // check available distance
EigenMesh3D::hit_result t IndexedMesh::hit_result t
= pinhead_mesh_intersect(hp, // touching point = pinhead_mesh_intersect(hp, // touching point
nn, // normal nn, // normal
pin_r, pin_r,
@ -781,7 +781,7 @@ void SupportTreeBuildsteps::filter()
polar = std::get<0>(oresult.optimum); polar = std::get<0>(oresult.optimum);
azimuth = std::get<1>(oresult.optimum); azimuth = std::get<1>(oresult.optimum);
nn = spheric_to_dir(polar, azimuth).normalized(); nn = spheric_to_dir(polar, azimuth).normalized();
t = EigenMesh3D::hit_result(oresult.score); t = IndexedMesh::hit_result(oresult.score);
} }
} }

View File

@ -103,9 +103,8 @@ public:
} }
}; };
EigenMesh3D::hit_result query_hit(const SupportableMesh &msh, const Bridge &br, double safety_d = std::nan("")); //IndexedMesh::hit_result query_hit(const SupportableMesh &msh, const Bridge &br, double safety_d = std::nan(""));
EigenMesh3D::hit_result query_hit(const SupportableMesh &msh, const Head &br, double safety_d = std::nan("")); //IndexedMesh::hit_result query_hit(const SupportableMesh &msh, const Head &br, double safety_d = std::nan(""));
inline Vec3d dirv(const Vec3d& startp, const Vec3d& endp) { inline Vec3d dirv(const Vec3d& startp, const Vec3d& endp) {
return (endp - startp).normalized(); return (endp - startp).normalized();
@ -181,8 +180,8 @@ IntegerOnly<DoubleI> pairhash(I a, I b)
} }
class SupportTreeBuildsteps { class SupportTreeBuildsteps {
const SupportConfig& m_cfg; const SupportTreeConfig& m_cfg;
const EigenMesh3D& m_mesh; const IndexedMesh& m_mesh;
const std::vector<SupportPoint>& m_support_pts; const std::vector<SupportPoint>& m_support_pts;
using PtIndices = std::vector<unsigned>; using PtIndices = std::vector<unsigned>;
@ -191,7 +190,7 @@ class SupportTreeBuildsteps {
PtIndices m_iheads_onmodel; PtIndices m_iheads_onmodel;
PtIndices m_iheadless; // headless support points PtIndices m_iheadless; // headless support points
std::map<unsigned, EigenMesh3D::hit_result> m_head_to_ground_scans; std::map<unsigned, IndexedMesh::hit_result> m_head_to_ground_scans;
// normals for support points from model faces. // normals for support points from model faces.
PointSet m_support_nmls; PointSet m_support_nmls;
@ -217,7 +216,7 @@ class SupportTreeBuildsteps {
// When bridging heads to pillars... TODO: find a cleaner solution // When bridging heads to pillars... TODO: find a cleaner solution
ccr::BlockingMutex m_bridge_mutex; ccr::BlockingMutex m_bridge_mutex;
inline EigenMesh3D::hit_result ray_mesh_intersect(const Vec3d& s, inline IndexedMesh::hit_result ray_mesh_intersect(const Vec3d& s,
const Vec3d& dir) const Vec3d& dir)
{ {
return m_mesh.query_ray_hit(s, dir); return m_mesh.query_ray_hit(s, dir);
@ -234,7 +233,7 @@ class SupportTreeBuildsteps {
// point was inside the model, an "invalid" hit_result will be returned // point was inside the model, an "invalid" hit_result will be returned
// with a zero distance value instead of a NAN. This way the result can // with a zero distance value instead of a NAN. This way the result can
// be used safely for comparison with other distances. // be used safely for comparison with other distances.
EigenMesh3D::hit_result pinhead_mesh_intersect( IndexedMesh::hit_result pinhead_mesh_intersect(
const Vec3d& s, const Vec3d& s,
const Vec3d& dir, const Vec3d& dir,
double r_pin, double r_pin,
@ -249,13 +248,13 @@ class SupportTreeBuildsteps {
// point was inside the model, an "invalid" hit_result will be returned // point was inside the model, an "invalid" hit_result will be returned
// with a zero distance value instead of a NAN. This way the result can // with a zero distance value instead of a NAN. This way the result can
// be used safely for comparison with other distances. // be used safely for comparison with other distances.
EigenMesh3D::hit_result bridge_mesh_intersect( IndexedMesh::hit_result bridge_mesh_intersect(
const Vec3d& s, const Vec3d& s,
const Vec3d& dir, const Vec3d& dir,
double r, double r,
double safety_d); double safety_d);
EigenMesh3D::hit_result bridge_mesh_intersect( IndexedMesh::hit_result bridge_mesh_intersect(
const Vec3d& s, const Vec3d& s,
const Vec3d& dir, const Vec3d& dir,
double r) double r)

View File

@ -35,9 +35,9 @@ bool is_zero_elevation(const SLAPrintObjectConfig &c)
} }
// Compile the argument for support creation from the static print config. // Compile the argument for support creation from the static print config.
sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c) sla::SupportTreeConfig make_support_cfg(const SLAPrintObjectConfig& c)
{ {
sla::SupportConfig scfg; sla::SupportTreeConfig scfg;
scfg.enabled = c.supports_enable.getBool(); scfg.enabled = c.supports_enable.getBool();
scfg.head_front_radius_mm = 0.5*c.support_head_front_diameter.getFloat(); scfg.head_front_radius_mm = 0.5*c.support_head_front_diameter.getFloat();
@ -616,7 +616,7 @@ std::string SLAPrint::validate() const
return L("Cannot proceed without support points! " return L("Cannot proceed without support points! "
"Add support points or disable support generation."); "Add support points or disable support generation.");
sla::SupportConfig cfg = make_support_cfg(po->config()); sla::SupportTreeConfig cfg = make_support_cfg(po->config());
double elv = cfg.object_elevation_mm; double elv = cfg.object_elevation_mm;

View File

@ -544,7 +544,7 @@ private:
bool is_zero_elevation(const SLAPrintObjectConfig &c); bool is_zero_elevation(const SLAPrintObjectConfig &c);
sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c); sla::SupportTreeConfig make_support_cfg(const SLAPrintObjectConfig& c);
sla::PadConfig::EmbedObject builtin_pad_cfg(const SLAPrintObjectConfig& c); sla::PadConfig::EmbedObject builtin_pad_cfg(const SLAPrintObjectConfig& c);

View File

@ -134,7 +134,7 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
Vec3d direction; Vec3d direction;
line_from_mouse_pos(mouse_pos, trafo, camera, point, direction); line_from_mouse_pos(mouse_pos, trafo, camera, point, direction);
std::vector<sla::EigenMesh3D::hit_result> hits = m_emesh.query_ray_hits(point, direction); std::vector<sla::IndexedMesh::hit_result> hits = m_emesh.query_ray_hits(point, direction);
if (hits.empty()) if (hits.empty())
return false; // no intersection found return false; // no intersection found
@ -184,7 +184,7 @@ std::vector<unsigned> MeshRaycaster::get_unobscured_idxs(const Geometry::Transfo
bool is_obscured = false; bool is_obscured = false;
// Cast a ray in the direction of the camera and look for intersection with the mesh: // Cast a ray in the direction of the camera and look for intersection with the mesh:
std::vector<sla::EigenMesh3D::hit_result> hits; std::vector<sla::IndexedMesh::hit_result> hits;
// Offset the start of the ray by EPSILON to account for numerical inaccuracies. // Offset the start of the ray by EPSILON to account for numerical inaccuracies.
hits = m_emesh.query_ray_hits((inverse_trafo * pt + direction_to_camera_mesh * EPSILON).cast<double>(), hits = m_emesh.query_ray_hits((inverse_trafo * pt + direction_to_camera_mesh * EPSILON).cast<double>(),
direction_to_camera.cast<double>()); direction_to_camera.cast<double>());

View File

@ -3,7 +3,7 @@
#include "libslic3r/Point.hpp" #include "libslic3r/Point.hpp"
#include "libslic3r/Geometry.hpp" #include "libslic3r/Geometry.hpp"
#include "libslic3r/SLA/EigenMesh3D.hpp" #include "libslic3r/SLA/IndexedMesh.hpp"
#include "admesh/stl.h" #include "admesh/stl.h"
#include "slic3r/GUI/3DScene.hpp" #include "slic3r/GUI/3DScene.hpp"
@ -147,7 +147,7 @@ public:
Vec3f get_triangle_normal(size_t facet_idx) const; Vec3f get_triangle_normal(size_t facet_idx) const;
private: private:
sla::EigenMesh3D m_emesh; sla::IndexedMesh m_emesh;
std::vector<stl_normal> m_normals; std::vector<stl_normal> m_normals;
}; };

View File

@ -37,9 +37,9 @@ TEST_CASE("Support point generator should be deterministic if seeded",
"[SLASupportGeneration], [SLAPointGen]") { "[SLASupportGeneration], [SLAPointGen]") {
TriangleMesh mesh = load_model("A_upsidedown.obj"); TriangleMesh mesh = load_model("A_upsidedown.obj");
sla::EigenMesh3D emesh{mesh}; sla::IndexedMesh emesh{mesh};
sla::SupportConfig supportcfg; sla::SupportTreeConfig supportcfg;
sla::SupportPointGenerator::Config autogencfg; sla::SupportPointGenerator::Config autogencfg;
autogencfg.head_diameter = float(2 * supportcfg.head_front_radius_mm); autogencfg.head_diameter = float(2 * supportcfg.head_front_radius_mm);
sla::SupportPointGenerator point_gen{emesh, autogencfg, [] {}, [](int) {}}; sla::SupportPointGenerator point_gen{emesh, autogencfg, [] {}, [](int) {}};
@ -124,14 +124,14 @@ TEST_CASE("WingedPadAroundObjectIsValid", "[SLASupportGeneration]") {
} }
TEST_CASE("ElevatedSupportGeometryIsValid", "[SLASupportGeneration]") { TEST_CASE("ElevatedSupportGeometryIsValid", "[SLASupportGeneration]") {
sla::SupportConfig supportcfg; sla::SupportTreeConfig supportcfg;
supportcfg.object_elevation_mm = 5.; supportcfg.object_elevation_mm = 5.;
for (auto fname : SUPPORT_TEST_MODELS) test_supports(fname); for (auto fname : SUPPORT_TEST_MODELS) test_supports(fname);
} }
TEST_CASE("FloorSupportGeometryIsValid", "[SLASupportGeneration]") { TEST_CASE("FloorSupportGeometryIsValid", "[SLASupportGeneration]") {
sla::SupportConfig supportcfg; sla::SupportTreeConfig supportcfg;
supportcfg.object_elevation_mm = 0; supportcfg.object_elevation_mm = 0;
for (auto &fname: SUPPORT_TEST_MODELS) test_supports(fname, supportcfg); for (auto &fname: SUPPORT_TEST_MODELS) test_supports(fname, supportcfg);
@ -139,7 +139,7 @@ TEST_CASE("FloorSupportGeometryIsValid", "[SLASupportGeneration]") {
TEST_CASE("ElevatedSupportsDoNotPierceModel", "[SLASupportGeneration]") { TEST_CASE("ElevatedSupportsDoNotPierceModel", "[SLASupportGeneration]") {
sla::SupportConfig supportcfg; sla::SupportTreeConfig supportcfg;
for (auto fname : SUPPORT_TEST_MODELS) for (auto fname : SUPPORT_TEST_MODELS)
test_support_model_collision(fname, supportcfg); test_support_model_collision(fname, supportcfg);
@ -147,7 +147,7 @@ TEST_CASE("ElevatedSupportsDoNotPierceModel", "[SLASupportGeneration]") {
TEST_CASE("FloorSupportsDoNotPierceModel", "[SLASupportGeneration]") { TEST_CASE("FloorSupportsDoNotPierceModel", "[SLASupportGeneration]") {
sla::SupportConfig supportcfg; sla::SupportTreeConfig supportcfg;
supportcfg.object_elevation_mm = 0; supportcfg.object_elevation_mm = 0;
for (auto fname : SUPPORT_TEST_MODELS) for (auto fname : SUPPORT_TEST_MODELS)

View File

@ -1,7 +1,7 @@
#include <catch2/catch.hpp> #include <catch2/catch.hpp>
#include <test_utils.hpp> #include <test_utils.hpp>
#include <libslic3r/SLA/EigenMesh3D.hpp> #include <libslic3r/SLA/IndexedMesh.hpp>
#include <libslic3r/SLA/Hollowing.hpp> #include <libslic3r/SLA/Hollowing.hpp>
#include "sla_test_utils.hpp" #include "sla_test_utils.hpp"
@ -65,7 +65,7 @@ TEST_CASE("Raycaster with loaded drillholes", "[sla_raycast]")
cube.merge(*cube_inside); cube.merge(*cube_inside);
cube.require_shared_vertices(); cube.require_shared_vertices();
sla::EigenMesh3D emesh{cube}; sla::IndexedMesh emesh{cube};
emesh.load_holes(holes); emesh.load_holes(holes);
Vec3d s = center.cast<double>(); Vec3d s = center.cast<double>();

View File

@ -2,13 +2,13 @@
#include "libslic3r/SLA/AGGRaster.hpp" #include "libslic3r/SLA/AGGRaster.hpp"
void test_support_model_collision(const std::string &obj_filename, void test_support_model_collision(const std::string &obj_filename,
const sla::SupportConfig &input_supportcfg, const sla::SupportTreeConfig &input_supportcfg,
const sla::HollowingConfig &hollowingcfg, const sla::HollowingConfig &hollowingcfg,
const sla::DrainHoles &drainholes) const sla::DrainHoles &drainholes)
{ {
SupportByproducts byproducts; SupportByproducts byproducts;
sla::SupportConfig supportcfg = input_supportcfg; sla::SupportTreeConfig supportcfg = input_supportcfg;
// Set head penetration to a small negative value which should ensure that // Set head penetration to a small negative value which should ensure that
// the supports will not touch the model body. // the supports will not touch the model body.
@ -73,7 +73,7 @@ void export_failed_case(const std::vector<ExPolygons> &support_slices, const Sup
} }
void test_supports(const std::string &obj_filename, void test_supports(const std::string &obj_filename,
const sla::SupportConfig &supportcfg, const sla::SupportTreeConfig &supportcfg,
const sla::HollowingConfig &hollowingcfg, const sla::HollowingConfig &hollowingcfg,
const sla::DrainHoles &drainholes, const sla::DrainHoles &drainholes,
SupportByproducts &out) SupportByproducts &out)
@ -104,7 +104,7 @@ void test_supports(const std::string &obj_filename,
// Create the special index-triangle mesh with spatial indexing which // Create the special index-triangle mesh with spatial indexing which
// is the input of the support point and support mesh generators // is the input of the support point and support mesh generators
sla::EigenMesh3D emesh{mesh}; sla::IndexedMesh emesh{mesh};
#ifdef SLIC3R_HOLE_RAYCASTER #ifdef SLIC3R_HOLE_RAYCASTER
if (hollowingcfg.enabled) if (hollowingcfg.enabled)
@ -168,7 +168,7 @@ void test_supports(const std::string &obj_filename,
} }
void check_support_tree_integrity(const sla::SupportTreeBuilder &stree, void check_support_tree_integrity(const sla::SupportTreeBuilder &stree,
const sla::SupportConfig &cfg) const sla::SupportTreeConfig &cfg)
{ {
double gnd = stree.ground_level; double gnd = stree.ground_level;
double H1 = cfg.max_solo_pillar_height_mm; double H1 = cfg.max_solo_pillar_height_mm;

View File

@ -67,16 +67,16 @@ struct SupportByproducts
const constexpr float CLOSING_RADIUS = 0.005f; const constexpr float CLOSING_RADIUS = 0.005f;
void check_support_tree_integrity(const sla::SupportTreeBuilder &stree, void check_support_tree_integrity(const sla::SupportTreeBuilder &stree,
const sla::SupportConfig &cfg); const sla::SupportTreeConfig &cfg);
void test_supports(const std::string &obj_filename, void test_supports(const std::string &obj_filename,
const sla::SupportConfig &supportcfg, const sla::SupportTreeConfig &supportcfg,
const sla::HollowingConfig &hollowingcfg, const sla::HollowingConfig &hollowingcfg,
const sla::DrainHoles &drainholes, const sla::DrainHoles &drainholes,
SupportByproducts &out); SupportByproducts &out);
inline void test_supports(const std::string &obj_filename, inline void test_supports(const std::string &obj_filename,
const sla::SupportConfig &supportcfg, const sla::SupportTreeConfig &supportcfg,
SupportByproducts &out) SupportByproducts &out)
{ {
sla::HollowingConfig hcfg; sla::HollowingConfig hcfg;
@ -85,7 +85,7 @@ inline void test_supports(const std::string &obj_filename,
} }
inline void test_supports(const std::string &obj_filename, inline void test_supports(const std::string &obj_filename,
const sla::SupportConfig &supportcfg = {}) const sla::SupportTreeConfig &supportcfg = {})
{ {
SupportByproducts byproducts; SupportByproducts byproducts;
test_supports(obj_filename, supportcfg, byproducts); test_supports(obj_filename, supportcfg, byproducts);
@ -97,13 +97,13 @@ void export_failed_case(const std::vector<ExPolygons> &support_slices,
void test_support_model_collision( void test_support_model_collision(
const std::string &obj_filename, const std::string &obj_filename,
const sla::SupportConfig &input_supportcfg, const sla::SupportTreeConfig &input_supportcfg,
const sla::HollowingConfig &hollowingcfg, const sla::HollowingConfig &hollowingcfg,
const sla::DrainHoles &drainholes); const sla::DrainHoles &drainholes);
inline void test_support_model_collision( inline void test_support_model_collision(
const std::string &obj_filename, const std::string &obj_filename,
const sla::SupportConfig &input_supportcfg = {}) const sla::SupportTreeConfig &input_supportcfg = {})
{ {
sla::HollowingConfig hcfg; sla::HollowingConfig hcfg;
hcfg.enabled = false; hcfg.enabled = false;

View File

@ -1,99 +1,99 @@
#include <catch2/catch.hpp> //#include <catch2/catch.hpp>
#include <test_utils.hpp> //#include <test_utils.hpp>
#include "libslic3r/TriangleMesh.hpp" //#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/SLA/SupportTreeBuildsteps.hpp" //#include "libslic3r/SLA/SupportTreeBuildsteps.hpp"
#include "libslic3r/SLA/SupportTreeMesher.hpp" //#include "libslic3r/SLA/SupportTreeMesher.hpp"
TEST_CASE("Test bridge_mesh_intersect on a cube's wall", "[SLABridgeMeshInters]") { //TEST_CASE("Test bridge_mesh_intersect on a cube's wall", "[SLABridgeMeshInters]") {
using namespace Slic3r; // using namespace Slic3r;
TriangleMesh cube = make_cube(10., 10., 10.); // TriangleMesh cube = make_cube(10., 10., 10.);
sla::SupportConfig cfg = {}; // use default config // sla::SupportConfig cfg = {}; // use default config
sla::SupportPoints pts = {{10.f, 5.f, 5.f, float(cfg.head_front_radius_mm), false}}; // sla::SupportPoints pts = {{10.f, 5.f, 5.f, float(cfg.head_front_radius_mm), false}};
sla::SupportableMesh sm{cube, pts, cfg}; // sla::SupportableMesh sm{cube, pts, cfg};
size_t steps = 45; // size_t steps = 45;
SECTION("Bridge is straight horizontal and pointing away from the cube") { // SECTION("Bridge is straight horizontal and pointing away from the cube") {
sla::Bridge bridge(pts[0].pos.cast<double>(), Vec3d{15., 5., 5.}, // sla::Bridge bridge(pts[0].pos.cast<double>(), Vec3d{15., 5., 5.},
pts[0].head_front_radius); // pts[0].head_front_radius);
auto hit = sla::query_hit(sm, bridge); // auto hit = sla::query_hit(sm, bridge);
REQUIRE(std::isinf(hit.distance())); // REQUIRE(std::isinf(hit.distance()));
cube.merge(sla::to_triangle_mesh(get_mesh(bridge, steps))); // cube.merge(sla::to_triangle_mesh(get_mesh(bridge, steps)));
cube.require_shared_vertices(); // cube.require_shared_vertices();
cube.WriteOBJFile("cube1.obj"); // cube.WriteOBJFile("cube1.obj");
} // }
SECTION("Bridge is tilted down in 45 degrees, pointing away from the cube") { // SECTION("Bridge is tilted down in 45 degrees, pointing away from the cube") {
sla::Bridge bridge(pts[0].pos.cast<double>(), Vec3d{15., 5., 0.}, // sla::Bridge bridge(pts[0].pos.cast<double>(), Vec3d{15., 5., 0.},
pts[0].head_front_radius); // pts[0].head_front_radius);
auto hit = sla::query_hit(sm, bridge); // auto hit = sla::query_hit(sm, bridge);
REQUIRE(std::isinf(hit.distance())); // REQUIRE(std::isinf(hit.distance()));
cube.merge(sla::to_triangle_mesh(get_mesh(bridge, steps))); // cube.merge(sla::to_triangle_mesh(get_mesh(bridge, steps)));
cube.require_shared_vertices(); // cube.require_shared_vertices();
cube.WriteOBJFile("cube2.obj"); // cube.WriteOBJFile("cube2.obj");
} // }
} //}
TEST_CASE("Test bridge_mesh_intersect on a sphere", "[SLABridgeMeshInters]") { //TEST_CASE("Test bridge_mesh_intersect on a sphere", "[SLABridgeMeshInters]") {
using namespace Slic3r; // using namespace Slic3r;
TriangleMesh sphere = make_sphere(1.); // TriangleMesh sphere = make_sphere(1.);
sla::SupportConfig cfg = {}; // use default config // sla::SupportConfig cfg = {}; // use default config
cfg.head_back_radius_mm = cfg.head_front_radius_mm; // cfg.head_back_radius_mm = cfg.head_front_radius_mm;
sla::SupportPoints pts = {{1.f, 0.f, 0.f, float(cfg.head_front_radius_mm), false}}; // sla::SupportPoints pts = {{1.f, 0.f, 0.f, float(cfg.head_front_radius_mm), false}};
sla::SupportableMesh sm{sphere, pts, cfg}; // sla::SupportableMesh sm{sphere, pts, cfg};
size_t steps = 45; // size_t steps = 45;
SECTION("Bridge is straight horizontal and pointing away from the sphere") { // SECTION("Bridge is straight horizontal and pointing away from the sphere") {
sla::Bridge bridge(pts[0].pos.cast<double>(), Vec3d{2., 0., 0.}, // sla::Bridge bridge(pts[0].pos.cast<double>(), Vec3d{2., 0., 0.},
pts[0].head_front_radius); // pts[0].head_front_radius);
auto hit = sla::query_hit(sm, bridge); // auto hit = sla::query_hit(sm, bridge);
sphere.merge(sla::to_triangle_mesh(get_mesh(bridge, steps))); // sphere.merge(sla::to_triangle_mesh(get_mesh(bridge, steps)));
sphere.require_shared_vertices(); // sphere.require_shared_vertices();
sphere.WriteOBJFile("sphere1.obj"); // sphere.WriteOBJFile("sphere1.obj");
REQUIRE(std::isinf(hit.distance())); // REQUIRE(std::isinf(hit.distance()));
} // }
SECTION("Bridge is tilted down 45 deg and pointing away from the sphere") { // SECTION("Bridge is tilted down 45 deg and pointing away from the sphere") {
sla::Bridge bridge(pts[0].pos.cast<double>(), Vec3d{2., 0., -2.}, // sla::Bridge bridge(pts[0].pos.cast<double>(), Vec3d{2., 0., -2.},
pts[0].head_front_radius); // pts[0].head_front_radius);
auto hit = sla::query_hit(sm, bridge); // auto hit = sla::query_hit(sm, bridge);
sphere.merge(sla::to_triangle_mesh(get_mesh(bridge, steps))); // sphere.merge(sla::to_triangle_mesh(get_mesh(bridge, steps)));
sphere.require_shared_vertices(); // sphere.require_shared_vertices();
sphere.WriteOBJFile("sphere2.obj"); // sphere.WriteOBJFile("sphere2.obj");
REQUIRE(std::isinf(hit.distance())); // REQUIRE(std::isinf(hit.distance()));
} // }
SECTION("Bridge is tilted down 90 deg and pointing away from the sphere") { // SECTION("Bridge is tilted down 90 deg and pointing away from the sphere") {
sla::Bridge bridge(pts[0].pos.cast<double>(), Vec3d{1., 0., -2.}, // sla::Bridge bridge(pts[0].pos.cast<double>(), Vec3d{1., 0., -2.},
pts[0].head_front_radius); // pts[0].head_front_radius);
auto hit = sla::query_hit(sm, bridge); // auto hit = sla::query_hit(sm, bridge);
sphere.merge(sla::to_triangle_mesh(get_mesh(bridge, steps))); // sphere.merge(sla::to_triangle_mesh(get_mesh(bridge, steps)));
sphere.require_shared_vertices(); // sphere.require_shared_vertices();
sphere.WriteOBJFile("sphere3.obj"); // sphere.WriteOBJFile("sphere3.obj");
REQUIRE(std::isinf(hit.distance())); // REQUIRE(std::isinf(hit.distance()));
} // }
} //}