mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-13 03:21:49 +08:00
Merge remote-tracking branch 'origin/lm_cut_gizmo' into ys_cut
This commit is contained in:
commit
1e5d5ae2f5
@ -248,6 +248,8 @@ void GLGizmoCut3D::render_cut_plane()
|
|||||||
{
|
{
|
||||||
const BoundingBoxf3 box = m_move_gizmo.bounding_box();
|
const BoundingBoxf3 box = m_move_gizmo.bounding_box();
|
||||||
Vec3d plane_center = m_move_gizmo.get_center();// == Vec3d::Zero() ? box.center() : m_move_gizmo.get_center();
|
Vec3d plane_center = m_move_gizmo.get_center();// == Vec3d::Zero() ? box.center() : m_move_gizmo.get_center();
|
||||||
|
// update_contours();
|
||||||
|
m_c->object_clipper()->render_cut();
|
||||||
|
|
||||||
const float min_x = box.min.x() - GLGizmoCenterMove::Margin - plane_center.x();
|
const float min_x = box.min.x() - GLGizmoCenterMove::Margin - plane_center.x();
|
||||||
const float max_x = box.max.x() + GLGizmoCenterMove::Margin - plane_center.x();
|
const float max_x = box.max.x() + GLGizmoCenterMove::Margin - plane_center.x();
|
||||||
@ -433,7 +435,7 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit)
|
|||||||
ImGui::SameLine(m_label_width);
|
ImGui::SameLine(m_label_width);
|
||||||
for (Axis axis : {X, Y, Z})
|
for (Axis axis : {X, Y, Z})
|
||||||
render_rotation_input(axis);
|
render_rotation_input(axis);
|
||||||
m_imgui->text(_L("°"));
|
m_imgui->text(_L("°"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ImGui::AlignTextToFramePadding();
|
ImGui::AlignTextToFramePadding();
|
||||||
@ -489,6 +491,16 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit)
|
|||||||
const bool cut_clicked = m_imgui->button(_L("Perform cut"));
|
const bool cut_clicked = m_imgui->button(_L("Perform cut"));
|
||||||
m_imgui->disabled_end();
|
m_imgui->disabled_end();
|
||||||
|
|
||||||
|
////////
|
||||||
|
static bool hide_clipped = true;
|
||||||
|
static bool fill_cut = true;
|
||||||
|
static float contour_width = 0.;
|
||||||
|
m_imgui->checkbox("hide_clipped", hide_clipped);
|
||||||
|
m_imgui->checkbox("fill_cut", fill_cut);
|
||||||
|
m_imgui->slider_float("contour_width", &contour_width, 0.f, 3.f);
|
||||||
|
m_c->object_clipper()->set_behavior(hide_clipped, fill_cut, contour_width);
|
||||||
|
////////
|
||||||
|
|
||||||
m_imgui->end();
|
m_imgui->end();
|
||||||
|
|
||||||
if (cut_clicked && (m_keep_upper || m_keep_lower))
|
if (cut_clicked && (m_keep_upper || m_keep_lower))
|
||||||
@ -498,6 +510,12 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit)
|
|||||||
bool GLGizmoCut3D::can_perform_cut() const
|
bool GLGizmoCut3D::can_perform_cut() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
const BoundingBoxf3 box = bounding_box();
|
||||||
|
Vec3d plane_center = box.center();
|
||||||
|
plane_center.z() = 0;
|
||||||
|
m_c->object_clipper()->set_range_and_pos(plane_center,
|
||||||
|
plane_center + m_max_z * Vec3d::UnitZ(), m_cut_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::perform_cut(const Selection& selection)
|
void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||||
@ -521,5 +539,45 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down)
|
||||||
|
{
|
||||||
|
if (is_dragging())
|
||||||
|
return false;
|
||||||
|
const ModelObject *mo = m_c->selection_info()->model_object();
|
||||||
|
const ModelInstance *mi = mo->instances[m_c->selection_info()->get_active_instance()];
|
||||||
|
const Transform3d instance_trafo = mi->get_transformation().get_matrix();
|
||||||
|
const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix(true);
|
||||||
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
|
|
||||||
|
int mesh_id = -1;
|
||||||
|
for (const ModelVolume *mv : mo->volumes) {
|
||||||
|
++mesh_id;
|
||||||
|
if (! mv->is_model_part())
|
||||||
|
continue;
|
||||||
|
Vec3f hit;
|
||||||
|
Vec3f normal;
|
||||||
|
bool clipping_plane_was_hit = false;
|
||||||
|
m_c->raycaster()->raycasters()[mesh_id]->unproject_on_mesh(mouse_position, instance_trafo * mv->get_matrix(),
|
||||||
|
camera, hit, normal, m_c->object_clipper()->get_clipping_plane(),
|
||||||
|
nullptr, &clipping_plane_was_hit);
|
||||||
|
if (clipping_plane_was_hit) {
|
||||||
|
// The clipping plane was clicked, hit containts coordinates of the hit in world coords.
|
||||||
|
std::cout << hit.x() << "\t" << hit.y() << "\t" << hit.z() << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonGizmosDataID GLGizmoCut3D::on_get_requirements() const {
|
||||||
|
return CommonGizmosDataID(
|
||||||
|
int(CommonGizmosDataID::SelectionInfo)
|
||||||
|
| int(CommonGizmosDataID::InstancesHider)
|
||||||
|
| int(CommonGizmosDataID::ObjectClipper)
|
||||||
|
| int(CommonGizmosDataID::Raycaster));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
enum class SLAGizmoEventType : unsigned char;
|
||||||
|
|
||||||
class GLGizmoCenterMove : public GLGizmoMove3D
|
class GLGizmoCenterMove : public GLGizmoMove3D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -108,13 +110,20 @@ public:
|
|||||||
GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||||
|
|
||||||
std::string get_tooltip() const override;
|
std::string get_tooltip() const override;
|
||||||
|
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
|
||||||
|
|
||||||
void shift_cut_z(double delta);
|
void shift_cut_z(double delta);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool on_init() override;
|
bool on_init() override;
|
||||||
|
void on_load(cereal::BinaryInputArchive& ar) override { ar(m_cut_z, m_keep_upper, m_keep_lower, m_rotate_lower); }
|
||||||
|
void on_save(cereal::BinaryOutputArchive& ar) const override { ar(m_cut_z, m_keep_upper, m_keep_lower, m_rotate_lower); }
|
||||||
std::string on_get_name() const override;
|
std::string on_get_name() const override;
|
||||||
void on_set_state() override;
|
void on_set_state() override;
|
||||||
|
bool on_is_activable() const override;
|
||||||
|
void on_start_dragging() override;
|
||||||
|
void on_update(const UpdateData& data) override;
|
||||||
|
CommonGizmosDataID on_get_requirements() const override;
|
||||||
void on_set_hover_id() override;
|
void on_set_hover_id() override;
|
||||||
void on_enable_grabber(unsigned int id) override;
|
void on_enable_grabber(unsigned int id) override;
|
||||||
void on_disable_grabber(unsigned int id) override;
|
void on_disable_grabber(unsigned int id) override;
|
||||||
@ -129,6 +138,7 @@ protected:
|
|||||||
}
|
}
|
||||||
void on_render_input_window(float x, float y, float bottom_limit) override;
|
void on_render_input_window(float x, float y, float bottom_limit) override;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_center(const Vec3d& center);
|
void set_center(const Vec3d& center);
|
||||||
void render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx);
|
void render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx);
|
||||||
|
@ -295,7 +295,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||||||
else {
|
else {
|
||||||
if (m_imgui->button(m_desc.at("reset_direction"))) {
|
if (m_imgui->button(m_desc.at("reset_direction"))) {
|
||||||
wxGetApp().CallAfter([this](){
|
wxGetApp().CallAfter([this](){
|
||||||
m_c->object_clipper()->set_position(-1., false);
|
m_c->object_clipper()->set_position_by_ratio(-1., false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -304,7 +304,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||||||
ImGui::SameLine(sliders_left_width);
|
ImGui::SameLine(sliders_left_width);
|
||||||
ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width);
|
ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width);
|
||||||
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true, _L("Ctrl + Mouse wheel")))
|
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true, _L("Ctrl + Mouse wheel")))
|
||||||
m_c->object_clipper()->set_position(clp_dist, true);
|
m_c->object_clipper()->set_position_by_ratio(clp_dist, true);
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (m_imgui->button(m_desc.at("remove_all"))) {
|
if (m_imgui->button(m_desc.at("remove_all"))) {
|
||||||
|
@ -383,19 +383,19 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
|
|||||||
if (action == SLAGizmoEventType::MouseWheelUp && control_down) {
|
if (action == SLAGizmoEventType::MouseWheelUp && control_down) {
|
||||||
double pos = m_c->object_clipper()->get_position();
|
double pos = m_c->object_clipper()->get_position();
|
||||||
pos = std::min(1., pos + 0.01);
|
pos = std::min(1., pos + 0.01);
|
||||||
m_c->object_clipper()->set_position(pos, true);
|
m_c->object_clipper()->set_position_by_ratio(pos, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == SLAGizmoEventType::MouseWheelDown && control_down) {
|
if (action == SLAGizmoEventType::MouseWheelDown && control_down) {
|
||||||
double pos = m_c->object_clipper()->get_position();
|
double pos = m_c->object_clipper()->get_position();
|
||||||
pos = std::max(0., pos - 0.01);
|
pos = std::max(0., pos - 0.01);
|
||||||
m_c->object_clipper()->set_position(pos, true);
|
m_c->object_clipper()->set_position_by_ratio(pos, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == SLAGizmoEventType::ResetClippingPlane) {
|
if (action == SLAGizmoEventType::ResetClippingPlane) {
|
||||||
m_c->object_clipper()->set_position(-1., false);
|
m_c->object_clipper()->set_position_by_ratio(-1., false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,7 +693,7 @@ RENDER_AGAIN:
|
|||||||
else {
|
else {
|
||||||
if (m_imgui->button(m_desc.at("reset_direction"))) {
|
if (m_imgui->button(m_desc.at("reset_direction"))) {
|
||||||
wxGetApp().CallAfter([this](){
|
wxGetApp().CallAfter([this](){
|
||||||
m_c->object_clipper()->set_position(-1., false);
|
m_c->object_clipper()->set_position_by_ratio(-1., false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -702,7 +702,7 @@ RENDER_AGAIN:
|
|||||||
ImGui::PushItemWidth(window_width - settings_sliders_left);
|
ImGui::PushItemWidth(window_width - settings_sliders_left);
|
||||||
float clp_dist = m_c->object_clipper()->get_position();
|
float clp_dist = m_c->object_clipper()->get_position();
|
||||||
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f"))
|
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f"))
|
||||||
m_c->object_clipper()->set_position(clp_dist, true);
|
m_c->object_clipper()->set_position_by_ratio(clp_dist, true);
|
||||||
|
|
||||||
// make sure supports are shown/hidden as appropriate
|
// make sure supports are shown/hidden as appropriate
|
||||||
bool show_sups = m_c->instances_hider()->are_supports_shown();
|
bool show_sups = m_c->instances_hider()->are_supports_shown();
|
||||||
|
@ -463,7 +463,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
|
|||||||
m_imgui->text(m_desc.at("clipping_of_view"));
|
m_imgui->text(m_desc.at("clipping_of_view"));
|
||||||
} else {
|
} else {
|
||||||
if (m_imgui->button(m_desc.at("reset_direction"))) {
|
if (m_imgui->button(m_desc.at("reset_direction"))) {
|
||||||
wxGetApp().CallAfter([this]() { m_c->object_clipper()->set_position(-1., false); });
|
wxGetApp().CallAfter([this]() { m_c->object_clipper()->set_position_by_ratio(-1., false); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,7 +471,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
|
|||||||
ImGui::SameLine(sliders_left_width);
|
ImGui::SameLine(sliders_left_width);
|
||||||
ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width);
|
ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width);
|
||||||
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true, _L("Ctrl + Mouse wheel")))
|
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true, _L("Ctrl + Mouse wheel")))
|
||||||
m_c->object_clipper()->set_position(clp_dist, true);
|
m_c->object_clipper()->set_position_by_ratio(clp_dist, true);
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (m_imgui->button(m_desc.at("remove_all"))) {
|
if (m_imgui->button(m_desc.at("remove_all"))) {
|
||||||
|
@ -429,7 +429,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||||||
pos = action == SLAGizmoEventType::MouseWheelDown
|
pos = action == SLAGizmoEventType::MouseWheelDown
|
||||||
? std::max(0., pos - 0.01)
|
? std::max(0., pos - 0.01)
|
||||||
: std::min(1., pos + 0.01);
|
: std::min(1., pos + 0.01);
|
||||||
m_c->object_clipper()->set_position(pos, true);
|
m_c->object_clipper()->set_position_by_ratio(pos, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (alt_down) {
|
else if (alt_down) {
|
||||||
@ -461,7 +461,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action == SLAGizmoEventType::ResetClippingPlane) {
|
if (action == SLAGizmoEventType::ResetClippingPlane) {
|
||||||
m_c->object_clipper()->set_position(-1., false);
|
m_c->object_clipper()->set_position_by_ratio(-1., false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
|
|||||||
else {
|
else {
|
||||||
if (m_imgui->button(m_desc.at("reset_direction"))) {
|
if (m_imgui->button(m_desc.at("reset_direction"))) {
|
||||||
wxGetApp().CallAfter([this](){
|
wxGetApp().CallAfter([this](){
|
||||||
m_c->object_clipper()->set_position(-1., false);
|
m_c->object_clipper()->set_position_by_ratio(-1., false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
|
|||||||
ImGui::SameLine(sliders_left_width);
|
ImGui::SameLine(sliders_left_width);
|
||||||
ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width);
|
ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width);
|
||||||
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true, _L("Ctrl + Mouse wheel")))
|
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true, _L("Ctrl + Mouse wheel")))
|
||||||
m_c->object_clipper()->set_position(clp_dist, true);
|
m_c->object_clipper()->set_position_by_ratio(clp_dist, true);
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (m_imgui->button(m_desc.at("remove_all"))) {
|
if (m_imgui->button(m_desc.at("remove_all"))) {
|
||||||
|
@ -516,19 +516,19 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||||||
if (action == SLAGizmoEventType::MouseWheelUp && control_down) {
|
if (action == SLAGizmoEventType::MouseWheelUp && control_down) {
|
||||||
double pos = m_c->object_clipper()->get_position();
|
double pos = m_c->object_clipper()->get_position();
|
||||||
pos = std::min(1., pos + 0.01);
|
pos = std::min(1., pos + 0.01);
|
||||||
m_c->object_clipper()->set_position(pos, true);
|
m_c->object_clipper()->set_position_by_ratio(pos, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == SLAGizmoEventType::MouseWheelDown && control_down) {
|
if (action == SLAGizmoEventType::MouseWheelDown && control_down) {
|
||||||
double pos = m_c->object_clipper()->get_position();
|
double pos = m_c->object_clipper()->get_position();
|
||||||
pos = std::max(0., pos - 0.01);
|
pos = std::max(0., pos - 0.01);
|
||||||
m_c->object_clipper()->set_position(pos, true);
|
m_c->object_clipper()->set_position_by_ratio(pos, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == SLAGizmoEventType::ResetClippingPlane) {
|
if (action == SLAGizmoEventType::ResetClippingPlane) {
|
||||||
m_c->object_clipper()->set_position(-1., false);
|
m_c->object_clipper()->set_position_by_ratio(-1., false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -826,7 +826,7 @@ RENDER_AGAIN:
|
|||||||
else {
|
else {
|
||||||
if (m_imgui->button(m_desc.at("reset_direction"))) {
|
if (m_imgui->button(m_desc.at("reset_direction"))) {
|
||||||
wxGetApp().CallAfter([this](){
|
wxGetApp().CallAfter([this](){
|
||||||
m_c->object_clipper()->set_position(-1., false);
|
m_c->object_clipper()->set_position_by_ratio(-1., false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -835,7 +835,7 @@ RENDER_AGAIN:
|
|||||||
ImGui::PushItemWidth(window_width - clipping_slider_left);
|
ImGui::PushItemWidth(window_width - clipping_slider_left);
|
||||||
float clp_dist = m_c->object_clipper()->get_position();
|
float clp_dist = m_c->object_clipper()->get_position();
|
||||||
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f"))
|
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f"))
|
||||||
m_c->object_clipper()->set_position(clp_dist, true);
|
m_c->object_clipper()->set_position_by_ratio(clp_dist, true);
|
||||||
|
|
||||||
|
|
||||||
if (m_imgui->button("?")) {
|
if (m_imgui->button("?")) {
|
||||||
|
@ -425,18 +425,20 @@ void ObjectClipper::render_cut() const
|
|||||||
glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
clipper->render_cut({ 1.0f, 0.37f, 0.0f, 1.0f });
|
clipper->render_cut({ 1.0f, 0.37f, 0.0f, 1.0f });
|
||||||
|
clipper->render_contour({ 1.f, 1.f, 1.f, 1.f});
|
||||||
#else
|
#else
|
||||||
glsafe(::glColor3f(1.0f, 0.37f, 0.0f));
|
glsafe(::glColor3f(1.0f, 0.37f, 0.0f));
|
||||||
clipper->render_cut();
|
clipper->render_cut();
|
||||||
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
glsafe(::glColor3f(1.f, 1.f, 1.f));
|
||||||
|
clipper->render_contour();
|
||||||
|
#endif
|
||||||
glsafe(::glPopMatrix());
|
glsafe(::glPopMatrix());
|
||||||
|
|
||||||
++clipper_id;
|
++clipper_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectClipper::set_position_by_ratio(double pos, bool keep_normal)
|
||||||
void ObjectClipper::set_position(double pos, bool keep_normal)
|
|
||||||
{
|
{
|
||||||
const ModelObject* mo = get_pool()->selection_info()->model_object();
|
const ModelObject* mo = get_pool()->selection_info()->model_object();
|
||||||
int active_inst = get_pool()->selection_info()->get_active_instance();
|
int active_inst = get_pool()->selection_info()->get_active_instance();
|
||||||
@ -454,6 +456,28 @@ void ObjectClipper::set_position(double pos, bool keep_normal)
|
|||||||
get_pool()->get_canvas()->set_as_dirty();
|
get_pool()->get_canvas()->set_as_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectClipper::set_range_and_pos(const Vec3d& origin, const Vec3d& end, double pos)
|
||||||
|
{
|
||||||
|
Vec3d normal = end-origin;
|
||||||
|
double norm = normal.norm();
|
||||||
|
pos = std::clamp(pos, 0.0001, norm);
|
||||||
|
m_clp.reset(new ClippingPlane(normal, pos));
|
||||||
|
m_clp_ratio = pos/norm;
|
||||||
|
get_pool()->get_canvas()->set_as_dirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ClippingPlane* ObjectClipper::get_clipping_plane() const
|
||||||
|
{
|
||||||
|
static const ClippingPlane no_clip = ClippingPlane::ClipsNothing();
|
||||||
|
return m_hide_clipped ? m_clp.get() : &no_clip;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectClipper::set_behavior(bool hide_clipped, bool fill_cut, double contour_width)
|
||||||
|
{
|
||||||
|
m_hide_clipped = hide_clipped;
|
||||||
|
for (auto& clipper : m_clippers)
|
||||||
|
clipper->set_behaviour(fill_cut, contour_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SupportsClipper::on_update()
|
void SupportsClipper::on_update()
|
||||||
@ -542,9 +566,12 @@ void SupportsClipper::render_cut() const
|
|||||||
glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
m_clipper->render_cut({ 1.0f, 0.f, 0.37f, 1.0f });
|
m_clipper->render_cut({ 1.0f, 0.f, 0.37f, 1.0f });
|
||||||
|
m_clipper->render_contour({ 1.f, 1.f, 1.f, 1.f });
|
||||||
#else
|
#else
|
||||||
glsafe(::glColor3f(1.0f, 0.f, 0.37f));
|
glsafe(::glColor3f(1.0f, 0.f, 0.37f));
|
||||||
m_clipper->render_cut();
|
m_clipper->render_cut();
|
||||||
|
glsafe(::glColor3f(1.0f, 1.f, 1.f));
|
||||||
|
m_clipper->render_contour();
|
||||||
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
glsafe(::glPopMatrix());
|
glsafe(::glPopMatrix());
|
||||||
}
|
}
|
||||||
|
@ -255,10 +255,13 @@ public:
|
|||||||
CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
|
CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
|
||||||
#endif // NDEBUG
|
#endif // NDEBUG
|
||||||
|
|
||||||
void set_position(double pos, bool keep_normal);
|
void set_normal(const Vec3d& dir);
|
||||||
double get_position() const { return m_clp_ratio; }
|
double get_position() const { return m_clp_ratio; }
|
||||||
ClippingPlane* get_clipping_plane() const { return m_clp.get(); }
|
const ClippingPlane* get_clipping_plane() const;
|
||||||
void render_cut() const;
|
void render_cut() const;
|
||||||
|
void set_position_by_ratio(double pos, bool keep_normal);
|
||||||
|
void set_range_and_pos(const Vec3d& origin, const Vec3d& end, double pos);
|
||||||
|
void set_behavior(bool hide_clipped, bool fill_cut, double contour_width);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -271,6 +274,7 @@ private:
|
|||||||
std::unique_ptr<ClippingPlane> m_clp;
|
std::unique_ptr<ClippingPlane> m_clp;
|
||||||
double m_clp_ratio = 0.;
|
double m_clp_ratio = 0.;
|
||||||
double m_active_inst_bb_radius = 0.;
|
double m_active_inst_bb_radius = 0.;
|
||||||
|
bool m_hide_clipped = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -445,6 +445,8 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p
|
|||||||
return dynamic_cast<GLGizmoSeam*>(m_gizmos[Seam].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
return dynamic_cast<GLGizmoSeam*>(m_gizmos[Seam].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||||
else if (m_current == MmuSegmentation)
|
else if (m_current == MmuSegmentation)
|
||||||
return dynamic_cast<GLGizmoMmuSegmentation*>(m_gizmos[MmuSegmentation].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
return dynamic_cast<GLGizmoMmuSegmentation*>(m_gizmos[MmuSegmentation].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||||
|
else if (m_current == Cut)
|
||||||
|
return dynamic_cast<GLGizmoCut*>(m_gizmos[Cut].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -656,7 +658,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
|||||||
m_tooltip.clear();
|
m_tooltip.clear();
|
||||||
|
|
||||||
if (evt.LeftDown() && (!control_down || grabber_contains_mouse())) {
|
if (evt.LeftDown() && (!control_down || grabber_contains_mouse())) {
|
||||||
if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports || m_current == Seam || m_current == MmuSegmentation)
|
if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports || m_current == Seam || m_current == MmuSegmentation || m_current == Cut)
|
||||||
&& gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown(), evt.AltDown()))
|
&& gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown(), evt.AltDown()))
|
||||||
// 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;
|
||||||
|
@ -19,6 +19,16 @@
|
|||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
void MeshClipper::set_behaviour(bool fill_cut, double contour_width)
|
||||||
|
{
|
||||||
|
if (fill_cut != m_fill_cut || contour_width != m_contour_width)
|
||||||
|
m_triangles_valid = false;
|
||||||
|
m_fill_cut = fill_cut;
|
||||||
|
m_contour_width = contour_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MeshClipper::set_plane(const ClippingPlane& plane)
|
void MeshClipper::set_plane(const ClippingPlane& plane)
|
||||||
{
|
{
|
||||||
if (m_plane != plane) {
|
if (m_plane != plane) {
|
||||||
@ -43,7 +53,6 @@ void MeshClipper::set_mesh(const TriangleMesh& mesh)
|
|||||||
if (m_mesh != &mesh) {
|
if (m_mesh != &mesh) {
|
||||||
m_mesh = &mesh;
|
m_mesh = &mesh;
|
||||||
m_triangles_valid = false;
|
m_triangles_valid = false;
|
||||||
m_triangles2d.resize(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +61,6 @@ void MeshClipper::set_negative_mesh(const TriangleMesh& mesh)
|
|||||||
if (m_negative_mesh != &mesh) {
|
if (m_negative_mesh != &mesh) {
|
||||||
m_negative_mesh = &mesh;
|
m_negative_mesh = &mesh;
|
||||||
m_triangles_valid = false;
|
m_triangles_valid = false;
|
||||||
m_triangles2d.resize(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,12 +71,10 @@ void MeshClipper::set_transformation(const Geometry::Transformation& trafo)
|
|||||||
if (! m_trafo.get_matrix().isApprox(trafo.get_matrix())) {
|
if (! m_trafo.get_matrix().isApprox(trafo.get_matrix())) {
|
||||||
m_trafo = trafo;
|
m_trafo = trafo;
|
||||||
m_triangles_valid = false;
|
m_triangles_valid = false;
|
||||||
m_triangles2d.resize(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
void MeshClipper::render_cut(const ColorRGBA& color)
|
void MeshClipper::render_cut(const ColorRGBA& color)
|
||||||
#else
|
#else
|
||||||
@ -77,7 +83,6 @@ void MeshClipper::render_cut()
|
|||||||
{
|
{
|
||||||
if (! m_triangles_valid)
|
if (! m_triangles_valid)
|
||||||
recalculate_triangles();
|
recalculate_triangles();
|
||||||
|
|
||||||
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
GLShaderProgram* curr_shader = wxGetApp().get_current_shader();
|
GLShaderProgram* curr_shader = wxGetApp().get_current_shader();
|
||||||
if (curr_shader != nullptr)
|
if (curr_shader != nullptr)
|
||||||
@ -100,6 +105,36 @@ void MeshClipper::render_cut()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
|
void MeshClipper::render_contour(const ColorRGBA& color)
|
||||||
|
#else
|
||||||
|
void MeshClipper::render_contour()
|
||||||
|
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
|
{
|
||||||
|
if (! m_triangles_valid)
|
||||||
|
recalculate_triangles();
|
||||||
|
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
|
GLShaderProgram* curr_shader = wxGetApp().get_current_shader();
|
||||||
|
if (curr_shader != nullptr)
|
||||||
|
curr_shader->stop_using();
|
||||||
|
|
||||||
|
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||||
|
if (shader != nullptr) {
|
||||||
|
shader->start_using();
|
||||||
|
m_model_expanded.set_color(color);
|
||||||
|
m_model_expanded.render();
|
||||||
|
shader->stop_using();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curr_shader != nullptr)
|
||||||
|
curr_shader->start_using();
|
||||||
|
#else
|
||||||
|
if (m_vertex_array_expanded.has_VBOs())
|
||||||
|
m_vertex_array_expanded.render();
|
||||||
|
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MeshClipper::recalculate_triangles()
|
void MeshClipper::recalculate_triangles()
|
||||||
{
|
{
|
||||||
@ -181,24 +216,25 @@ void MeshClipper::recalculate_triangles()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_triangles2d = triangulate_expolygons_2f(expolys, m_trafo.get_matrix().matrix().determinant() < 0.);
|
|
||||||
|
|
||||||
tr.pretranslate(0.001 * m_plane.get_normal().normalized()); // to avoid z-fighting
|
tr.pretranslate(0.001 * m_plane.get_normal().normalized()); // to avoid z-fighting
|
||||||
|
|
||||||
|
std::vector<Vec2f> triangles2d = m_fill_cut
|
||||||
|
? triangulate_expolygons_2f(expolys, m_trafo.get_matrix().matrix().determinant() < 0.)
|
||||||
|
: std::vector<Vec2f>();
|
||||||
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
m_model.reset();
|
m_model.reset();
|
||||||
|
|
||||||
GLModel::Geometry init_data;
|
GLModel::Geometry init_data;
|
||||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(m_triangles2d.size()) };
|
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(triangles2d.size()) };
|
||||||
init_data.reserve_vertices(m_triangles2d.size());
|
init_data.reserve_vertices(triangles2d.size());
|
||||||
init_data.reserve_indices(m_triangles2d.size());
|
init_data.reserve_indices(triangles2d.size());
|
||||||
|
|
||||||
// vertices + indices
|
// vertices + indices
|
||||||
for (auto it = m_triangles2d.cbegin(); it != m_triangles2d.cend(); it = it + 3) {
|
for (auto it = triangles2d.cbegin(); it != triangles2d.cend(); it = it + 3) {
|
||||||
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 0)).x(), (*(it + 0)).y(), height_mesh)).cast<float>(), (Vec3f)up.cast<float>());
|
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 0)).x(), (*(it + 0)).y(), height_mesh)).cast<float>(), (Vec3f)up.cast<float>());
|
||||||
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 1)).x(), (*(it + 1)).y(), height_mesh)).cast<float>(), (Vec3f)up.cast<float>());
|
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 1)).x(), (*(it + 1)).y(), height_mesh)).cast<float>(), (Vec3f)up.cast<float>());
|
||||||
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 2)).x(), (*(it + 2)).y(), height_mesh)).cast<float>(), (Vec3f)up.cast<float>());
|
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 2)).x(), (*(it + 2)).y(), height_mesh)).cast<float>(), (Vec3f)up.cast<float>());
|
||||||
const size_t idx = it - m_triangles2d.cbegin();
|
const size_t idx = it - triangles2d.cbegin();
|
||||||
if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
||||||
init_data.add_ushort_triangle((unsigned short)idx, (unsigned short)idx + 1, (unsigned short)idx + 2);
|
init_data.add_ushort_triangle((unsigned short)idx, (unsigned short)idx + 1, (unsigned short)idx + 2);
|
||||||
else
|
else
|
||||||
@ -209,16 +245,61 @@ void MeshClipper::recalculate_triangles()
|
|||||||
m_model.init_from(std::move(init_data));
|
m_model.init_from(std::move(init_data));
|
||||||
#else
|
#else
|
||||||
m_vertex_array.release_geometry();
|
m_vertex_array.release_geometry();
|
||||||
for (auto it=m_triangles2d.cbegin(); it != m_triangles2d.cend(); it=it+3) {
|
for (auto it=triangles2d.cbegin(); it != triangles2d.cend(); it=it+3) {
|
||||||
m_vertex_array.push_geometry(tr * Vec3d((*(it+0))(0), (*(it+0))(1), height_mesh), up);
|
m_vertex_array.push_geometry(tr * Vec3d((*(it+0))(0), (*(it+0))(1), height_mesh), up);
|
||||||
m_vertex_array.push_geometry(tr * Vec3d((*(it+1))(0), (*(it+1))(1), height_mesh), up);
|
m_vertex_array.push_geometry(tr * Vec3d((*(it+1))(0), (*(it+1))(1), height_mesh), up);
|
||||||
m_vertex_array.push_geometry(tr * Vec3d((*(it+2))(0), (*(it+2))(1), height_mesh), up);
|
m_vertex_array.push_geometry(tr * Vec3d((*(it+2))(0), (*(it+2))(1), height_mesh), up);
|
||||||
const size_t idx = it - m_triangles2d.cbegin();
|
const size_t idx = it - triangles2d.cbegin();
|
||||||
m_vertex_array.push_triangle(idx, idx+1, idx+2);
|
m_vertex_array.push_triangle(idx, idx+1, idx+2);
|
||||||
}
|
}
|
||||||
m_vertex_array.finalize_geometry(true);
|
m_vertex_array.finalize_geometry(true);
|
||||||
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
|
|
||||||
|
|
||||||
|
triangles2d = {};
|
||||||
|
if (m_contour_width != 0.) {
|
||||||
|
ExPolygons expolys_exp = offset_ex(expolys, scale_(m_contour_width));
|
||||||
|
expolys_exp = diff_ex(expolys_exp, expolys);
|
||||||
|
triangles2d = triangulate_expolygons_2f(expolys_exp, m_trafo.get_matrix().matrix().determinant() < 0.);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
|
m_model_expanded.reset();
|
||||||
|
|
||||||
|
init_data = GLModel::Geometry();
|
||||||
|
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(triangles2d.size()) };
|
||||||
|
init_data.reserve_vertices(triangles2d.size());
|
||||||
|
init_data.reserve_indices(triangles2d.size());
|
||||||
|
|
||||||
|
// vertices + indices
|
||||||
|
for (auto it = triangles2d.cbegin(); it != triangles2d.cend(); it = it + 3) {
|
||||||
|
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 0)).x(), (*(it + 0)).y(), height_mesh)).cast<float>(), (Vec3f)up.cast<float>());
|
||||||
|
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 1)).x(), (*(it + 1)).y(), height_mesh)).cast<float>(), (Vec3f)up.cast<float>());
|
||||||
|
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 2)).x(), (*(it + 2)).y(), height_mesh)).cast<float>(), (Vec3f)up.cast<float>());
|
||||||
|
const size_t idx = it - triangles2d.cbegin();
|
||||||
|
if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
||||||
|
init_data.add_ushort_triangle((unsigned short)idx, (unsigned short)idx + 1, (unsigned short)idx + 2);
|
||||||
|
else
|
||||||
|
init_data.add_uint_triangle((unsigned int)idx, (unsigned int)idx + 1, (unsigned int)idx + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!init_data.is_empty())
|
||||||
|
m_model_expanded.init_from(std::move(init_data));
|
||||||
|
#else
|
||||||
|
m_vertex_array_expanded.release_geometry();
|
||||||
|
for (auto it=triangles2d.cbegin(); it != triangles2d.cend(); it=it+3) {
|
||||||
|
m_vertex_array_expanded.push_geometry(tr * Vec3d((*(it+0))(0), (*(it+0))(1), height_mesh), up);
|
||||||
|
m_vertex_array_expanded.push_geometry(tr * Vec3d((*(it+1))(0), (*(it+1))(1), height_mesh), up);
|
||||||
|
m_vertex_array_expanded.push_geometry(tr * Vec3d((*(it+2))(0), (*(it+2))(1), height_mesh), up);
|
||||||
|
const size_t idx = it - triangles2d.cbegin();
|
||||||
|
m_vertex_array_expanded.push_triangle(idx, idx+1, idx+2);
|
||||||
|
}
|
||||||
|
m_vertex_array_expanded.finalize_geometry(true);
|
||||||
|
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m_triangles_valid = true;
|
m_triangles_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,8 +334,11 @@ void MeshRaycaster::line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3
|
|||||||
|
|
||||||
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,
|
Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane,
|
||||||
size_t* facet_idx) const
|
size_t* facet_idx, bool* was_clipping_plane_hit) const
|
||||||
{
|
{
|
||||||
|
if (was_clipping_plane_hit)
|
||||||
|
*was_clipping_plane_hit = false;
|
||||||
|
|
||||||
Vec3d point;
|
Vec3d point;
|
||||||
Vec3d direction;
|
Vec3d direction;
|
||||||
line_from_mouse_pos(mouse_pos, trafo, camera, point, direction);
|
line_from_mouse_pos(mouse_pos, trafo, camera, point, direction);
|
||||||
@ -275,9 +359,26 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i==hits.size() || (hits.size()-i) % 2 != 0) {
|
if (i==hits.size()) {
|
||||||
// All hits are either clipped, or there is an odd number of unclipped
|
// All hits are clipped.
|
||||||
// hits - meaning the nearest must be from inside the mesh.
|
return false;
|
||||||
|
}
|
||||||
|
if ((hits.size()-i) % 2 != 0) {
|
||||||
|
// There is an odd number of unclipped hits - meaning the nearest must be from inside the mesh.
|
||||||
|
// In that case, calculate intersection with the clipping place.
|
||||||
|
if (clipping_plane && was_clipping_plane_hit) {
|
||||||
|
direction = direction + point;
|
||||||
|
point = trafo * point; // transform to world coords
|
||||||
|
direction = trafo * direction - point;
|
||||||
|
|
||||||
|
Vec3d normal = -clipping_plane->get_normal().cast<double>();
|
||||||
|
double den = normal.dot(direction);
|
||||||
|
if (den != 0.) {
|
||||||
|
double t = (-clipping_plane->get_offset() - normal.dot(point))/den;
|
||||||
|
position = (point + t * direction).cast<float>();
|
||||||
|
*was_clipping_plane_hit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,10 @@ public:
|
|||||||
class MeshClipper
|
class MeshClipper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// Set whether the cut should be triangulated and whether a cut
|
||||||
|
// contour should be calculated and shown.
|
||||||
|
void set_behaviour(bool fill_cut, double contour_width);
|
||||||
|
|
||||||
// Inform MeshClipper about which plane we want to use to cut the mesh
|
// Inform MeshClipper about which plane we want to use to cut the mesh
|
||||||
// This is supposed to be in world coordinates.
|
// This is supposed to be in world coordinates.
|
||||||
void set_plane(const ClippingPlane& plane);
|
void set_plane(const ClippingPlane& plane);
|
||||||
@ -100,8 +104,12 @@ public:
|
|||||||
// be set in world coords.
|
// be set in world coords.
|
||||||
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
void render_cut(const ColorRGBA& color);
|
void render_cut(const ColorRGBA& color);
|
||||||
|
void render_contour(const ColorRGBA& color);
|
||||||
#else
|
#else
|
||||||
void render_cut();
|
void render_cut();
|
||||||
|
// Render the triangulated contour. Transformation matrices should
|
||||||
|
// be set in world coords.
|
||||||
|
void render_contour();
|
||||||
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -112,13 +120,16 @@ private:
|
|||||||
const TriangleMesh* m_negative_mesh = nullptr;
|
const TriangleMesh* m_negative_mesh = nullptr;
|
||||||
ClippingPlane m_plane;
|
ClippingPlane m_plane;
|
||||||
ClippingPlane m_limiting_plane = ClippingPlane::ClipsNothing();
|
ClippingPlane m_limiting_plane = ClippingPlane::ClipsNothing();
|
||||||
std::vector<Vec2f> m_triangles2d;
|
|
||||||
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
GLModel m_model;
|
GLModel m_model;
|
||||||
|
GLModel m_model_expanded;
|
||||||
#else
|
#else
|
||||||
GLIndexedVertexArray m_vertex_array;
|
GLIndexedVertexArray m_vertex_array;
|
||||||
|
GLIndexedVertexArray m_vertex_array_expanded;
|
||||||
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
|
||||||
bool m_triangles_valid = false;
|
bool m_triangles_valid = false;
|
||||||
|
bool m_fill_cut = true;
|
||||||
|
double m_contour_width = 0.;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -143,10 +154,11 @@ public:
|
|||||||
const Vec2d& mouse_pos,
|
const Vec2d& mouse_pos,
|
||||||
const Transform3d& trafo, // how to get the mesh into world coords
|
const Transform3d& trafo, // how to get the mesh into world coords
|
||||||
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 if mesh, world coords if clipping plane)
|
||||||
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
|
size_t* facet_idx = nullptr, // index of the facet hit
|
||||||
|
bool* was_clipping_plane_hit = nullptr // is the hit on the clipping place cross section?
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
// Given a vector of points in woorld coordinates, this returns vector
|
// Given a vector of points in woorld coordinates, this returns vector
|
||||||
|
Loading…
x
Reference in New Issue
Block a user