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/Contour3D.hpp
SLA/Contour3D.cpp
SLA/EigenMesh3D.hpp
SLA/EigenMesh3D.cpp
SLA/IndexedMesh.hpp
SLA/IndexedMesh.cpp
SLA/Clustering.hpp
SLA/Clustering.cpp
SLA/ReprojectPointsOnMesh.hpp

View File

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

View File

@ -10,7 +10,7 @@ using Vec4i = Eigen::Matrix<int, 4, 1, Eigen::DontAlign>;
namespace sla {
class EigenMesh3D;
class IndexedMesh;
/// 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.
@ -22,7 +22,7 @@ struct Contour3D {
Contour3D() = default;
Contour3D(const TriangleMesh &trmesh);
Contour3D(TriangleMesh &&trmesh);
Contour3D(const EigenMesh3D &emesh);
Contour3D(const IndexedMesh &emesh);
Contour3D& merge(const Contour3D& ctr);
Contour3D& merge(const Pointf3s& triangles);

View File

@ -3,7 +3,7 @@
#include <libslic3r/OpenVDBUtils.hpp>
#include <libslic3r/TriangleMesh.hpp>
#include <libslic3r/SLA/Hollowing.hpp>
#include <libslic3r/SLA/EigenMesh3D.hpp>
#include <libslic3r/SLA/IndexedMesh.hpp>
#include <libslic3r/ClipperUtils.hpp>
#include <libslic3r/SimplifyMesh.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());
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);

View File

@ -1,4 +1,4 @@
#include "EigenMesh3D.hpp"
#include "IndexedMesh.hpp"
#include "Concurrency.hpp"
#include <libslic3r/AABBTreeIndirect.hpp>
@ -12,7 +12,7 @@
namespace Slic3r { namespace sla {
class EigenMesh3D::AABBImpl {
class IndexedMesh::AABBImpl {
private:
AABBTreeIndirect::Tree3f m_tree;
@ -57,7 +57,7 @@ public:
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)
{
auto&& bb = tmesh.bounding_box();
@ -67,61 +67,61 @@ EigenMesh3D::EigenMesh3D(const TriangleMesh& 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_aabb( new AABBImpl(*other.m_aabb) ) {}
EigenMesh3D &EigenMesh3D::operator=(const EigenMesh3D &other)
IndexedMesh &IndexedMesh::operator=(const IndexedMesh &other)
{
m_tm = other.m_tm;
m_ground_level = other.m_ground_level;
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;
}
const std::vector<Vec3i>& EigenMesh3D::indices() const
const std::vector<Vec3i>& IndexedMesh::indices() const
{
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];
}
const Vec3i& EigenMesh3D::indices(size_t idx) const
const Vec3i& IndexedMesh::indices(size_t idx) const
{
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>();
}
EigenMesh3D::hit_result
EigenMesh3D::query_ray_hit(const Vec3d &s, const Vec3d &dir) const
IndexedMesh::hit_result
IndexedMesh::query_ray_hit(const Vec3d &s, const Vec3d &dir) const
{
assert(is_approx(dir.norm(), 1.));
igl::Hit hit;
@ -149,10 +149,10 @@ EigenMesh3D::query_ray_hit(const Vec3d &s, const Vec3d &dir) const
return ret;
}
std::vector<EigenMesh3D::hit_result>
EigenMesh3D::query_ray_hits(const Vec3d &s, const Vec3d &dir) const
std::vector<IndexedMesh::hit_result>
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;
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
outs.reserve(hits.size());
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_dir = dir;
outs.back().m_source = s;
@ -185,8 +185,8 @@ EigenMesh3D::query_ray_hits(const Vec3d &s, const Vec3d &dir) const
#ifdef SLIC3R_HOLE_RAYCASTER
EigenMesh3D::hit_result EigenMesh3D::filter_hits(
const std::vector<EigenMesh3D::hit_result>& object_hits) const
IndexedMesh::hit_result IndexedMesh::filter_hits(
const std::vector<IndexedMesh::hit_result>& object_hits) const
{
assert(! m_holes.empty());
hit_result out(*this);
@ -282,7 +282,7 @@ EigenMesh3D::hit_result EigenMesh3D::filter_hits(
#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;
Eigen::Matrix<double, 1, 3> pp = p;
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,
const EigenMesh3D& mesh,
const IndexedMesh& mesh,
double eps,
std::function<void()> thr, // throw on cancel
const std::vector<unsigned>& pt_indices)

View File

@ -1,5 +1,5 @@
#ifndef SLA_EIGENMESH3D_H
#define SLA_EIGENMESH3D_H
#ifndef SLA_INDEXEDMESH_H
#define SLA_INDEXEDMESH_H
#include <memory>
#include <vector>
@ -26,7 +26,7 @@ using PointSet = Eigen::MatrixXd;
/// An index-triangle structure for libIGL functions. Also serves as an
/// alternative (raw) input format for the SLASupportTree.
// Implemented in libslic3r/SLA/Common.cpp
class EigenMesh3D {
class IndexedMesh {
class AABBImpl;
const TriangleMesh* m_tm;
@ -42,15 +42,15 @@ class EigenMesh3D {
public:
explicit EigenMesh3D(const TriangleMesh&);
explicit IndexedMesh(const TriangleMesh&);
EigenMesh3D(const EigenMesh3D& other);
EigenMesh3D& operator=(const EigenMesh3D&);
IndexedMesh(const IndexedMesh& other);
IndexedMesh& operator=(const IndexedMesh&);
EigenMesh3D(EigenMesh3D &&other);
EigenMesh3D& operator=(EigenMesh3D &&other);
IndexedMesh(IndexedMesh &&other);
IndexedMesh& operator=(IndexedMesh &&other);
~EigenMesh3D();
~IndexedMesh();
inline double ground_level() const { return m_ground_level + m_gnd_offset; }
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.
double m_t = infty();
int m_face_id = -1;
const EigenMesh3D *m_mesh = nullptr;
const IndexedMesh *m_mesh = nullptr;
Vec3d m_dir;
Vec3d m_source;
Vec3d m_normal;
friend class EigenMesh3D;
friend class IndexedMesh;
// A valid object of this class can only be obtained from
// EigenMesh3D::query_ray_hit method.
explicit inline hit_result(const EigenMesh3D& em): m_mesh(&em) {}
// IndexedMesh::query_ray_hit method.
explicit inline hit_result(const IndexedMesh& em): m_mesh(&em) {}
public:
// This denotes no hit on the mesh.
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
// holes were subtracted on slices, that is, before we started using CGAL
// 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
// 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
// mesh. This will call squared distance for each point.
PointSet normals(const PointSet& points,
const EigenMesh3D& convert_mesh,
const IndexedMesh& convert_mesh,
double eps = 0.05, // min distance from edges
std::function<void()> throw_on_cancel = [](){},
const std::vector<unsigned>& selected_points = {});
}} // namespace Slic3r::sla
#endif // EIGENMESH3D_H
#endif // INDEXEDMESH_H

View File

@ -4,7 +4,7 @@
#include "libslic3r/Point.hpp"
#include "SupportPoint.hpp"
#include "Hollowing.hpp"
#include "EigenMesh3D.hpp"
#include "IndexedMesh.hpp"
#include "libslic3r/Model.hpp"
#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 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) {
int junk;
@ -40,7 +40,7 @@ inline void reproject_points_and_holes(ModelObject *object)
TriangleMesh rmsh = object->raw_mesh();
rmsh.require_shared_vertices();
EigenMesh3D emesh{rmsh};
IndexedMesh emesh{rmsh};
if (has_sppoints)
reproject_support_points(emesh, object->sla_support_points);

View File

@ -50,7 +50,7 @@ float SupportPointGenerator::distance_limit(float angle) const
}*/
SupportPointGenerator::SupportPointGenerator(
const sla::EigenMesh3D &emesh,
const sla::IndexedMesh &emesh,
const std::vector<ExPolygons> &slices,
const std::vector<float> & heights,
const Config & config,
@ -64,7 +64,7 @@ SupportPointGenerator::SupportPointGenerator(
}
SupportPointGenerator::SupportPointGenerator(
const EigenMesh3D &emesh,
const IndexedMesh &emesh,
const SupportPointGenerator::Config &config,
std::function<void ()> throw_on_cancel,
std::function<void (int)> statusfn)
@ -95,8 +95,8 @@ void SupportPointGenerator::project_onto_mesh(std::vector<sla::SupportPoint>& po
m_throw_on_cancel();
Vec3f& p = points[point_id].pos;
// 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::EigenMesh3D::hit_result hit_down = 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::IndexedMesh::hit_result hit_down = m_emesh.query_ray_hit(p.cast<double>(), Vec3d(0., 0., -1.));
bool up = hit_up.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)
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>();
}
});

View File

@ -4,7 +4,7 @@
#include <random>
#include <libslic3r/SLA/SupportPoint.hpp>
#include <libslic3r/SLA/EigenMesh3D.hpp>
#include <libslic3r/SLA/IndexedMesh.hpp>
#include <libslic3r/BoundingBox.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)
};
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);
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; }
std::vector<SupportPoint>& output() { return m_output; }
@ -206,7 +206,7 @@ private:
static void output_structures(const std::vector<Structure> &structures);
#endif // SLA_SUPPORTPOINTGEN_DEBUG
const EigenMesh3D& m_emesh;
const IndexedMesh& m_emesh;
std::function<void(void)> m_throw_on_cancel;
std::function<void(int)> m_statusfn;

View File

@ -6,7 +6,7 @@
#include <Eigen/Geometry>
#include <libslic3r/SLA/Pad.hpp>
#include <libslic3r/SLA/EigenMesh3D.hpp>
#include <libslic3r/SLA/IndexedMesh.hpp>
#include <libslic3r/SLA/SupportPoint.hpp>
#include <libslic3r/SLA/JobController.hpp>
@ -31,7 +31,7 @@ enum class PillarConnectionMode
dynamic
};
struct SupportConfig
struct SupportTreeConfig
{
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 };
struct SupportableMesh
{
EigenMesh3D emesh;
IndexedMesh emesh;
SupportPoints pts;
SupportConfig cfg;
SupportTreeConfig cfg;
PadConfig pad_cfg;
explicit SupportableMesh(const TriangleMesh & trmsh,
const SupportPoints &sp,
const SupportConfig &c)
const SupportTreeConfig &c)
: emesh{trmsh}, pts{sp}, cfg{c}
{}
explicit SupportableMesh(const EigenMesh3D &em,
explicit SupportableMesh(const IndexedMesh &em,
const SupportPoints &sp,
const SupportConfig &c)
const SupportTreeConfig &c)
: emesh{em}, pts{sp}, cfg{c}
{}
};

