This commit is contained in:
bubnikv 2019-02-20 15:54:25 +01:00
commit 3901ac47d1
4 changed files with 100 additions and 64 deletions

View file

@ -3677,7 +3677,40 @@ GLCanvas3D::WarningTexture::WarningTexture()
{ {
} }
bool GLCanvas3D::WarningTexture::generate(const std::string& msg, const GLCanvas3D& canvas) void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool state, const GLCanvas3D& canvas)
{
auto it = std::find(m_warnings.begin(), m_warnings.end(), warning);
if (state) {
if (it != m_warnings.end()) // this warning is already set to be shown
return;
m_warnings.push_back(warning);
std::sort(m_warnings.begin(), m_warnings.end());
}
else {
if (it == m_warnings.end()) // deactivating something that is not active is an easy task
return;
m_warnings.erase(it);
if (m_warnings.empty()) { // nothing remains to be shown
reset();
return;
}
}
// Look at the end of our vector and generate proper texture.
std::string text;
switch (m_warnings.back()) {
case ObjectOutside : text = L("Detected object outside print volume"); break;
case ToolpathOutside : text = L("Detected toolpath outside print volume"); break;
case SomethingNotShown : text = L("Some objects are not visible when editing supports"); break;
}
_generate(text, canvas); // GUI::GLTexture::reset() is called at the beginning of generate(...)
}
bool GLCanvas3D::WarningTexture::_generate(const std::string& msg, const GLCanvas3D& canvas)
{ {
reset(); reset();
@ -3750,6 +3783,9 @@ bool GLCanvas3D::WarningTexture::generate(const std::string& msg, const GLCanvas
void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const
{ {
if (m_warnings.empty())
return;
if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0)) if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0))
{ {
::glDisable(GL_DEPTH_TEST); ::glDisable(GL_DEPTH_TEST);
@ -4074,7 +4110,6 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
, m_apply_zoom_to_volumes_filter(false) , m_apply_zoom_to_volumes_filter(false)
, m_hover_volume_id(-1) , m_hover_volume_id(-1)
, m_toolbar_action_running(false) , m_toolbar_action_running(false)
, m_warning_texture_enabled(false)
, m_legend_texture_enabled(false) , m_legend_texture_enabled(false)
, m_picking_enabled(false) , m_picking_enabled(false)
, m_moving_enabled(false) , m_moving_enabled(false)
@ -4232,8 +4267,7 @@ void GLCanvas3D::reset_volumes()
m_dirty = true; m_dirty = true;
} }
enable_warning_texture(false); _set_warning_texture(WarningTexture::ObjectOutside, false);
_reset_warning_texture();
} }
int GLCanvas3D::check_volumes_outside_state() const int GLCanvas3D::check_volumes_outside_state() const
@ -4262,6 +4296,12 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject
} }
if (visible && !mo) if (visible && !mo)
toggle_sla_auxiliaries_visibility(true); toggle_sla_auxiliaries_visibility(true);
if (!mo && !visible && !m_model->objects.empty() && (m_model->objects.size() > 1 || m_model->objects.front()->instances.size() > 1))
_set_warning_texture(WarningTexture::SomethingNotShown, true);
if (!mo && visible)
_set_warning_texture(WarningTexture::SomethingNotShown, false);
} }
@ -4375,11 +4415,6 @@ void GLCanvas3D::enable_layers_editing(bool enable)
} }
} }
void GLCanvas3D::enable_warning_texture(bool enable)
{
m_warning_texture_enabled = enable;
}
void GLCanvas3D::enable_legend_texture(bool enable) void GLCanvas3D::enable_legend_texture(bool enable)
{ {
m_legend_texture_enabled = enable; m_legend_texture_enabled = enable;
@ -4998,22 +5033,19 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
if (!contained) if (!contained)
{ {
enable_warning_texture(true); _set_warning_texture(WarningTexture::ObjectOutside, true);
_generate_warning_texture(L("Detected object outside print volume"));
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, state == ModelInstance::PVS_Fully_Outside)); post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, state == ModelInstance::PVS_Fully_Outside));
} }
else else
{ {
enable_warning_texture(false);
m_volumes.reset_outside_state(); m_volumes.reset_outside_state();
_reset_warning_texture(); _set_warning_texture(WarningTexture::ObjectOutside, false);
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, !m_model->objects.empty())); post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, !m_model->objects.empty()));
} }
} }
else else
{ {
enable_warning_texture(false); _set_warning_texture(WarningTexture::ObjectOutside, false);
_reset_warning_texture();
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false)); post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false));
} }
@ -6667,9 +6699,6 @@ void GLCanvas3D::_render_selection_center() const
void GLCanvas3D::_render_warning_texture() const void GLCanvas3D::_render_warning_texture() const
{ {
if (!m_warning_texture_enabled)
return;
m_warning_texture.render(*this); m_warning_texture.render(*this);
} }
@ -8204,17 +8233,7 @@ void GLCanvas3D::_update_toolpath_volumes_outside_state()
void GLCanvas3D::_show_warning_texture_if_needed() void GLCanvas3D::_show_warning_texture_if_needed()
{ {
_set_current(); _set_current();
_set_warning_texture(WarningTexture::ToolpathOutside, _is_any_volume_outside());
if (_is_any_volume_outside())
{
enable_warning_texture(true);
_generate_warning_texture(L("Detected toolpath outside print volume"));
}
else
{
enable_warning_texture(false);
_reset_warning_texture();
}
} }
std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& colors) std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& colors)
@ -8247,14 +8266,9 @@ void GLCanvas3D::_generate_legend_texture(const GCodePreviewData& preview_data,
m_legend_texture.generate(preview_data, tool_colors, *this, m_dynamic_background_enabled && _is_any_volume_outside()); m_legend_texture.generate(preview_data, tool_colors, *this, m_dynamic_background_enabled && _is_any_volume_outside());
} }
void GLCanvas3D::_generate_warning_texture(const std::string& msg) void GLCanvas3D::_set_warning_texture(WarningTexture::Warning warning, bool state)
{ {
m_warning_texture.generate(msg, *this); m_warning_texture.activate(warning, state, *this);
}
void GLCanvas3D::_reset_warning_texture()
{
m_warning_texture.reset();
} }
bool GLCanvas3D::_is_any_volume_outside() const bool GLCanvas3D::_is_any_volume_outside() const

