mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-13 01:37:53 -06:00
WIP: First working implementation of the triangle selector for the FDM support gizmo
This commit is contained in:
parent
7afe7326b6
commit
08daddb5de
7 changed files with 108 additions and 28 deletions
|
@ -303,8 +303,10 @@ EigenMesh3D::query_ray_hit(const Vec3d &s, const Vec3d &dir) const
|
||||||
ret.m_t = double(hit.t);
|
ret.m_t = double(hit.t);
|
||||||
ret.m_dir = dir;
|
ret.m_dir = dir;
|
||||||
ret.m_source = s;
|
ret.m_source = s;
|
||||||
if(!std::isinf(hit.t) && !std::isnan(hit.t))
|
if(!std::isinf(hit.t) && !std::isnan(hit.t)) {
|
||||||
ret.m_normal = this->normal_by_face_id(hit.id);
|
ret.m_normal = this->normal_by_face_id(hit.id);
|
||||||
|
ret.m_face_id = hit.id;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -340,8 +342,10 @@ EigenMesh3D::query_ray_hits(const Vec3d &s, const Vec3d &dir) const
|
||||||
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;
|
||||||
if(!std::isinf(hit.t) && !std::isnan(hit.t))
|
if(!std::isinf(hit.t) && !std::isnan(hit.t)) {
|
||||||
outs.back().m_normal = this->normal_by_face_id(hit.id);
|
outs.back().m_normal = this->normal_by_face_id(hit.id);
|
||||||
|
outs.back().m_face_id = hit.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return outs;
|
return outs;
|
||||||
|
|
|
@ -55,6 +55,7 @@ public:
|
||||||
class hit_result {
|
class hit_result {
|
||||||
// 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;
|
||||||
const EigenMesh3D *m_mesh = nullptr;
|
const EigenMesh3D *m_mesh = nullptr;
|
||||||
Vec3d m_dir;
|
Vec3d m_dir;
|
||||||
Vec3d m_source;
|
Vec3d m_source;
|
||||||
|
@ -74,6 +75,7 @@ public:
|
||||||
inline const Vec3d& direction() const { return m_dir; }
|
inline const Vec3d& direction() const { return m_dir; }
|
||||||
inline const Vec3d& source() const { return m_source; }
|
inline const Vec3d& source() const { return m_source; }
|
||||||
inline Vec3d position() const { return m_source + m_dir * m_t; }
|
inline Vec3d position() const { return m_source + m_dir * m_t; }
|
||||||
|
inline int face() const { return m_face_id; }
|
||||||
inline bool is_valid() const { return m_mesh != nullptr; }
|
inline bool is_valid() const { return m_mesh != nullptr; }
|
||||||
inline bool is_hit() const { return !std::isinf(m_t); }
|
inline bool is_hit() const { return !std::isinf(m_t); }
|
||||||
|
|
||||||
|
|
|
@ -105,13 +105,40 @@ void GLGizmoFdmSupports::on_render() const
|
||||||
glsafe(::glEnable(GL_BLEND));
|
glsafe(::glEnable(GL_BLEND));
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
|
render_triangles(selection);
|
||||||
render_clipping_plane(selection);
|
render_clipping_plane(selection);
|
||||||
|
|
||||||
glsafe(::glDisable(GL_BLEND));
|
glsafe(::glDisable(GL_BLEND));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoFdmSupports::render_triangles(const Selection& selection) const
|
||||||
|
{
|
||||||
|
if (! m_mesh)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get transformation of the instance
|
||||||
|
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||||
|
Transform3d trafo = vol->get_instance_transformation().get_matrix();
|
||||||
|
|
||||||
|
::glColor3f(0.0f, 0.37f, 1.0f);
|
||||||
|
|
||||||
|
for (size_t facet_idx : m_selected_facets) {
|
||||||
|
stl_normal normal = 0.01f * MeshRaycaster::get_triangle_normal(m_mesh->its, facet_idx);
|
||||||
|
::glPushMatrix();
|
||||||
|
::glTranslatef(normal(0), normal(1), normal(2));
|
||||||
|
::glMultMatrixd(trafo.data());
|
||||||
|
|
||||||
|
::glBegin(GL_TRIANGLES);
|
||||||
|
::glVertex3f(m_mesh->its.vertices[m_mesh->its.indices[facet_idx](0)](0), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](0)](1), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](0)](2));
|
||||||
|
::glVertex3f(m_mesh->its.vertices[m_mesh->its.indices[facet_idx](1)](0), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](1)](1), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](1)](2));
|
||||||
|
::glVertex3f(m_mesh->its.vertices[m_mesh->its.indices[facet_idx](2)](0), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](2)](1), m_mesh->its.vertices[m_mesh->its.indices[facet_idx](2)](2));
|
||||||
|
::glEnd();
|
||||||
|
::glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoFdmSupports::render_clipping_plane(const Selection& selection) const
|
void GLGizmoFdmSupports::render_clipping_plane(const Selection& selection) const
|
||||||
{
|
{
|
||||||
|
@ -193,7 +220,7 @@ void GLGizmoFdmSupports::update_mesh()
|
||||||
|
|
||||||
// Unprojects the mouse position on the mesh and saves hit point and normal of the facet into pos_and_normal
|
// Unprojects the mouse position on the mesh and saves hit point and normal of the facet into pos_and_normal
|
||||||
// Return false if no intersection was found, true otherwise.
|
// Return false if no intersection was found, true otherwise.
|
||||||
bool GLGizmoFdmSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal)
|
bool GLGizmoFdmSupports::unproject_on_mesh(const Vec2d& mouse_pos, size_t& facet_idx)
|
||||||
{
|
{
|
||||||
// if the gizmo doesn't have the V, F structures for igl, calculate them first:
|
// if the gizmo doesn't have the V, F structures for igl, calculate them first:
|
||||||
if (! m_mesh_raycaster)
|
if (! m_mesh_raycaster)
|
||||||
|
@ -208,11 +235,8 @@ bool GLGizmoFdmSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec
|
||||||
// The raycaster query
|
// The raycaster query
|
||||||
Vec3f hit;
|
Vec3f hit;
|
||||||
Vec3f normal;
|
Vec3f normal;
|
||||||
if (m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_clipping_plane.get())) {
|
if (m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_clipping_plane.get(), &facet_idx))
|
||||||
// Return both the point and the facet normal.
|
|
||||||
pos_and_normal = std::make_pair(hit, normal);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -240,6 +264,22 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action == SLAGizmoEventType::LeftDown || (action == SLAGizmoEventType::Dragging && m_wait_for_up_event)) {
|
||||||
|
size_t facet_idx = 0;
|
||||||
|
if (unproject_on_mesh(mouse_position, facet_idx)) {
|
||||||
|
m_selected_facets.push_back(facet_idx);
|
||||||
|
m_wait_for_up_event = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (action == SLAGizmoEventType::Dragging && m_wait_for_up_event)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == SLAGizmoEventType::LeftUp && m_wait_for_up_event) {
|
||||||
|
m_wait_for_up_event = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,11 +372,9 @@ std::string GLGizmoFdmSupports::on_get_name() const
|
||||||
|
|
||||||
void GLGizmoFdmSupports::on_set_state()
|
void GLGizmoFdmSupports::on_set_state()
|
||||||
{
|
{
|
||||||
if (m_state == On)
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
std::cout << "zapinam se..." << std::endl;
|
|
||||||
else
|
|
||||||
std::cout << "vypinam se..." << std::endl;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// m_model_object pointer can be invalid (for instance because of undo/redo action),
|
// m_model_object pointer can be invalid (for instance because of undo/redo action),
|
||||||
// we should recover it from the object id
|
// we should recover it from the object id
|
||||||
m_model_object = nullptr;
|
m_model_object = nullptr;
|
||||||
|
@ -351,7 +389,7 @@ void GLGizmoFdmSupports::on_set_state()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_state == On && m_old_state != On) { // the gizmo was just turned on
|
if (m_state == On && m_old_state != On) { // the gizmo was just turned on
|
||||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned on")));
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("FDM gizmo turned on")));
|
||||||
if (is_mesh_update_necessary())
|
if (is_mesh_update_necessary())
|
||||||
update_mesh();
|
update_mesh();
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
|
|
||||||
#include "GLGizmoBase.hpp"
|
#include "GLGizmoBase.hpp"
|
||||||
|
|
||||||
//#include "libslic3r/SLA/SLACommon.hpp"
|
|
||||||
//#include <wx/dialog.h>
|
|
||||||
|
|
||||||
#include <cereal/types/vector.hpp>
|
#include <cereal/types/vector.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +21,7 @@ private:
|
||||||
ObjectID m_model_object_id = 0;
|
ObjectID m_model_object_id = 0;
|
||||||
int m_active_instance = -1;
|
int m_active_instance = -1;
|
||||||
float m_active_instance_bb_radius; // to cache the bb
|
float m_active_instance_bb_radius; // to cache the bb
|
||||||
bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
|
bool unproject_on_mesh(const Vec2d& mouse_pos, size_t& facet_idx);
|
||||||
|
|
||||||
|
|
||||||
GLUquadricObj* m_quadric;
|
GLUquadricObj* m_quadric;
|
||||||
|
@ -34,6 +31,8 @@ private:
|
||||||
const indexed_triangle_set* m_its;
|
const indexed_triangle_set* m_its;
|
||||||
mutable std::vector<Vec2f> m_triangles;
|
mutable std::vector<Vec2f> m_triangles;
|
||||||
|
|
||||||
|
std::vector<size_t> m_selected_facets;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLGizmoFdmSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
GLGizmoFdmSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||||
|
@ -48,6 +47,7 @@ private:
|
||||||
void on_render() const override;
|
void on_render() const override;
|
||||||
void on_render_for_picking() const override;
|
void on_render_for_picking() const override;
|
||||||
|
|
||||||
|
void render_triangles(const Selection& selection) const;
|
||||||
void render_clipping_plane(const Selection& selection) const;
|
void render_clipping_plane(const Selection& selection) const;
|
||||||
bool is_mesh_update_necessary() const;
|
bool is_mesh_update_necessary() const;
|
||||||
void update_mesh();
|
void update_mesh();
|
||||||
|
|
|
@ -388,9 +388,12 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p
|
||||||
|
|
||||||
if (m_current == SlaSupports)
|
if (m_current == SlaSupports)
|
||||||
return dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
return dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||||
if (m_current == Hollow)
|
else if (m_current == Hollow)
|
||||||
return dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
return dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||||
return false;
|
else if (m_current == FdmSupports)
|
||||||
|
return dynamic_cast<GLGizmoFdmSupports*>(m_gizmos[FdmSupports].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClippingPlane GLGizmosManager::get_clipping_plane() const
|
ClippingPlane GLGizmosManager::get_clipping_plane() const
|
||||||
|
@ -444,7 +447,7 @@ bool GLGizmosManager::on_mouse_wheel(wxMouseEvent& evt)
|
||||||
{
|
{
|
||||||
bool processed = false;
|
bool processed = false;
|
||||||
|
|
||||||
if (m_current == SlaSupports || m_current == Hollow) {
|
if (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports) {
|
||||||
float rot = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta();
|
float rot = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta();
|
||||||
if (gizmo_event((rot > 0.f ? SLAGizmoEventType::MouseWheelUp : SLAGizmoEventType::MouseWheelDown), Vec2d::Zero(), evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
|
if (gizmo_event((rot > 0.f ? SLAGizmoEventType::MouseWheelUp : SLAGizmoEventType::MouseWheelDown), Vec2d::Zero(), evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
|
||||||
processed = true;
|
processed = true;
|
||||||
|
@ -502,7 +505,8 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
||||||
|
|
||||||
if (evt.LeftDown())
|
if (evt.LeftDown())
|
||||||
{
|
{
|
||||||
if ((m_current == SlaSupports || m_current == Hollow) && gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
|
if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports)
|
||||||
|
&& gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
|
||||||
// the gizmo got the event and took some action, there is no need to do anything more
|
// the gizmo got the event and took some action, there is no need to do anything more
|
||||||
processed = true;
|
processed = true;
|
||||||
else if (!selection.is_empty() && grabber_contains_mouse()) {
|
else if (!selection.is_empty() && grabber_contains_mouse()) {
|
||||||
|
@ -530,7 +534,8 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
||||||
else if (evt.Dragging() && (m_parent.get_move_volume_id() != -1) && (m_current == SlaSupports || m_current == Hollow))
|
else if (evt.Dragging() && (m_parent.get_move_volume_id() != -1) && (m_current == SlaSupports || m_current == Hollow))
|
||||||
// don't allow dragging objects with the Sla gizmo on
|
// don't allow dragging objects with the Sla gizmo on
|
||||||
processed = true;
|
processed = true;
|
||||||
else if (evt.Dragging() && (m_current == SlaSupports || m_current == Hollow) && gizmo_event(SLAGizmoEventType::Dragging, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
|
else if (evt.Dragging() && (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports )
|
||||||
|
&& gizmo_event(SLAGizmoEventType::Dragging, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
|
||||||
{
|
{
|
||||||
// the gizmo got the event and took some action, no need to do anything more here
|
// the gizmo got the event and took some action, no need to do anything more here
|
||||||
m_parent.set_as_dirty();
|
m_parent.set_as_dirty();
|
||||||
|
@ -603,9 +608,9 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
||||||
|
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
else if (evt.LeftUp() && (m_current == SlaSupports || m_current == Hollow) && !m_parent.is_mouse_dragging())
|
else if (evt.LeftUp() && (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports) && !m_parent.is_mouse_dragging())
|
||||||
{
|
{
|
||||||
// in case SLA gizmo is selected, we just pass the LeftUp event and stop processing - neither
|
// in case SLA/FDM gizmo is selected, we just pass the LeftUp event and stop processing - neither
|
||||||
// object moving or selecting is suppressed in that case
|
// object moving or selecting is suppressed in that case
|
||||||
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown());
|
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown());
|
||||||
processed = true;
|
processed = true;
|
||||||
|
@ -702,7 +707,7 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt)
|
||||||
case 'r' :
|
case 'r' :
|
||||||
case 'R' :
|
case 'R' :
|
||||||
{
|
{
|
||||||
if ((m_current == SlaSupports || m_current == Hollow) && gizmo_event(SLAGizmoEventType::ResetClippingPlane))
|
if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports) && gizmo_event(SLAGizmoEventType::ResetClippingPlane))
|
||||||
processed = true;
|
processed = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -95,9 +95,16 @@ void MeshClipper::recalculate_triangles()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vec3f MeshRaycaster::get_triangle_normal(const indexed_triangle_set& its, size_t facet_idx)
|
||||||
|
{
|
||||||
|
Vec3f a(its.vertices[its.indices[facet_idx](1)] - its.vertices[its.indices[facet_idx](0)]);
|
||||||
|
Vec3f b(its.vertices[its.indices[facet_idx](2)] - its.vertices[its.indices[facet_idx](0)]);
|
||||||
|
return Vec3f(a.cross(b)).normalized();
|
||||||
|
}
|
||||||
|
|
||||||
bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera,
|
bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera,
|
||||||
Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane) const
|
Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane,
|
||||||
|
size_t* facet_idx) const
|
||||||
{
|
{
|
||||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||||
const Transform3d& model_mat = camera.get_view_matrix();
|
const Transform3d& model_mat = camera.get_view_matrix();
|
||||||
|
@ -112,7 +119,21 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
|
||||||
pt1 = inv * pt1;
|
pt1 = inv * pt1;
|
||||||
pt2 = inv * pt2;
|
pt2 = inv * pt2;
|
||||||
|
|
||||||
std::vector<sla::EigenMesh3D::hit_result> hits = m_emesh.query_ray_hits(pt1, pt2-pt1);
|
point = pt1;
|
||||||
|
direction = pt2-pt1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera,
|
||||||
|
Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane,
|
||||||
|
size_t* facet_idx) const
|
||||||
|
{
|
||||||
|
Vec3d point;
|
||||||
|
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);
|
||||||
|
|
||||||
if (hits.empty())
|
if (hits.empty())
|
||||||
return false; // no intersection found
|
return false; // no intersection found
|
||||||
|
|
||||||
|
@ -134,6 +155,10 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
|
||||||
// Now stuff the points in the provided vector and calculate normals if asked about them:
|
// Now stuff the points in the provided vector and calculate normals if asked about them:
|
||||||
position = hits[i].position().cast<float>();
|
position = hits[i].position().cast<float>();
|
||||||
normal = hits[i].normal().cast<float>();
|
normal = hits[i].normal().cast<float>();
|
||||||
|
|
||||||
|
if (facet_idx)
|
||||||
|
*facet_idx = hits[i].face();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
#include "libslic3r/Geometry.hpp"
|
#include "libslic3r/Geometry.hpp"
|
||||||
#include "libslic3r/SLA/EigenMesh3D.hpp"
|
#include "libslic3r/SLA/EigenMesh3D.hpp"
|
||||||
|
#include "admesh/stl.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
@ -118,7 +120,8 @@ public:
|
||||||
const Camera& camera, // current camera position
|
const Camera& camera, // current camera position
|
||||||
Vec3f& position, // where to save the positibon of the hit (mesh coords)
|
Vec3f& position, // where to save the positibon of the hit (mesh coords)
|
||||||
Vec3f& normal, // normal of the triangle that was hit
|
Vec3f& normal, // normal of the triangle that was hit
|
||||||
const ClippingPlane* clipping_plane = nullptr // clipping plane (if active)
|
const ClippingPlane* clipping_plane = nullptr, // clipping plane (if active)
|
||||||
|
size_t* facet_idx = nullptr // index of the facet hit
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
// Given a vector of points in woorld coordinates, this returns vector
|
// Given a vector of points in woorld coordinates, this returns vector
|
||||||
|
@ -134,8 +137,11 @@ public:
|
||||||
// Given a point in world coords, the method returns closest point on the mesh.
|
// Given a point in world coords, the method returns closest point on the mesh.
|
||||||
// The output is in mesh coords.
|
// The output is in mesh coords.
|
||||||
// normal* can be used to also get normal of the respective triangle.
|
// normal* can be used to also get normal of the respective triangle.
|
||||||
|
|
||||||
Vec3f get_closest_point(const Vec3f& point, Vec3f* normal = nullptr) const;
|
Vec3f get_closest_point(const Vec3f& point, Vec3f* normal = nullptr) const;
|
||||||
|
|
||||||
|
static Vec3f get_triangle_normal(const indexed_triangle_set& its, size_t facet_idx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sla::EigenMesh3D m_emesh;
|
sla::EigenMesh3D m_emesh;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue