Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/xs
diff options
context:
space:
mode:
authorEnrico Turri <enricoturri@seznam.cz>2018-06-13 14:14:17 +0300
committerEnrico Turri <enricoturri@seznam.cz>2018-06-13 14:14:17 +0300
commit099d59ad2755bb3b008bc8172c8c39107c4a1ae7 (patch)
tree23fe35bb9d075987f2ad4bf447edcabc8456d509 /xs
parentc657654c02a0490734c43dbb682c098652b2e3ac (diff)
Selection on gizmo overlay
Diffstat (limited to 'xs')
-rw-r--r--xs/src/slic3r/GUI/GLCanvas3D.cpp162
-rw-r--r--xs/src/slic3r/GUI/GLCanvas3D.hpp15
2 files changed, 116 insertions, 61 deletions
diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp
index 9ad7afeb8..e3db3af10 100644
--- a/xs/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp
@@ -564,11 +564,14 @@ GLCanvas3D::Axes::Axes()
{
}
-void GLCanvas3D::Axes::render() const
+void GLCanvas3D::Axes::render(bool depth_test) const
{
::glDisable(GL_LIGHTING);
- // disable depth testing so that axes are not covered by ground
- ::glDisable(GL_DEPTH_TEST);
+ if (depth_test)
+ ::glEnable(GL_DEPTH_TEST);
+ else
+ ::glDisable(GL_DEPTH_TEST);
+
::glLineWidth(2.0f);
::glBegin(GL_LINES);
// draw line for x axis
@@ -582,7 +585,9 @@ void GLCanvas3D::Axes::render() const
::glEnd();
// draw line for Z axis
// (re-enable depth test so that axis is correctly shown when objects are behind it)
- ::glEnable(GL_DEPTH_TEST);
+ if (!depth_test)
+ ::glEnable(GL_DEPTH_TEST);
+
::glBegin(GL_LINES);
::glColor3f(0.0f, 0.0f, 1.0f);
::glVertex3f((GLfloat)origin.x, (GLfloat)origin.y, (GLfloat)origin.z);
@@ -841,21 +846,6 @@ float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
-1000.0f;
}
-int GLCanvas3D::LayersEditing::get_first_selected_object_id(const GLVolumeCollection& volumes, unsigned int objects_count)
-{
- for (const GLVolume* vol : volumes.volumes)
- {
- if ((vol != nullptr) && vol->selected)
- {
- int object_id = vol->select_group_id / 1000000;
- // Objects with object_id >= 1000 have a specific meaning, for example the wipe tower proxy.
- if (object_id < 10000)
- return (object_id >= (int)objects_count) ? -1 : object_id;
- }
- }
- return -1;
-}
-
bool GLCanvas3D::LayersEditing::bar_rect_contains(const GLCanvas3D& canvas, float x, float y)
{
const Rect& rect = get_bar_rect_screen(canvas);
@@ -1156,19 +1146,68 @@ void GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, const Poin
float top_y = 0.5f * (cnv_h - height);
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
{
- if ((it->second == nullptr) || (it->second->get_state() == GLGizmoBase::On))
+ if (it->second == nullptr)
continue;
float tex_size = (float)it->second->get_textures_size();
float half_tex_size = 0.5f * tex_size;
// we currently use circular icons for gizmo, so we check the radius
- bool inside = length(Pointf(OverlayOffsetX + half_tex_size, top_y + half_tex_size).vector_to(mouse_pos)) < half_tex_size;
- it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off);
+ if (it->second->get_state() != GLGizmoBase::On)
+ {
+ bool inside = length(Pointf(OverlayOffsetX + half_tex_size, top_y + half_tex_size).vector_to(mouse_pos)) < half_tex_size;
+ it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off);
+ }
+ top_y += (tex_size + OverlayGapY);
+ }
+}
+
+void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Pointf& mouse_pos)
+{
+ if (!m_enabled)
+ return;
+
+ float cnv_h = (float)canvas.get_canvas_size().get_height();
+ float height = _get_total_overlay_height();
+ float top_y = 0.5f * (cnv_h - height);
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if (it->second == nullptr)
+ continue;
+
+ float tex_size = (float)it->second->get_textures_size();
+ float half_tex_size = 0.5f * tex_size;
+
+ // we currently use circular icons for gizmo, so we check the radius
+ if (length(Pointf(OverlayOffsetX + half_tex_size, top_y + half_tex_size).vector_to(mouse_pos)) < half_tex_size)
+ it->second->set_state((it->second->get_state() == GLGizmoBase::On) ? GLGizmoBase::Off : GLGizmoBase::On);
+ else
+ it->second->set_state(GLGizmoBase::Off);
+
top_y += (tex_size + OverlayGapY);
}
}
+void GLCanvas3D::Gizmos::reset_all_states()
+{
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if (it->second != nullptr)
+ it->second->set_state(GLGizmoBase::Off);
+ }
+}
+
+bool GLCanvas3D::Gizmos::contains_mouse() const
+{
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if ((it->second != nullptr) && (it->second->get_state() == GLGizmoBase::Hover))
+ return true;
+ }
+
+ return false;
+}
+
void GLCanvas3D::Gizmos::render(const GLCanvas3D& canvas) const
{
if (!m_enabled)
@@ -1696,14 +1735,15 @@ void GLCanvas3D::render()
if (is_custom_bed)
{
_render_bed(theta);
- _render_axes();
+ // disable depth testing so that axes are not covered by ground
+ _render_axes(false);
}
_render_objects();
// textured bed needs to be rendered after objects
if (!is_custom_bed)
{
+ _render_axes(true);
_render_bed(theta);
- _render_axes();
}
_render_cutting_plane();
_render_warning_texture();
@@ -2439,13 +2479,13 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt)
return;
// Performs layers editing updates, if enabled
- if (is_layers_editing_enabled() && (m_print != nullptr))
+ if (is_layers_editing_enabled())
{
- int object_idx_selected = _get_layers_editing_first_selected_object_id((unsigned int)m_print->objects.size());
+ int object_idx_selected = _get_first_selected_object_id();
if (object_idx_selected != -1)
{
// A volume is selected. Test, whether hovering over a layer thickness bar.
- if (_bar_rect_contains((float)evt.GetX(), (float)evt.GetY()))
+ if (m_layers_editing.bar_rect_contains(*this, (float)evt.GetX(), (float)evt.GetY()))
{
// Adjust the width of the selection.
m_layers_editing.band_width = std::max(std::min(m_layers_editing.band_width * (1.0f + 0.1f * (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta()), 10.0f), 1.5f);
@@ -2485,8 +2525,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
{
Point pos(evt.GetX(), evt.GetY());
- int selected_object_idx = (is_layers_editing_enabled() && (m_print != nullptr)) ? _get_layers_editing_first_selected_object_id(m_print->objects.size()) : -1;
- m_layers_editing.last_object_id = selected_object_idx;
+ int selected_object_idx = _get_first_selected_object_id();
+ int layer_editing_object_idx = is_layers_editing_enabled() ? selected_object_idx : -1;
+ m_layers_editing.last_object_id = layer_editing_object_idx;
+ bool gizmos_contains_mouse = m_gizmos.contains_mouse();
if (evt.Entering())
{
@@ -2506,25 +2548,30 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
// on a volume or not.
int volume_idx = m_hover_volume_id;
m_layers_editing.state = LayersEditing::Unknown;
- if ((selected_object_idx != -1) && _bar_rect_contains(pos.x, pos.y))
+ if ((layer_editing_object_idx != -1) && m_layers_editing.bar_rect_contains(*this, pos.x, pos.y))
{
// A volume is selected and the mouse is inside the layer thickness bar.
// Start editing the layer height.
m_layers_editing.state = LayersEditing::Editing;
_perform_layer_editing_action(&evt);
}
- else if ((selected_object_idx != -1) && _reset_rect_contains(pos.x, pos.y))
+ else if ((layer_editing_object_idx != -1) && m_layers_editing.reset_rect_contains(*this, pos.x, pos.y))
{
if (evt.LeftDown())
{
// A volume is selected and the mouse is inside the reset button.
- m_print->get_object(selected_object_idx)->reset_layer_height_profile();
+ m_print->get_object(layer_editing_object_idx)->reset_layer_height_profile();
// Index 2 means no editing, just wait for mouse up event.
m_layers_editing.state = LayersEditing::Completed;
m_dirty = true;
}
}
+ else if ((selected_object_idx != -1) && gizmos_contains_mouse)
+ {
+ m_gizmos.update_on_off_state(*this, m_mouse.position);
+ m_dirty = true;
+ }
else
{
// Select volume in this 3D canvas.
@@ -2586,7 +2633,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
}
}
- else if (evt.Dragging() && evt.LeftIsDown() && (m_layers_editing.state == LayersEditing::Unknown) && (m_mouse.drag.volume_idx != -1))
+ else if (evt.Dragging() && evt.LeftIsDown() && !gizmos_contains_mouse && (m_layers_editing.state == LayersEditing::Unknown) && (m_mouse.drag.volume_idx != -1))
{
m_mouse.dragging = true;
@@ -2633,11 +2680,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_dirty = true;
}
- else if (evt.Dragging())
+ else if (evt.Dragging() && !gizmos_contains_mouse)
{
m_mouse.dragging = true;
- if ((m_layers_editing.state != LayersEditing::Unknown) && (selected_object_idx != -1))
+ if ((m_layers_editing.state != LayersEditing::Unknown) && (layer_editing_object_idx != -1))
{
if (m_layers_editing.state == LayersEditing::Editing)
_perform_layer_editing_action(&evt);
@@ -2685,7 +2732,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_layers_editing.state = LayersEditing::Unknown;
_stop_timer();
- if (selected_object_idx != -1)
+ if (layer_editing_object_idx != -1)
m_on_model_update_callback.call();
}
else if ((m_mouse.drag.volume_idx != -1) && m_mouse.dragging)
@@ -3050,8 +3097,10 @@ void GLCanvas3D::_picking_pass() const
}
// updates gizmos overlay
- if (!m_volumes.empty())
+ if (_get_first_selected_object_id() != -1)
m_gizmos.update_hover_state(*this, pos);
+ else
+ m_gizmos.reset_all_states();
}
}
@@ -3093,9 +3142,9 @@ void GLCanvas3D::_render_bed(float theta) const
m_bed.render(theta);
}
-void GLCanvas3D::_render_axes() const
+void GLCanvas3D::_render_axes(bool depth_test) const
{
- m_axes.render();
+ m_axes.render(depth_test);
}
void GLCanvas3D::_render_objects() const
@@ -3302,11 +3351,6 @@ float GLCanvas3D::_get_layers_editing_cursor_z_relative() const
return m_layers_editing.get_cursor_z_relative(*this);
}
-int GLCanvas3D::_get_layers_editing_first_selected_object_id(unsigned int objects_count) const
-{
- return m_layers_editing.get_first_selected_object_id(m_volumes, objects_count);
-}
-
void GLCanvas3D::_perform_layer_editing_action(wxMouseEvent* evt)
{
int object_idx_selected = m_layers_editing.last_object_id;
@@ -3355,16 +3399,6 @@ void GLCanvas3D::_perform_layer_editing_action(wxMouseEvent* evt)
_start_timer();
}
-bool GLCanvas3D::_bar_rect_contains(float x, float y) const
-{
- return m_layers_editing.bar_rect_contains(*this, x, y);
-}
-
-bool GLCanvas3D::_reset_rect_contains(float x, float y) const
-{
- return m_layers_editing.reset_rect_contains(*this, x, y);
-}
-
Pointf3 GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z)
{
if (!set_current())
@@ -3401,6 +3435,26 @@ void GLCanvas3D::_stop_timer()
m_timer->Stop();
}
+int GLCanvas3D::_get_first_selected_object_id() const
+{
+ if (m_print != nullptr)
+ {
+ int objects_count = (int)m_print->objects.size();
+
+ for (const GLVolume* vol : m_volumes.volumes)
+ {
+ if ((vol != nullptr) && vol->selected)
+ {
+ int object_id = vol->select_group_id / 1000000;
+ // Objects with object_id >= 1000 have a specific meaning, for example the wipe tower proxy.
+ if (object_id < 10000)
+ return (object_id >= objects_count) ? -1 : object_id;
+ }
+ }
+ }
+ return -1;
+}
+
static inline int hex_digit_to_int(const char c)
{
return
diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp
index 2852d82d1..738df637c 100644
--- a/xs/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp
@@ -189,7 +189,7 @@ public:
Axes();
- void render() const;
+ void render(bool depth_test) const;
};
class CuttingPlane
@@ -277,7 +277,6 @@ public:
int get_shader_program_id() const;
static float get_cursor_z_relative(const GLCanvas3D& canvas);
- static int get_first_selected_object_id(const GLVolumeCollection& volumes, unsigned int objects_count);
static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y);
static bool reset_rect_contains(const GLCanvas3D& canvas, float x, float y);
static Rect get_bar_rect_screen(const GLCanvas3D& canvas);
@@ -355,6 +354,10 @@ public:
void reset_selection();
void update_hover_state(const GLCanvas3D& canvas, const Pointf& mouse_pos);
+ void update_on_off_state(const GLCanvas3D& canvas, const Pointf& mouse_pos);
+ void reset_all_states();
+
+ bool contains_mouse() const;
void render(const GLCanvas3D& canvas) const;
@@ -567,7 +570,7 @@ private:
void _picking_pass() const;
void _render_background() const;
void _render_bed(float theta) const;
- void _render_axes() const;
+ void _render_axes(bool depth_test) const;
void _render_objects() const;
void _render_cutting_plane() const;
void _render_warning_texture() const;
@@ -577,12 +580,8 @@ private:
void _render_gizmo() const;
float _get_layers_editing_cursor_z_relative() const;
- int _get_layers_editing_first_selected_object_id(unsigned int objects_count) const;
void _perform_layer_editing_action(wxMouseEvent* evt = nullptr);
- bool _bar_rect_contains(float x, float y) const;
- bool _reset_rect_contains(float x, float y) const;
-
// Convert the screen space coordinate to an object space coordinate.
// If the Z screen space coordinate is not provided, a depth buffer value is substituted.
Pointf3 _mouse_to_3d(const Point& mouse_pos, float* z = nullptr);
@@ -590,6 +589,8 @@ private:
void _start_timer();
void _stop_timer();
+ int _get_first_selected_object_id() const;
+
// generates gcode extrusion paths geometry
void _load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
// generates gcode travel paths geometry