View file

@ -843,18 +843,32 @@ private:
class WarningTexture : public GUI::GLTexture class WarningTexture : public GUI::GLTexture
{ {
public:
WarningTexture();
enum Warning {
ObjectOutside,
ToolpathOutside,
SomethingNotShown
};
// Sets a warning of the given type to be active/inactive. If several warnings are active simultaneously,
// only the last one is shown (decided by the order in the enum above).
void activate(WarningTexture::Warning warning, bool state, const GLCanvas3D& canvas);
void render(const GLCanvas3D& canvas) const;
private:
static const unsigned char Background_Color[3]; static const unsigned char Background_Color[3];
static const unsigned char Opacity; static const unsigned char Opacity;
int m_original_width; int m_original_width;
int m_original_height; int m_original_height;
public: // Information about which warnings are currently active.
WarningTexture(); std::vector<Warning> m_warnings;
bool generate(const std::string& msg, const GLCanvas3D& canvas); // Generates the texture with given text.
bool _generate(const std::string& msg, const GLCanvas3D& canvas);
void render(const GLCanvas3D& canvas) const;
}; };
class LegendTexture : public GUI::GLTexture class LegendTexture : public GUI::GLTexture
@ -1003,7 +1017,6 @@ public:
bool is_reload_delayed() const; bool is_reload_delayed() const;
void enable_layers_editing(bool enable); void enable_layers_editing(bool enable);
void enable_warning_texture(bool enable);
void enable_legend_texture(bool enable); void enable_legend_texture(bool enable);
void enable_picking(bool enable); void enable_picking(bool enable);
void enable_moving(bool enable); void enable_moving(bool enable);
@ -1189,8 +1202,7 @@ private:
void _generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors); void _generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
// generates a warning texture containing the given message // generates a warning texture containing the given message
void _generate_warning_texture(const std::string& msg); void _set_warning_texture(WarningTexture::Warning warning, bool state);
void _reset_warning_texture();
bool _is_any_volume_outside() const; bool _is_any_volume_outside() const;