View File

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

View File

@ -544,7 +544,7 @@ private:
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);

View File

@ -134,7 +134,7 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
Vec3d 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())
return false; // no intersection found
@ -184,7 +184,7 @@ std::vector<unsigned> MeshRaycaster::get_unobscured_idxs(const Geometry::Transfo
bool is_obscured = false;
// 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.
hits = m_emesh.query_ray_hits((inverse_trafo * pt + direction_to_camera_mesh * EPSILON).cast<double>(),
direction_to_camera.cast<double>());

View File

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

View File

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

View File

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

View File

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

View File

@ -67,16 +67,16 @@ struct SupportByproducts
const constexpr float CLOSING_RADIUS = 0.005f;
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,
const sla::SupportConfig &supportcfg,
const sla::SupportTreeConfig &supportcfg,
const sla::HollowingConfig &hollowingcfg,
const sla::DrainHoles &drainholes,
SupportByproducts &out);
inline void test_supports(const std::string &obj_filename,
const sla::SupportConfig &supportcfg,
const sla::SupportTreeConfig &supportcfg,
SupportByproducts &out)
{
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,
const sla::SupportConfig &supportcfg = {})
const sla::SupportTreeConfig &supportcfg = {})
{
SupportByproducts 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(
const std::string &obj_filename,
const sla::SupportConfig &input_supportcfg,
const sla::SupportTreeConfig &input_supportcfg,
const sla::HollowingConfig &hollowingcfg,
const sla::DrainHoles &drainholes);
inline void test_support_model_collision(
const std::string &obj_filename,
const sla::SupportConfig &input_supportcfg = {})
const sla::SupportTreeConfig &input_supportcfg = {})
{
sla::HollowingConfig hcfg;
hcfg.enabled = false;

View File

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