Merge branch 'lm_gizmomanagerrefactoring' into dev

This commit is contained in:
Lukas Matena 2019-09-03 08:29:31 +02:00
commit b89d9c7aff
7 changed files with 194 additions and 412 deletions

View file

@ -69,7 +69,6 @@ public:
enum EState enum EState
{ {
Off, Off,
Hover,
On, On,
Num_States Num_States
}; };

View file

@ -44,12 +44,12 @@ public:
Vec3d get_flattening_normal() const; Vec3d get_flattening_normal() const;
protected: protected:
virtual bool on_init(); virtual bool on_init() override;
virtual std::string on_get_name() const; virtual std::string on_get_name() const override;
virtual bool on_is_activable() const; virtual bool on_is_activable() const override;
virtual void on_start_dragging(); virtual void on_start_dragging() override;
virtual void on_render() const; virtual void on_render() const override;
virtual void on_render_for_picking() const; virtual void on_render_for_picking() const override;
virtual void on_set_state() override; virtual void on_set_state() override;
}; };

View file

@ -87,16 +87,12 @@ protected:
virtual void on_set_state() virtual void on_set_state()
{ {
for (GLGizmoRotate& g : m_gizmos) for (GLGizmoRotate& g : m_gizmos)
{
g.set_state(m_state); g.set_state(m_state);
}
} }
virtual void on_set_hover_id() virtual void on_set_hover_id()
{ {
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
{
m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1); m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1);
}
} }
virtual void on_enable_grabber(unsigned int id) virtual void on_enable_grabber(unsigned int id)
{ {

View file

@ -12,6 +12,7 @@
#include "slic3r/GUI/GUI.hpp" #include "slic3r/GUI/GUI.hpp"
#include "slic3r/GUI/GUI_ObjectSettings.hpp" #include "slic3r/GUI/GUI_ObjectSettings.hpp"
#include "slic3r/GUI/GUI_ObjectList.hpp" #include "slic3r/GUI/GUI_ObjectList.hpp"
#include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/PresetBundle.hpp" #include "slic3r/GUI/PresetBundle.hpp"
#include "libslic3r/SLAPrint.hpp" #include "libslic3r/SLAPrint.hpp"
#include "libslic3r/Tesselate.hpp" #include "libslic3r/Tesselate.hpp"
@ -1099,9 +1100,6 @@ std::string GLGizmoSlaSupports::on_get_name() const
void GLGizmoSlaSupports::on_set_state() void GLGizmoSlaSupports::on_set_state()
{ {
if (m_state == Hover)
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;
@ -1112,6 +1110,11 @@ void GLGizmoSlaSupports::on_set_state()
} }
} }
if (m_state == m_old_state)
return;
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo on/off")));
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("SLA gizmo turned on")));
if (is_mesh_update_necessary()) if (is_mesh_update_necessary())

View file