View file

@ -1445,8 +1445,8 @@ void GLGizmoFlatten::on_render(const GLCanvas3D::Selection& selection) const
{ {
const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(); const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix();
::glPushMatrix(); ::glPushMatrix();
::glMultMatrixd(m.data());
::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z()); ::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z());
::glMultMatrixd(m.data());
if (this->is_plane_update_necessary()) if (this->is_plane_update_necessary())
const_cast<GLGizmoFlatten*>(this)->update_planes(); const_cast<GLGizmoFlatten*>(this)->update_planes();
for (int i = 0; i < (int)m_planes.size(); ++i) for (int i = 0; i < (int)m_planes.size(); ++i)
@ -1479,8 +1479,8 @@ void GLGizmoFlatten::on_render_for_picking(const GLCanvas3D::Selection& selectio
{ {
const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(); const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix();
::glPushMatrix(); ::glPushMatrix();
::glMultMatrixd(m.data());
::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z()); ::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z());
::glMultMatrixd(m.data());
if (this->is_plane_update_necessary()) if (this->is_plane_update_necessary())
const_cast<GLGizmoFlatten*>(this)->update_planes(); const_cast<GLGizmoFlatten*>(this)->update_planes();
for (int i = 0; i < (int)m_planes.size(); ++i) for (int i = 0; i < (int)m_planes.size(); ++i)
@ -2064,18 +2064,21 @@ bool GLGizmoSlaSupports::mouse_event(SLAGizmoEventType action, const Vec2d& mous
if (instance_id == -1) if (instance_id == -1)
return false; return false;
// Regardless of whether the user clicked the object or not, we will unselect all points: // If there is some selection, don't add new point and deselect everything instead.
select_point(NoPoints); if (m_selection_empty) {
Vec3f new_pos;
try {
new_pos = unproject_on_mesh(mouse_position); // this can throw - we don't want to create a new point in that case
m_editing_mode_cache.emplace_back(std::make_pair(sla::SupportPoint(new_pos, m_new_point_head_diameter/2.f, false), false));
m_unsaved_changes = true;
}
catch (...) { // not clicked on object
return true; // prevents deselection of the gizmo by GLCanvas3D
}
}
else
select_point(NoPoints);
Vec3f new_pos;
try {
new_pos = unproject_on_mesh(mouse_position); // this can throw - we don't want to create a new point in that case
m_editing_mode_cache.emplace_back(std::make_pair(sla::SupportPoint(new_pos, m_new_point_head_diameter/2.f, false), true));
m_unsaved_changes = true;
}
catch (...) { // not clicked on object
return true; // prevents deselection of the gizmo by GLCanvas3D
}
return true; return true;
} }
@ -2106,9 +2109,8 @@ bool GLGizmoSlaSupports::mouse_event(SLAGizmoEventType action, const Vec2d& mous
direction_to_camera = instance_matrix_no_translation.inverse().cast<float>() * direction_to_camera.eval(); direction_to_camera = instance_matrix_no_translation.inverse().cast<float>() * direction_to_camera.eval();
// Iterate over all points, check if they're in the rectangle and if so, check that they are not obscured by the mesh: // Iterate over all points, check if they're in the rectangle and if so, check that they are not obscured by the mesh:
for (std::pair<sla::SupportPoint, bool>& point_and_selection : m_editing_mode_cache) { for (unsigned int i=0; i<m_editing_mode_cache.size(); ++i) {
const sla::SupportPoint& support_point = point_and_selection.first; Vec3f pos = instance_matrix.cast<float>() * m_editing_mode_cache[i].first.pos;
Vec3f pos = instance_matrix.cast<float>() * support_point.pos;
pos(2) += z_offset; pos(2) += z_offset;
GLdouble out_x, out_y, out_z; GLdouble out_x, out_y, out_z;
::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z); ::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z);
@ -2118,14 +2120,14 @@ bool GLGizmoSlaSupports::mouse_event(SLAGizmoEventType action, const Vec2d& mous
bool is_obscured = false; bool is_obscured = false;
// Cast a ray in the direction of the camera and look for intersection with the mesh: // Cast a ray in the direction of the camera and look for intersection with the mesh:
std::vector<igl::Hit> hits; std::vector<igl::Hit> hits;
if (m_AABB.intersect_ray(m_V, m_F, support_point.pos, direction_to_camera, hits)) if (m_AABB.intersect_ray(m_V, m_F, m_editing_mode_cache[i].first.pos, direction_to_camera, hits))
// FIXME: the intersection could in theory be behind the camera, but as of now we only have camera direction. // FIXME: the intersection could in theory be behind the camera, but as of now we only have camera direction.
// Also, the threshold is in mesh coordinates, not in actual dimensions. // Also, the threshold is in mesh coordinates, not in actual dimensions.
if (hits.size() > 1 || hits.front().t > 0.001f) if (hits.size() > 1 || hits.front().t > 0.001f)
is_obscured = true; is_obscured = true;
if (!is_obscured) if (!is_obscured)
point_and_selection.second = true; select_point(i);
} }
} }
m_selection_rectangle_active = false; m_selection_rectangle_active = false;
@ -2170,6 +2172,8 @@ void GLGizmoSlaSupports::delete_selected_points()
// wxGetApp().plater()->reslice(); // wxGetApp().plater()->reslice();
} }
select_point(NoPoints);
//m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); //m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
} }
@ -2269,7 +2273,9 @@ RENDER_AGAIN:
m_imgui->checkbox(_(L("Lock supports under new islands")), m_lock_unique_islands); m_imgui->checkbox(_(L("Lock supports under new islands")), m_lock_unique_islands);
force_refresh |= changed != m_lock_unique_islands; force_refresh |= changed != m_lock_unique_islands;
m_imgui->disabled_begin(m_selection_empty);
remove_selected = m_imgui->button(_(L("Remove selected points"))); remove_selected = m_imgui->button(_(L("Remove selected points")));
m_imgui->disabled_end();
m_imgui->text(" "); // vertical gap m_imgui->text(" "); // vertical gap
@ -2448,10 +2454,13 @@ void GLGizmoSlaSupports::select_point(int i)
{ {
if (i == AllPoints || i == NoPoints) { if (i == AllPoints || i == NoPoints) {
for (auto& point_and_selection : m_editing_mode_cache) for (auto& point_and_selection : m_editing_mode_cache)
point_and_selection.second = ( i == AllPoints ? true : false); point_and_selection.second = ( i == AllPoints );
m_selection_empty = (i == NoPoints);
} }
else else {
m_editing_mode_cache[i].second = true; m_editing_mode_cache[i].second = true;
m_selection_empty = false;
}
} }
void GLGizmoSlaSupports::editing_mode_discard_changes() void GLGizmoSlaSupports::editing_mode_discard_changes()

View file

@ -502,6 +502,7 @@ private:
bool m_ignore_up_event = false; bool m_ignore_up_event = false;
bool m_combo_box_open = false; bool m_combo_box_open = false;
bool m_unsaved_changes = false; bool m_unsaved_changes = false;
bool m_selection_empty = true;
EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state) EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state)
#if SLAGIZMO_IMGUI_MODAL #if SLAGIZMO_IMGUI_MODAL
bool m_show_modal = false; bool m_show_modal = false;