1 #ifndef SLA_INDEXEDMESH_H 2 #define SLA_INDEXEDMESH_H 3 4 #include <memory> 5 #include <vector> 6 7 #include <libslic3r/Point.hpp> 8 9 // There is an implementation of a hole-aware raycaster that was eventually 10 // not used in production version. It is now hidden under following define 11 // for possible future use. 12 // #define SLIC3R_HOLE_RAYCASTER 13 14 #ifdef SLIC3R_HOLE_RAYCASTER 15 #include "libslic3r/SLA/Hollowing.hpp" 16 #endif 17 18 namespace Slic3r { 19 20 class TriangleMesh; 21 22 namespace sla { 23 24 using PointSet = Eigen::MatrixXd; 25 26 /// An index-triangle structure for libIGL functions. Also serves as an 27 /// alternative (raw) input format for the SLASupportTree. 28 // Implemented in libslic3r/SLA/Common.cpp 29 class IndexedMesh { 30 class AABBImpl; 31 32 const TriangleMesh* m_tm; 33 double m_ground_level = 0, m_gnd_offset = 0; 34 35 std::unique_ptr<AABBImpl> m_aabb; 36 37 #ifdef SLIC3R_HOLE_RAYCASTER 38 // This holds a copy of holes in the mesh. Initialized externally 39 // by load_mesh setter. 40 std::vector<DrainHole> m_holes; 41 #endif 42 43 public: 44 45 explicit IndexedMesh(const TriangleMesh&); 46 47 IndexedMesh(const IndexedMesh& other); 48 IndexedMesh& operator=(const IndexedMesh&); 49 50 IndexedMesh(IndexedMesh &&other); 51 IndexedMesh& operator=(IndexedMesh &&other); 52 53 ~IndexedMesh(); 54 ground_level() const55 inline double ground_level() const { return m_ground_level + m_gnd_offset; } ground_level_offset(double o)56 inline void ground_level_offset(double o) { m_gnd_offset = o; } ground_level_offset() const57 inline double ground_level_offset() const { return m_gnd_offset; } 58 59 const std::vector<Vec3f>& vertices() const; 60 const std::vector<Vec3i>& indices() const; 61 const Vec3f& vertices(size_t idx) const; 62 const Vec3i& indices(size_t idx) const; 63 64 // Result of a raycast 65 class hit_result { 66 // m_t holds a distance from m_source to the intersection. 67 double m_t = infty(); 68 int m_face_id = -1; 69 const IndexedMesh *m_mesh = nullptr; 70 Vec3d m_dir; 71 Vec3d m_source; 72 Vec3d m_normal; 73 friend class IndexedMesh; 74 75 // A valid object of this class can only be obtained from 76 // IndexedMesh::query_ray_hit method. hit_result(const IndexedMesh & em)77 explicit inline hit_result(const IndexedMesh& em): m_mesh(&em) {} 78 public: 79 // This denotes no hit on the mesh. infty()80 static inline constexpr double infty() { return std::numeric_limits<double>::infinity(); } 81 hit_result(double val=infty ())82 explicit inline hit_result(double val = infty()) : m_t(val) {} 83 distance() const84 inline double distance() const { return m_t; } direction() const85 inline const Vec3d& direction() const { return m_dir; } source() const86 inline const Vec3d& source() const { return m_source; } position() const87 inline Vec3d position() const { return m_source + m_dir * m_t; } face() const88 inline int face() const { return m_face_id; } is_valid() const89 inline bool is_valid() const { return m_mesh != nullptr; } is_hit() const90 inline bool is_hit() const { return m_face_id >= 0 && !std::isinf(m_t); } 91 normal() const92 inline const Vec3d& normal() const { 93 assert(is_valid()); 94 return m_normal; 95 } 96 is_inside() const97 inline bool is_inside() const { 98 return is_hit() && normal().dot(m_dir) > 0; 99 } 100 }; 101 102 #ifdef SLIC3R_HOLE_RAYCASTER 103 // Inform the object about location of holes 104 // creates internal copy of the vector load_holes(const std::vector<DrainHole> & holes)105 void load_holes(const std::vector<DrainHole>& holes) { 106 m_holes = holes; 107 } 108 109 // Iterates over hits and holes and returns the true hit, possibly 110 // on the inside of a hole. 111 // This function is currently not used anywhere, it was written when the 112 // holes were subtracted on slices, that is, before we started using CGAL 113 // to actually cut the holes into the mesh. 114 hit_result filter_hits(const std::vector<IndexedMesh::hit_result>& obj_hits) const; 115 #endif 116 117 // Casting a ray on the mesh, returns the distance where the hit occures. 118 hit_result query_ray_hit(const Vec3d &s, const Vec3d &dir) const; 119 120 // Casts a ray on the mesh and returns all hits 121 std::vector<hit_result> query_ray_hits(const Vec3d &s, const Vec3d &dir) const; 122 123 double squared_distance(const Vec3d& p, int& i, Vec3d& c) const; squared_distance(const Vec3d & p) const124 inline double squared_distance(const Vec3d &p) const 125 { 126 int i; 127 Vec3d c; 128 return squared_distance(p, i, c); 129 } 130 131 Vec3d normal_by_face_id(int face_id) const; 132 get_triangle_mesh() const133 const TriangleMesh * get_triangle_mesh() const { return m_tm; } 134 }; 135 136 // Calculate the normals for the selected points (from 'points' set) on the 137 // mesh. This will call squared distance for each point. 138 PointSet normals(const PointSet& points, 139 const IndexedMesh& convert_mesh, 140 double eps = 0.05, // min distance from edges __anon4716b31f0102()141 std::function<void()> throw_on_cancel = [](){}, __anon4716b31f0202()142 const std::vector<unsigned>& selected_points = {}); 143 144 }} // namespace Slic3r::sla 145 146 #endif // INDEXEDMESH_H 147