@ -157,6 +157,7 @@ private:
protected: protected:
void on_set_state() override; void on_set_state() override;
void on_set_hover_id() override void on_set_hover_id() override
{ {
if (! m_editing_mode || (int)m_editing_cache.size() <= m_hover_id) if (! m_editing_mode || (int)m_editing_cache.size() <= m_hover_id)
m_hover_id = -1; m_hover_id = -1;

View file

@ -29,9 +29,49 @@ GLGizmosManager::GLGizmosManager(GLCanvas3D& parent)
{ {
} }
GLGizmosManager::~GLGizmosManager() std::vector<size_t> GLGizmosManager::get_selectable_idxs() const
{ {
reset(); std::vector<size_t> out;
for (size_t i=0; i<m_gizmos.size(); ++i)
if (m_gizmos[i]->is_selectable())
out.push_back(i);
return out;
}
std::vector<size_t> GLGizmosManager::get_activable_idxs() const
{
std::vector<size_t> out;
for (size_t i=0; i<m_gizmos.size(); ++i)
if (m_gizmos[i]->is_activable())
out.push_back(i);
return out;
}
size_t GLGizmosManager::get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const
{
if (! m_enabled)
return Undefined;
float cnv_h = (float)m_parent.get_canvas_size().get_height();
float height = get_total_overlay_height();
float scaled_icons_size = m_overlay_icons_size * m_overlay_scale;
float scaled_border = m_overlay_border * m_overlay_scale;
float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
float scaled_stride_y = scaled_icons_size + scaled_gap_y;
float top_y = 0.5f * (cnv_h - height) + scaled_border;
// is mouse horizontally in the area?
if ((scaled_border <= (float)mouse_pos(0) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size))) {
// which icon is it on?
size_t from_top = (size_t)((float)mouse_pos(1) - top_y)/scaled_stride_y;
// is it really on the icon or already past the border?
if ((float)mouse_pos(1) <= top_y + from_top*scaled_stride_y + scaled_icons_size) {
std::vector<size_t> selectable = get_selectable_idxs();
if (from_top < selectable.size())
return selectable[from_top];
}
}
return Undefined;
} }
bool GLGizmosManager::init() bool GLGizmosManager::init()
@ -45,77 +85,25 @@ bool GLGizmosManager::init()
if (!m_background_texture.metadata.filename.empty()) if (!m_background_texture.metadata.filename.empty())
{ {
if (!m_background_texture.texture.load_from_file(resources_dir() + "/icons/" + m_background_texture.metadata.filename, false, GLTexture::SingleThreaded, false)) if (!m_background_texture.texture.load_from_file(resources_dir() + "/icons/" + m_background_texture.metadata.filename, false, GLTexture::SingleThreaded, false))
{ return false;
reset(); }
m_gizmos.emplace_back(new GLGizmoMove3D(m_parent, "move.svg", 0));
m_gizmos.emplace_back(new GLGizmoScale3D(m_parent, "scale.svg", 1));
m_gizmos.emplace_back(new GLGizmoRotate3D(m_parent, "rotate.svg", 2));
m_gizmos.emplace_back(new GLGizmoFlatten(m_parent, "place.svg", 3));
m_gizmos.emplace_back(new GLGizmoCut(m_parent, "cut.svg", 4));
m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 5));
for (auto& gizmo : m_gizmos) {
if (! gizmo->init()) {
m_gizmos.clear();
return false; return false;
} }
} }
GLGizmoBase* gizmo = new GLGizmoMove3D(m_parent, "move.svg", 0); m_current = Undefined;
if (gizmo == nullptr) m_hover = Undefined;
return false;
if (!gizmo->init())
return false;
m_gizmos.insert(GizmosMap::value_type(Move, gizmo));
gizmo = new GLGizmoScale3D(m_parent, "scale.svg", 1);
if (gizmo == nullptr)
return false;
if (!gizmo->init())
return false;
m_gizmos.insert(GizmosMap::value_type(Scale, gizmo));
gizmo = new GLGizmoRotate3D(m_parent, "rotate.svg", 2);
if (gizmo == nullptr)
{
reset();
return false;
}
if (!gizmo->init())
{
reset();
return false;
}
m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo));
gizmo = new GLGizmoFlatten(m_parent, "place.svg", 3);
if (gizmo == nullptr)
return false;
if (!gizmo->init()) {
reset();
return false;
}
m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo));
gizmo = new GLGizmoCut(m_parent, "cut.svg", 4);
if (gizmo == nullptr)
return false;
if (!gizmo->init()) {
reset();
return false;
}
m_gizmos.insert(GizmosMap::value_type(Cut, gizmo));
gizmo = new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 5);
if (gizmo == nullptr)
return false;
if (!gizmo->init()) {
reset();
return false;
}
m_gizmos.insert(GizmosMap::value_type(SlaSupports, gizmo));
return true; return true;
} }
@ -140,65 +128,39 @@ void GLGizmosManager::set_overlay_scale(float scale)
void GLGizmosManager::refresh_on_off_state() void GLGizmosManager::refresh_on_off_state()
{ {
if (m_serializing) if (m_serializing || m_current == Undefined || m_gizmos.empty())
return; return;
GizmosMap::iterator it = m_gizmos.find(m_current); if (m_current != Undefined && ! m_gizmos[m_current]->is_activable())
if ((it != m_gizmos.end()) && (it->second != nullptr)) activate_gizmo(Undefined);
{
if (!it->second->is_activable())
{
it->second->set_state(GLGizmoBase::Off);
m_current = Undefined;
}
}
} }
void GLGizmosManager::reset_all_states() void GLGizmosManager::reset_all_states()
{ {
if (!m_enabled) if (! m_enabled || m_serializing)
return; return;
if (m_serializing) activate_gizmo(Undefined);
return; m_hover = Undefined;
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
{
if (it->second != nullptr)
{
it->second->set_state(GLGizmoBase::Off);
it->second->set_hover_id(-1);
}
}
m_current = Undefined;
} }
void GLGizmosManager::set_hover_id(int id) void GLGizmosManager::set_hover_id(int id)
{ {
if (!m_enabled) if (!m_enabled || m_current == Undefined)
return; return;
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) m_gizmos[m_current]->set_hover_id(id);
{
if ((it->second != nullptr) && (it->second->get_state() == GLGizmoBase::On))
it->second->set_hover_id(id);
}
} }
void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable) void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable)
{ {
if (!m_enabled) if (!m_enabled || type == Undefined || m_gizmos.empty())
return; return;
GizmosMap::const_iterator it = m_gizmos.find(type); if (enable)
if (it != m_gizmos.end()) m_gizmos[type]->enable_grabber(id);
{ else
if (enable) m_gizmos[type]->disable_grabber(id);
it->second->enable_grabber(id);
else
it->second->disable_grabber(id);
}
} }
void GLGizmosManager::update(const Linef3& mouse_ray, const Point& mouse_pos) void GLGizmosManager::update(const Linef3& mouse_ray, const Point& mouse_pos)
@ -269,8 +231,9 @@ bool GLGizmosManager::is_running() const
if (!m_enabled) if (!m_enabled)
return false; return false;
GLGizmoBase* curr = get_current(); //GLGizmoBase* curr = get_current();
return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false; //return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false;
return m_current != Undefined;
} }
bool GLGizmosManager::handle_shortcut(int key) bool GLGizmosManager::handle_shortcut(int key)
@ -283,43 +246,12 @@ bool GLGizmosManager::handle_shortcut(int key)
bool handled = false; bool handled = false;
for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) for (size_t idx : get_selectable_idxs()) {
{ int it_key = m_gizmos[idx]->get_shortcut_key();
if ((it->second == nullptr) || !it->second->is_selectable())
continue;
int it_key = it->second->get_shortcut_key(); if (m_gizmos[idx]->is_activable() && ((it_key == key - 64) || (it_key == key - 96))) {
activate_gizmo(m_current == idx ? Undefined : (EType)idx);
if (it->second->is_activable() && ((it_key == key - 64) || (it_key == key - 96)))
{
if ((it->second->get_state() == GLGizmoBase::On))
{
it->second->set_state(GLGizmoBase::Off);
if (it->second->get_state() == GLGizmoBase::Off) {
m_current = Undefined;
}
handled = true; handled = true;
}
else if ((it->second->get_state() == GLGizmoBase::Off))
{
// Before turning anything on, turn everything else off to see if
// nobody refuses. Only then activate the gizmo.
bool can_open = true;
for (GizmosMap::iterator i = m_gizmos.begin(); i != m_gizmos.end(); ++i) {
if (i->first != it->first) {
if (m_current == i->first && i->second->get_state() != GLGizmoBase::Off ) {
i->second->set_state(GLGizmoBase::Off);
if (i->second->get_state() != GLGizmoBase::Off)
can_open = false;
}
}
}
if (can_open) {
it->second->set_state(GLGizmoBase::On);
m_current = it->first;
}
handled = true;
}
} }
} }
@ -328,31 +260,25 @@ bool GLGizmosManager::handle_shortcut(int key)
bool GLGizmosManager::is_dragging() const bool GLGizmosManager::is_dragging() const
{ {
if (!m_enabled) if (! m_enabled || m_current == Undefined)
return false; return false;
GLGizmoBase* curr = get_current(); return m_gizmos[m_current]->is_dragging();
return (curr != nullptr) ? curr->is_dragging() : false;
} }
void GLGizmosManager::start_dragging() void GLGizmosManager::start_dragging()
{ {
if (!m_enabled) if (! m_enabled || m_current == Undefined)
return; return;
m_gizmos[m_current]->start_dragging();
GLGizmoBase* curr = get_current();
if (curr != nullptr)
curr->start_dragging();
} }
void GLGizmosManager::stop_dragging() void GLGizmosManager::stop_dragging()
{ {
if (!m_enabled) if (! m_enabled || m_current == Undefined)
return; return;
GLGizmoBase* curr = get_current(); m_gizmos[m_current]->stop_dragging();
if (curr != nullptr)
curr->stop_dragging();
} }
Vec3d GLGizmosManager::get_displacement() const Vec3d GLGizmosManager::get_displacement() const
@ -360,8 +286,7 @@ Vec3d GLGizmosManager::get_displacement() const
if (!m_enabled) if (!m_enabled)
return Vec3d::Zero(); return Vec3d::Zero();
GizmosMap::const_iterator it = m_gizmos.find(Move); return dynamic_cast<GLGizmoMove3D*>(m_gizmos[Move].get())->get_displacement();
return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoMove3D*>(it->second)->get_displacement() : Vec3d::Zero();
} }
Vec3d GLGizmosManager::get_scale() const Vec3d GLGizmosManager::get_scale() const
@ -369,126 +294,101 @@ Vec3d GLGizmosManager::get_scale() const
if (!m_enabled) if (!m_enabled)
return Vec3d::Ones(); return Vec3d::Ones();
GizmosMap::const_iterator it = m_gizmos.find(Scale); return dynamic_cast<GLGizmoScale3D*>(m_gizmos[Scale].get())->get_scale();
return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoScale3D*>(it->second)->get_scale() : Vec3d::Ones();
} }
void GLGizmosManager::set_scale(const Vec3d& scale) void GLGizmosManager::set_scale(const Vec3d& scale)
{ {
if (!m_enabled) if (!m_enabled || m_gizmos.empty())
return; return;
GizmosMap::const_iterator it = m_gizmos.find(Scale); dynamic_cast<GLGizmoScale3D*>(m_gizmos[Scale].get())->set_scale(scale);
if (it != m_gizmos.end())
reinterpret_cast<GLGizmoScale3D*>(it->second)->set_scale(scale);
} }
Vec3d GLGizmosManager::get_scale_offset() const Vec3d GLGizmosManager::get_scale_offset() const
{ {
if (!m_enabled) if (!m_enabled || m_gizmos.empty())
return Vec3d::Zero(); return Vec3d::Zero();
GizmosMap::const_iterator it = m_gizmos.find(Scale); return dynamic_cast<GLGizmoScale3D*>(m_gizmos[Scale].get())->get_offset();
return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoScale3D*>(it->second)->get_offset() : Vec3d::Zero();
} }
Vec3d GLGizmosManager::get_rotation() const Vec3d GLGizmosManager::get_rotation() const
{ {
if (!m_enabled) if (!m_enabled || m_gizmos.empty())
return Vec3d::Zero(); return Vec3d::Zero();
GizmosMap::const_iterator it = m_gizmos.find(Rotate); return dynamic_cast<GLGizmoRotate3D*>(m_gizmos[Rotate].get())->get_rotation();
return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoRotate3D*>(it->second)->get_rotation() : Vec3d::Zero();
} }
void GLGizmosManager::set_rotation(const Vec3d& rotation) void GLGizmosManager::set_rotation(const Vec3d& rotation)
{ {
if (!m_enabled) if (!m_enabled || m_gizmos.empty())
return; return;
dynamic_cast<GLGizmoRotate3D*>(m_gizmos[Rotate].get())->set_rotation(rotation);
GizmosMap::const_iterator it = m_gizmos.find(Rotate);
if (it != m_gizmos.end())
reinterpret_cast<GLGizmoRotate3D*>(it->second)->set_rotation(rotation);
} }
Vec3d GLGizmosManager::get_flattening_normal() const Vec3d GLGizmosManager::get_flattening_normal() const
{ {
if (!m_enabled) if (!m_enabled || m_gizmos.empty())
return Vec3d::Zero(); return Vec3d::Zero();
GizmosMap::const_iterator it = m_gizmos.find(Flatten); return dynamic_cast<GLGizmoFlatten*>(m_gizmos[Flatten].get())->get_flattening_normal();
return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoFlatten*>(it->second)->get_flattening_normal() : Vec3d::Zero();
} }
void GLGizmosManager::set_flattening_data(const ModelObject* model_object) void GLGizmosManager::set_flattening_data(const ModelObject* model_object)
{ {
if (!m_enabled) if (!m_enabled || m_gizmos.empty())
return; return;
GizmosMap::const_iterator it = m_gizmos.find(Flatten); dynamic_cast<GLGizmoFlatten*>(m_gizmos[Flatten].get())->set_flattening_data(model_object);
if (it != m_gizmos.end())
reinterpret_cast<GLGizmoFlatten*>(it->second)->set_flattening_data(model_object);
} }
void GLGizmosManager::set_sla_support_data(ModelObject* model_object) void GLGizmosManager::set_sla_support_data(ModelObject* model_object)
{ {
if (!m_enabled) if (!m_enabled || m_gizmos.empty())
return; return;
GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->set_sla_support_data(model_object, m_parent.get_selection());
if (it != m_gizmos.end())
reinterpret_cast<GLGizmoSlaSupports*>(it->second)->set_sla_support_data(model_object, m_parent.get_selection());
} }
// Returns true if the gizmo used the event to do something, false otherwise. // Returns true if the gizmo used the event to do something, false otherwise.
bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down)
{ {
if (!m_enabled) if (!m_enabled || m_gizmos.empty())
return false; return false;
GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); return dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
if (it != m_gizmos.end())
return reinterpret_cast<GLGizmoSlaSupports*>(it->second)->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
return false;
} }
ClippingPlane GLGizmosManager::get_sla_clipping_plane() const ClippingPlane GLGizmosManager::get_sla_clipping_plane() const
{ {
if (!m_enabled || m_current != SlaSupports) if (!m_enabled || m_current != SlaSupports || m_gizmos.empty())
return ClippingPlane::ClipsNothing(); return ClippingPlane::ClipsNothing();
GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); return dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->get_sla_clipping_plane();
if (it != m_gizmos.end())
return reinterpret_cast<GLGizmoSlaSupports*>(it->second)->get_sla_clipping_plane();
return ClippingPlane::ClipsNothing();
} }
bool GLGizmosManager::wants_reslice_supports_on_undo() const bool GLGizmosManager::wants_reslice_supports_on_undo() const
{ {
return (m_current == SlaSupports return (m_current == SlaSupports
&& dynamic_cast<const GLGizmoSlaSupports*>(m_gizmos.at(SlaSupports))->has_backend_supports()); && dynamic_cast<const GLGizmoSlaSupports*>(m_gizmos.at(SlaSupports).get())->has_backend_supports());
} }
void GLGizmosManager::render_current_gizmo() const void GLGizmosManager::render_current_gizmo() const
{ {
if (!m_enabled) if (!m_enabled || m_current == Undefined)
return; return;
GLGizmoBase* curr = get_current(); m_gizmos[m_current]->render();
if (curr != nullptr)
curr->render();
} }
void GLGizmosManager::render_current_gizmo_for_picking_pass() const void GLGizmosManager::render_current_gizmo_for_picking_pass() const
{ {
if (!m_enabled) if (! m_enabled || m_current == Undefined)
return; return;
GLGizmoBase* curr = get_current(); m_gizmos[m_current]->render_for_picking();
if (curr != nullptr)
curr->render_for_picking();
} }
void GLGizmosManager::render_overlay() const void GLGizmosManager::render_overlay() const
@ -547,7 +447,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
// if the button down was done on this toolbar, prevent from dragging into the scene // if the button down was done on this toolbar, prevent from dragging into the scene
processed = true; processed = true;
if (!overlay_contains_mouse(mouse_pos)) if (get_gizmo_idx_from_mouse(mouse_pos) == Undefined)
{ {
// mouse is outside the toolbar // mouse is outside the toolbar
m_tooltip = ""; m_tooltip = "";
@ -557,14 +457,12 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown())) if ((m_current == SlaSupports) && 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()) {
{
update_data(); update_data();
selection.start_dragging(); selection.start_dragging();
start_dragging(); start_dragging();
if (m_current == Flatten) if (m_current == Flatten) {
{
// Rotate the object so the normal points downward: // Rotate the object so the normal points downward:
m_parent.do_flatten(get_flattening_normal(), L("Gizmo-Place on Face")); m_parent.do_flatten(get_flattening_normal(), L("Gizmo-Place on Face"));
wxGetApp().obj_manipul()->set_dirty(); wxGetApp().obj_manipul()->set_dirty();
@ -634,25 +532,14 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
} }
else if (evt.LeftUp() && is_dragging()) else if (evt.LeftUp() && is_dragging())
{ {
switch (m_current) switch (m_current) {
{ case Move : m_parent.do_move(L("Gizmo-Move"));
case Move: break;
{ case Scale : m_parent.do_scale(L("Gizmo-Scale"));
m_parent.do_move(L("Gizmo-Move")); break;
break; case Rotate : m_parent.do_rotate(L("Gizmo-Rotate"));
} break;
case Scale: default : break;
{
m_parent.do_scale(L("Gizmo-Scale"));
break;
}
case Rotate:
{
m_parent.do_rotate(L("Gizmo-Rotate"));
break;
}
default:
break;
} }
stop_dragging(); stop_dragging();
@ -842,7 +729,7 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
{ {
if (m_current == SlaSupports) if (m_current == SlaSupports)
{ {
GLGizmoSlaSupports* gizmo = reinterpret_cast<GLGizmoSlaSupports*>(get_current()); GLGizmoSlaSupports* gizmo = dynamic_cast<GLGizmoSlaSupports*>(get_current());
if (keyCode == WXK_SHIFT) if (keyCode == WXK_SHIFT)
{ {
@ -863,7 +750,8 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
} }
else if (evt.GetEventType() == wxEVT_KEY_DOWN) else if (evt.GetEventType() == wxEVT_KEY_DOWN)
{ {
if ((m_current == SlaSupports) && ((keyCode == WXK_SHIFT) || (keyCode == WXK_ALT)) && reinterpret_cast<GLGizmoSlaSupports*>(get_current())->is_in_editing_mode()) if ((m_current == SlaSupports) && ((keyCode == WXK_SHIFT) || (keyCode == WXK_ALT))
&& dynamic_cast<GLGizmoSlaSupports*>(get_current())->is_in_editing_mode())
{ {
// m_parent.set_cursor(GLCanvas3D::Cross); // m_parent.set_cursor(GLCanvas3D::Cross);
processed = true; processed = true;
@ -882,18 +770,7 @@ void GLGizmosManager::update_after_undo_redo(const UndoRedo::Snapshot& snapshot)
m_serializing = false; m_serializing = false;
if (m_current == SlaSupports if (m_current == SlaSupports
&& snapshot.snapshot_data.flags & UndoRedo::SnapshotData::RECALCULATE_SLA_SUPPORTS) && snapshot.snapshot_data.flags & UndoRedo::SnapshotData::RECALCULATE_SLA_SUPPORTS)
dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports])->reslice_SLA_supports(true); dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->reslice_SLA_supports(true);
}
void GLGizmosManager::reset()
{
for (GizmosMap::value_type& gizmo : m_gizmos)
{
delete gizmo.second;
gizmo.second = nullptr;
}
m_gizmos.clear();
} }
void GLGizmosManager::render_background(float left, float top, float right, float bottom, float border) const void GLGizmosManager::render_background(float left, float top, float right, float bottom, float border) const
@ -911,7 +788,7 @@ void GLGizmosManager::render_background(float left, float top, float right, floa
float internal_top = top - border; float internal_top = top - border;
float internal_bottom = bottom + border; float internal_bottom = bottom + border;
float left_uv = 0.0f; // float left_uv = 0.0f;
float right_uv = 1.0f; float right_uv = 1.0f;
float top_uv = 1.0f; float top_uv = 1.0f;
float bottom_uv = 0.0f; float bottom_uv = 0.0f;
@ -981,33 +858,32 @@ void GLGizmosManager::do_render_overlay() const
float scaled_icons_size = m_overlay_icons_size * m_overlay_scale * inv_zoom; float scaled_icons_size = m_overlay_icons_size * m_overlay_scale * inv_zoom;
float scaled_stride_y = scaled_icons_size + scaled_gap_y; float scaled_stride_y = scaled_icons_size + scaled_gap_y;
unsigned int icons_texture_id = m_icons_texture.get_id(); unsigned int icons_texture_id = m_icons_texture.get_id();
unsigned int tex_width = m_icons_texture.get_width(); int tex_width = m_icons_texture.get_width();
unsigned int tex_height = m_icons_texture.get_height(); int tex_height = m_icons_texture.get_height();
float inv_tex_width = (tex_width != 0) ? 1.0f / (float)tex_width : 0.0f; float inv_tex_width = (tex_width != 0) ? 1.0f / tex_width : 0.0f;
float inv_tex_height = (tex_height != 0) ? 1.0f / (float)tex_height : 0.0f; float inv_tex_height = (tex_height != 0) ? 1.0f / tex_height : 0.0f;
if ((icons_texture_id == 0) || (tex_width <= 0) || (tex_height <= 0)) if ((icons_texture_id == 0) || (tex_width <= 0) || (tex_height <= 0))
return; return;
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) for (size_t idx : get_selectable_idxs())
{ {
if ((it->second == nullptr) || !it->second->is_selectable()) GLGizmoBase* gizmo = m_gizmos[idx].get();
continue;
unsigned int sprite_id = it->second->get_sprite_id(); unsigned int sprite_id = gizmo->get_sprite_id();
GLGizmoBase::EState state = it->second->get_state(); int icon_idx = m_current == idx ? 2 : (m_hover == idx ? 1 : 0);
float u_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_width; float u_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_width;
float v_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_height; float v_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_height;
float v_top = sprite_id * v_icon_size; float v_top = sprite_id * v_icon_size;
float u_left = state * u_icon_size; float u_left = icon_idx * u_icon_size;
float v_bottom = v_top + v_icon_size; float v_bottom = v_top + v_icon_size;
float u_right = u_left + u_icon_size; float u_right = u_left + u_icon_size;
GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } });
if (it->second->get_state() == GLGizmoBase::On) { if (idx == m_current) {
float toolbar_top = (float)cnv_h - m_parent.get_view_toolbar_height(); float toolbar_top = cnv_h - m_parent.get_view_toolbar_height();
it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top); gizmo->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top);
} }
top_y -= scaled_stride_y; top_y -= scaled_stride_y;
} }
@ -1021,13 +897,14 @@ float GLGizmosManager::get_total_overlay_height() const
float scaled_stride_y = scaled_icons_size + scaled_gap_y; float scaled_stride_y = scaled_icons_size + scaled_gap_y;
float height = 2.0f * scaled_border; float height = 2.0f * scaled_border;
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) /*for (size_t idx=0; idx<m_gizmos.size(); ++idx)
{ {
if ((it->second == nullptr) || !it->second->is_selectable()) if ((m_gizmos[idx] == nullptr) || !m_gizmos[idx]->is_selectable())
continue; continue;
height += scaled_stride_y; height += scaled_stride_y;
} }*/
height += get_selectable_idxs().size() * scaled_stride_y;
return height - scaled_gap_y; return height - scaled_gap_y;
} }
@ -1039,19 +916,21 @@ float GLGizmosManager::get_total_overlay_width() const
GLGizmoBase* GLGizmosManager::get_current() const GLGizmoBase* GLGizmosManager::get_current() const
{ {
GizmosMap::const_iterator it = m_gizmos.find(m_current); if (m_current==Undefined || m_gizmos.empty())
return (it != m_gizmos.end()) ? it->second : nullptr; return nullptr;
else
return m_gizmos[m_current].get();
} }
bool GLGizmosManager::generate_icons_texture() const bool GLGizmosManager::generate_icons_texture() const
{ {
std::string path = resources_dir() + "/icons/"; std::string path = resources_dir() + "/icons/";
std::vector<std::string> filenames; std::vector<std::string> filenames;
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) for (size_t idx=0; idx<m_gizmos.size(); ++idx)
{ {
if (it->second != nullptr) if (m_gizmos[idx] != nullptr)
{ {
const std::string& icon_filename = it->second->get_icon_filename(); const std::string& icon_filename = m_gizmos[idx]->get_icon_filename();
if (!icon_filename.empty()) if (!icon_filename.empty())
filenames.push_back(path + icon_filename); filenames.push_back(path + icon_filename);
} }
@ -1074,74 +953,9 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos)
if (!m_enabled) if (!m_enabled)
return; return;
float cnv_h = (float)m_parent.get_canvas_size().get_height(); size_t idx = get_gizmo_idx_from_mouse(mouse_pos);
float height = get_total_overlay_height(); if (idx != Undefined && m_gizmos[idx]->is_activable() && m_hover == idx)
activate_gizmo(m_current == idx ? Undefined : (EType)idx);
float scaled_icons_size = m_overlay_icons_size * m_overlay_scale;
float scaled_border = m_overlay_border * m_overlay_scale;
float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
float scaled_stride_y = scaled_icons_size + scaled_gap_y;
float top_y = 0.5f * (cnv_h - height) + scaled_border;
auto inside = [scaled_border, scaled_icons_size, &mouse_pos](float top_y) {
return (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size);
};
bool could_activate = true;
for (std::pair<const GLGizmosManager::EType, GLGizmoBase*> &type_and_gizmo : m_gizmos)
{
GLGizmoBase *gizmo = type_and_gizmo.second;
if ((gizmo == nullptr) || !gizmo->is_selectable())
continue;
if (! (gizmo->is_activable() && inside(top_y))) {
gizmo->set_state(GLGizmoBase::Off);
if (gizmo->get_state() != GLGizmoBase::Off) {
// Gizmo refused to leave it's active state. Don't try to select
could_activate = false;
}
}
top_y += scaled_stride_y;
}
// We may change m_current soon. If we did it during following loop, gizmos that take undo/redo snapshots
// in their on_set_state function could snapshot a state with the new gizmo already active.
// Therefore, just remember what needs to be done and actually change m_current afterwards.
EType new_current = m_current;
top_y = 0.5f * (cnv_h - height) + scaled_border;
for (std::pair<const GLGizmosManager::EType, GLGizmoBase*> &type_and_gizmo : m_gizmos)
{
GLGizmoBase *gizmo = type_and_gizmo.second;
if ((gizmo == nullptr) || !gizmo->is_selectable())
continue;
if (gizmo->is_activable() && inside(top_y))
{
if ((gizmo->get_state() == GLGizmoBase::On))
{
gizmo->set_state(GLGizmoBase::Off);
if (gizmo->get_state() == GLGizmoBase::Off) {
gizmo->set_state(GLGizmoBase::Hover);
new_current = Undefined;
}
}
else if ((gizmo->get_state() == GLGizmoBase::Hover) && could_activate)
{
gizmo->set_state(GLGizmoBase::On);
new_current = type_and_gizmo.first;
}
}
top_y += scaled_stride_y;
}
m_current = new_current;
if (could_activate) {
GizmosMap::iterator it = m_gizmos.find(m_current);
if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On))
it->second->set_state(GLGizmoBase::On);
}
} }
std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos) std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos)
@ -1151,60 +965,37 @@ std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos)
if (!m_enabled) if (!m_enabled)
return name; return name;
float cnv_h = (float)m_parent.get_canvas_size().get_height(); m_hover = Undefined;
float height = get_total_overlay_height();
float scaled_icons_size = m_overlay_icons_size * m_overlay_scale;
float scaled_border = m_overlay_border * m_overlay_scale;
float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
float scaled_stride_y = scaled_icons_size + scaled_gap_y;
float top_y = 0.5f * (cnv_h - height) + scaled_border;
for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) size_t idx = get_gizmo_idx_from_mouse(mouse_pos);
{ if (idx != Undefined) {
if ((it->second == nullptr) || !it->second->is_selectable()) name = m_gizmos[idx]->get_name();
continue;
bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); if (m_gizmos[idx]->is_activable())
if (inside) m_hover = (EType)idx;
name = it->second->get_name();
if (it->second->is_activable() && (it->second->get_state() != GLGizmoBase::On))
it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off);
top_y += scaled_stride_y;
} }
return name; return name;
} }
bool GLGizmosManager::overlay_contains_mouse(const Vec2d& mouse_pos) const void GLGizmosManager::activate_gizmo(EType type)
{ {
if (!m_enabled) if (m_gizmos.empty() || m_current == type)
return false; return;
float cnv_h = (float)m_parent.get_canvas_size().get_height(); if (m_current != Undefined) {
float height = get_total_overlay_height(); m_gizmos[m_current]->set_state(GLGizmoBase::Off);
if (m_gizmos[m_current]->get_state() != GLGizmoBase::Off)
float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; return; // gizmo refused to be turned off, do nothing.
float scaled_border = m_overlay_border * m_overlay_scale;
float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
float scaled_stride_y = scaled_icons_size + scaled_gap_y;
float top_y = 0.5f * (cnv_h - height) + scaled_border;
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
{
if ((it->second == nullptr) || !it->second->is_selectable())
continue;
if ((scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size))
return true;
top_y += scaled_stride_y;
} }
return false; if (type != Undefined)
m_gizmos[type]->set_state(GLGizmoBase::On);
m_current = type;
} }
bool GLGizmosManager::grabber_contains_mouse() const bool GLGizmosManager::grabber_contains_mouse() const
{ {
if (!m_enabled) if (!m_enabled)

View file

@ -54,25 +54,30 @@ public:
enum EType : unsigned char enum EType : unsigned char
{ {
Undefined,
Move, Move,
Scale, Scale,
Rotate, Rotate,
Flatten, Flatten,
Cut, Cut,
SlaSupports, SlaSupports,
Num_Types Undefined
}; };
private: private:
GLCanvas3D& m_parent; GLCanvas3D& m_parent;
bool m_enabled; bool m_enabled;
typedef std::map<EType, GLGizmoBase*> GizmosMap; std::vector<std::unique_ptr<GLGizmoBase>> m_gizmos;
GizmosMap m_gizmos;
mutable GLTexture m_icons_texture; mutable GLTexture m_icons_texture;
mutable bool m_icons_texture_dirty; mutable bool m_icons_texture_dirty;
BackgroundTexture m_background_texture; BackgroundTexture m_background_texture;
EType m_current; EType m_current;
EType m_hover;
std::vector<size_t> get_selectable_idxs() const;
std::vector<size_t> get_activable_idxs() const;
size_t get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const;
void activate_gizmo(EType type);
float m_overlay_icons_size; float m_overlay_icons_size;
float m_overlay_scale; float m_overlay_scale;
@ -98,7 +103,6 @@ private:
public: public:
explicit GLGizmosManager(GLCanvas3D& parent); explicit GLGizmosManager(GLCanvas3D& parent);
~GLGizmosManager();
bool init(); bool init();
@ -112,16 +116,8 @@ public:
ar(m_current); ar(m_current);
GLGizmoBase* curr = get_current(); if (m_current != Undefined)
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { m_gizmos[m_current]->load(ar);
GLGizmoBase* gizmo = it->second;
if (gizmo != nullptr) {
gizmo->set_hover_id(-1);
gizmo->set_state((it->second == curr) ? GLGizmoBase::On : GLGizmoBase::Off);
if (gizmo == curr)
gizmo->load(ar);
}
}
} }
template<class Archive> template<class Archive>
@ -132,9 +128,8 @@ public:
ar(m_current); ar(m_current);
GLGizmoBase* curr = get_current(); if (m_current != Undefined && !m_gizmos.empty())
if (curr != nullptr) m_gizmos[m_current]->save(ar);
curr->save(ar);
} }
bool is_enabled() const { return m_enabled; } bool is_enabled() const { return m_enabled; }
@ -195,8 +190,6 @@ public:
void update_after_undo_redo(const UndoRedo::Snapshot& snapshot); void update_after_undo_redo(const UndoRedo::Snapshot& snapshot);
private: private:
void reset();
void render_background(float left, float top, float right, float bottom, float border) const; void render_background(float left, float top, float right, float bottom, float border) const;
void do_render_overlay() const; void do_render_overlay() const;
@ -209,7 +202,6 @@ private:
void update_on_off_state(const Vec2d& mouse_pos); void update_on_off_state(const Vec2d& mouse_pos);
std::string update_hover_state(const Vec2d& mouse_pos); std::string update_hover_state(const Vec2d& mouse_pos);
bool overlay_contains_mouse(const Vec2d& mouse_pos) const;
bool grabber_contains_mouse() const; bool grabber_contains_mouse() const;
}; };