Various gizmos refactoring

This commit is contained in:
Filip Sykala 2023-10-29 23:11:10 +08:00 committed by Noisyfox
parent 30af274d44
commit 9dbb2dfe0d
22 changed files with 292 additions and 451 deletions

View file

@ -3309,7 +3309,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
m_dirty = true;
},
[this](const Vec3d& direction, bool slow, bool camera_space) {
m_selection.start_dragging();
m_selection.setup_cache();
double multiplier = slow ? 1.0 : 10.0;
Vec3d displacement;
@ -3322,7 +3322,6 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
displacement = multiplier * direction;
m_selection.translate(displacement);
m_selection.stop_dragging();
m_dirty = true;
}
);}
@ -3463,9 +3462,8 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
post_event(SimpleEvent(EVT_GLCANVAS_COLLAPSE_SIDEBAR));
} else if (m_gizmos.is_enabled() && !m_selection.is_empty() && m_canvas_type != CanvasAssembleView) {
auto _do_rotate = [this](double angle_z_rad) {
m_selection.start_dragging();
m_selection.setup_cache();
m_selection.rotate(Vec3d(0.0, 0.0, angle_z_rad), TransformationType(TransformationType::World_Relative_Joint));
m_selection.stop_dragging();
m_dirty = true;
// wxGetApp().obj_manipul()->set_dirty();
};
@ -3903,23 +3901,20 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
// It should be detection of volume change
// Not only detection of some modifiers !!!
if (evt.Dragging()) {
GLGizmosManager::EType c = m_gizmos.get_current_type();
if (current_printer_technology() == ptFFF &&
(fff_print()->config().print_sequence == PrintSequence::ByObject)) {
switch (m_gizmos.get_current_type()) {
case GLGizmosManager::EType::Move:
case GLGizmosManager::EType::Scale:
case GLGizmosManager::EType::Rotate:
if (c == GLGizmosManager::EType::Move ||
c == GLGizmosManager::EType::Scale ||
c == GLGizmosManager::EType::Rotate )
update_sequential_clearance();
}
} else {
switch (m_gizmos.get_current_type()) {
case GLGizmosManager::EType::Move:
case GLGizmosManager::EType::Scale:
case GLGizmosManager::EType::Rotate:
if (c == GLGizmosManager::EType::Move ||
c == GLGizmosManager::EType::Scale ||
c == GLGizmosManager::EType::Rotate)
show_sinking_contours();
}
}
}
else if (evt.LeftUp() &&
m_gizmos.get_current_type() == GLGizmosManager::EType::Scale &&
m_gizmos.get_current()->get_state() == GLGizmoBase::EState::On) {
@ -4050,7 +4045,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_volumes.volumes[volume_idx]->hover = GLVolume::HS_None;
// The dragging operation is initiated.
m_mouse.drag.move_volume_idx = volume_idx;
m_selection.start_dragging();
m_selection.setup_cache();
m_mouse.drag.start_position_3D = m_mouse.scene_position;
m_sequential_print_clearance_first_displacement = true;
m_moving = true;
@ -4218,7 +4213,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_mouse.position = pos.cast<double>();
if (evt.LeftUp()) {
m_selection.stop_dragging();
m_rotation_center(0) = m_rotation_center(1) = m_rotation_center(2) = 0.f;
}

View file

@ -104,13 +104,19 @@ GLGizmoAdvancedCut::GLGizmoAdvancedCut(GLCanvas3D& parent, const std::string& ic
for (int i = 0; i < 4; i++)
m_cut_plane_points[i] = { 0., 0., 0. };
set_group_id(m_gizmos.size());
m_group_id = (m_gizmos.size());
m_rotation.setZero();
//m_current_base_rotation.setZero();
m_rotate_cmds.clear();
m_buffered_rotation.setZero();
}
void GLGizmoAdvancedCut::data_changed()
{
GLGizmoRotate3D::data_changed();
finish_rotation();
}
bool GLGizmoAdvancedCut::gizmo_event(SLAGizmoEventType action, const Vec2d &mouse_position, bool shift_down, bool alt_down, bool control_down)
{
CutConnectors &connectors = m_c->selection_info()->model_object()->cut_connectors;
@ -126,7 +132,7 @@ bool GLGizmoAdvancedCut::gizmo_event(SLAGizmoEventType action, const Vec2d &mous
return false;
if (m_hover_id != -1) {
start_dragging();
//start_dragging();
return true;
}
@ -449,7 +455,7 @@ void GLGizmoAdvancedCut::on_dragging(const UpdateData &data)
m_rotation = rotation;
//m_move_grabber.angles = m_current_base_rotation + m_rotation;
if (m_hover_id == get_group_id()) {
if (m_hover_id == m_group_id) {
double move = calc_projection(data.mouse_ray);
set_movement(m_start_movement + move);
Vec3d plane_normal = get_plane_normal();
@ -941,7 +947,7 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers()
// m_move_grabber.color = GrabberColor;
// m_move_grabber.hover_color = GrabberHoverColor;
// m_move_grabber.render(m_hover_id == get_group_id(), (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0));
bool hover = (m_hover_id == get_group_id());
bool hover = (m_hover_id == m_group_id);
ColorRGBA render_color;
if (hover) {
render_color = GrabberHoverColor;

View file

@ -138,6 +138,8 @@ public:
virtual bool apply_clipping_plane() { return m_connectors_editing; }
void data_changed() override;
protected:
bool on_init() override;
void on_load(cereal::BinaryInputArchive &ar) override;
@ -154,28 +156,6 @@ protected:
void show_tooltip_information(float x, float y);
virtual void on_enable_grabber(unsigned int id)
{
if (id < 3)
m_gizmos[id].enable_grabber(0);
else if (id == 3)
this->enable_grabber(0);
}
virtual void on_disable_grabber(unsigned int id)
{
if (id < 3)
m_gizmos[id].disable_grabber(0);
else if (id == 3)
this->disable_grabber(0);
}
virtual void on_set_hover_id()
{
for (int i = 0; i < 3; ++i)
m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1);
}
private:
void perform_cut(const Selection& selection);
bool can_perform_cut() const;

View file

@ -200,9 +200,6 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u
, m_sprite_id(sprite_id)
, m_imgui(wxGetApp().imgui())
{
m_base_color = DEFAULT_BASE_COLOR;
m_drag_color = DEFAULT_DRAG_COLOR;
m_highlight_color = DEFAULT_HIGHLIGHT_COLOR;
}
void GLGizmoBase::set_icon_filename(const std::string &filename) {
@ -212,7 +209,7 @@ void GLGizmoBase::set_icon_filename(const std::string &filename) {
void GLGizmoBase::set_hover_id(int id)
{
// do not change hover id during dragging
if (m_dragging) return;
assert(!m_dragging);
// allow empty grabbers when not using grabbers but use hover_id - flatten, rotate
if (!m_grabbers.empty() && id >= (int) m_grabbers.size())
@ -222,49 +219,6 @@ void GLGizmoBase::set_hover_id(int id)
on_set_hover_id();
}
void GLGizmoBase::enable_grabber(unsigned int id)
{
if (id < m_grabbers.size())
m_grabbers[id].enabled = true;
on_enable_grabber(id);
}
void GLGizmoBase::disable_grabber(unsigned int id)
{
if (id < m_grabbers.size())
m_grabbers[id].enabled = false;
on_disable_grabber(id);
}
void GLGizmoBase::start_dragging()
{
m_dragging = true;
for (int i = 0; i < (int)m_grabbers.size(); ++i)
{
m_grabbers[i].dragging = (m_hover_id == i);
}
on_start_dragging();
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("this %1%, m_hover_id=%2%\n")%this %m_hover_id;
}
void GLGizmoBase::stop_dragging()
{
m_dragging = false;
for (int i = 0; i < (int)m_grabbers.size(); ++i)
{
m_grabbers[i].dragging = false;
}
on_stop_dragging();
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("this %1%, m_hover_id=%2%\n")%this %m_hover_id;
}
bool GLGizmoBase::update_items_state()
{
bool res = m_dirty;
@ -347,54 +301,72 @@ void GLGizmoBase::render_grabbers(float size) const
// help function to process grabbers
// call start_dragging, stop_dragging, on_dragging
bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {
bool is_dragging_finished = false;
if (mouse_event.Moving()) {
// it should not happen but for sure
assert(!m_dragging);
// only for sure
if (m_dragging) m_dragging = false;
return false;
if (m_dragging) is_dragging_finished = true;
else return false;
}
if (mouse_event.LeftDown()) {
Selection &selection = m_parent.get_selection();
if (!selection.is_empty() && m_hover_id != -1) {
selection.start_dragging();
if (!selection.is_empty() && m_hover_id != -1 &&
(m_grabbers.empty() || m_hover_id < static_cast<int>(m_grabbers.size()))) {
selection.setup_cache();
start_dragging();
m_dragging = true;
for (auto &grabber : m_grabbers) grabber.dragging = false;
if (!m_grabbers.empty() && m_hover_id < int(m_grabbers.size()))
m_grabbers[m_hover_id].dragging = true;
// prevent change of hover_id during dragging
m_parent.set_mouse_as_dragging();
on_start_dragging();
// Let the plater know that the dragging started
m_parent.post_event(
SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_STARTED));
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_STARTED));
m_parent.set_as_dirty();
return true;
}
} else if (m_dragging) {
// when mouse cursor leave window than finish actual dragging operation
bool is_leaving = mouse_event.Leaving();
if (mouse_event.Dragging()) {
m_parent.set_mouse_as_dragging();
Point mouse_coord(mouse_event.GetX(), mouse_event.GetY());
UpdateData data{m_parent.mouse_ray(mouse_coord), mouse_coord};
auto ray = m_parent.mouse_ray(mouse_coord);
UpdateData data(ray, mouse_coord);
on_dragging(data);
wxGetApp().obj_manipul()->set_dirty();
m_parent.set_as_dirty();
return true;
} else if (mouse_event.LeftUp()) {
stop_dragging();
} else if (mouse_event.LeftUp() || is_leaving || is_dragging_finished) {
for (auto &grabber : m_grabbers) grabber.dragging = false;
m_dragging = false;
// NOTE: This should be part of GLCanvas3D
// Reset hover_id when leave window
if (is_leaving) m_parent.mouse_up_cleanup();
on_stop_dragging();
// There is prediction that after draggign, data are changed
// Data are updated twice also by canvas3D::reload_scene.
// Should be fixed.
m_parent.get_gizmos_manager().update_data();
wxGetApp().obj_manipul()->set_dirty();
// Let the plater know that the dragging finished, so a delayed
// refresh of the scene with the background processing data should
// be performed.
m_parent.post_event(
SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
// updates camera target constraints
m_parent.refresh_camera_scene_box();
return true;
} else if (mouse_event.Leaving()) {
m_dragging = false;
}
}
return false;

View file

@ -29,7 +29,6 @@ class ImGuiWrapper;
class GLCanvas3D;
enum class CommonGizmosDataID;
class CommonGizmosDataPool;
class Selection;
class GLGizmoBase
{
@ -137,13 +136,9 @@ protected:
unsigned int m_sprite_id;
int m_hover_id{ -1 };
bool m_dragging{ false };
ColorRGBA m_base_color;
ColorRGBA m_drag_color;
ColorRGBA m_highlight_color;
mutable std::vector<Grabber> m_grabbers;
ImGuiWrapper* m_imgui;
bool m_first_input_window_render{ true };
mutable std::string m_tooltip;
CommonGizmosDataPool* m_c{ nullptr };
bool m_is_dark_mode = false;
@ -161,9 +156,6 @@ public:
std::string get_name(bool include_shortcut = true) const;
int get_group_id() const { return m_group_id; }
void set_group_id(int id) { m_group_id = id; }
EState get_state() const { return m_state; }
void set_state(EState state) { m_state = state; on_set_state(); }
@ -189,28 +181,29 @@ public:
int get_hover_id() const { return m_hover_id; }
void set_hover_id(int id);
void set_highlight_color(const ColorRGBA& color) { m_highlight_color = color; }
void enable_grabber(unsigned int id);
void disable_grabber(unsigned int id);
void start_dragging();
void stop_dragging();
bool is_dragging() const { return m_dragging; }
// returns True when Gizmo changed its state
bool update_items_state();
void render() { m_tooltip.clear(); on_render(); }
void render() { on_render(); }
void render_input_window(float x, float y, float bottom_limit);
virtual void on_change_color_mode(bool is_dark) { m_is_dark_mode = is_dark; }
/// <summary>
/// Mouse tooltip text
/// </summary>
/// <returns>Text to be visible in mouse tooltip</returns>
virtual std::string get_tooltip() const { return ""; }
int get_count() { return ++count; }
std::string get_gizmo_name() { return on_get_name(); }
/// <summary>
/// Is called when data (Selection) is changed
/// </summary>
virtual void data_changed(){};
/// <summary>
/// Implement when want to process mouse events in gizmo
/// Click, Right click, move, drag, ...
@ -265,10 +258,12 @@ protected:
void set_dirty();
/// <summary>
///
/// function which
/// Set up m_dragging and call functions
/// on_start_dragging / on_dragging / on_stop_dragging
/// </summary>
/// <param name="mouse_event"></param>
/// <returns></returns>
/// <param name="mouse_event">Keep information about mouse click</param>
/// <returns>same as on_mouse</returns>
bool use_grabbers(const wxMouseEvent &mouse_event);
private:
// Flag for dirty visible state of Gizmo

View file

@ -25,27 +25,47 @@ bool GLGizmoFlatten::on_mouse(const wxMouseEvent &mouse_event)
if (mouse_event.Moving()) {
// only for sure
m_mouse_left_down = false;
if (m_hover_id != -1) m_parent.set_as_dirty();
return false;
}
if (mouse_event.LeftDown() && m_hover_id != -1) {
if (mouse_event.LeftDown()) {
if (m_hover_id != -1) {
m_mouse_left_down = true;
Selection &selection = m_parent.get_selection();
if (selection.is_single_full_instance()) {
// Rotate the object so the normal points downward:
selection.flattening_rotate(m_planes[m_hover_id].normal);
m_parent.do_rotate(L("Gizmo-Place on Face"));
}
m_mouse_left_down = true;
return true;
} else if (m_mouse_left_down && mouse_event.LeftUp()) {
// responsible for mouse left up
}
// fix: prevent restart gizmo when reselect object
// take responsibility for left up
if (m_parent.get_first_hover_volume_idx() >= 0) m_mouse_left_down = true;
} else if (mouse_event.LeftUp()) {
if (m_mouse_left_down) {
// responsible for mouse left up after selecting plane
m_mouse_left_down = false;
return true;
}
} else if (mouse_event.Leaving()) {
m_mouse_left_down = false;
}
return false;
}
void GLGizmoFlatten::data_changed()
{
const Selection & selection = m_parent.get_selection();
const ModelObject *model_object = nullptr;
if (selection.is_single_full_instance() ||
selection.is_from_single_object() ) {
model_object = selection.get_model()->objects[selection.get_object_idx()];
}
set_flattening_data(model_object);
}
bool GLGizmoFlatten::on_init()
{
// BBS

View file

@ -35,7 +35,7 @@ private:
std::vector<PlaneData> m_planes;
std::vector<std::shared_ptr<SceneRaycasterItem>> m_planes_casters;
bool m_mouse_left_down = false;
bool m_mouse_left_down = false; // for detection left_up of this gizmo
const ModelObject* m_old_model_object = nullptr;
std::vector<const Transform3d*> instances_matrices;
@ -54,6 +54,7 @@ public:
/// <returns>Return True when use the information otherwise False.</returns>
bool on_mouse(const wxMouseEvent &mouse_event) override;
void data_changed() override;
protected:
bool on_init() override;
std::string on_get_name() const override;

View file

@ -162,11 +162,10 @@ void GLGizmoMmuSegmentation::render_painter_gizmo()
glsafe(::glDisable(GL_BLEND));
}
void GLGizmoMmuSegmentation::set_painter_gizmo_data(const Selection &selection)
void GLGizmoMmuSegmentation::data_changed()
{
GLGizmoPainterBase::set_painter_gizmo_data(selection);
if (m_state != On || wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptFFF || wxGetApp().filaments_cnt() <= 1)
GLGizmoPainterBase::data_changed();
if (m_state != On || wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptFFF || wxGetApp().extruders_edited_cnt() <= 1)
return;
ModelObject* model_object = m_c->selection_info()->model_object();

View file

@ -70,7 +70,7 @@ public:
void render_painter_gizmo() override;
void set_painter_gizmo_data(const Selection& selection) override;
void data_changed() override;
void render_triangles(const Selection& selection) const override;

View file

@ -47,6 +47,12 @@ bool GLGizmoMove3D::on_mouse(const wxMouseEvent &mouse_event) {
return use_grabbers(mouse_event);
}
void GLGizmoMove3D::data_changed() {
const Selection &selection = m_parent.get_selection();
bool is_wipe_tower = selection.is_wipe_tower();
m_grabbers[2].enabled = !is_wipe_tower;
}
bool GLGizmoMove3D::on_init()
{
for (int i = 0; i < 3; ++i) {

View file

@ -49,6 +49,10 @@ public:
/// <returns>Return True when use the information otherwise False.</returns>
bool on_mouse(const wxMouseEvent &mouse_event) override;
/// <summary>
/// Detect reduction of move for wipetover on selection change
/// </summary>
void data_changed() override;
protected:
bool on_init() override;
std::string on_get_name() const override;

View file

@ -34,13 +34,13 @@ GLGizmoPainterBase::~GLGizmoPainterBase()
s_sphere.reset();
}
void GLGizmoPainterBase::set_painter_gizmo_data(const Selection& selection)
void GLGizmoPainterBase::data_changed()
{
if (m_state != On)
return;
const ModelObject* mo = m_c->selection_info() ? m_c->selection_info()->model_object() : nullptr;
const Selection & selection = m_parent.get_selection();
if (mo && selection.is_from_single_instance()
&& (m_schedule_update || mo->id() != m_old_mo_id || mo->volumes.size() != m_old_volumes_size))
{
@ -902,22 +902,13 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
bool GLGizmoPainterBase::on_mouse(const wxMouseEvent &mouse_event)
{
// TODO: distribute implementation into gizmos itself
GLGizmosManager & mng = m_parent.get_gizmos_manager();
GLGizmosManager::EType current_type = mng.get_current_type();
// wxCoord == int --> wx/types.h
Vec2i mouse_coord(mouse_event.GetX(), mouse_event.GetY());
Vec2d mouse_pos = mouse_coord.cast<double>();
if (mouse_event.Moving()) {
if (current_type == GLGizmosManager::MmuSegmentation ||
current_type == GLGizmosManager::FdmSupports ||
current_type == GLGizmosManager::Text)
gizmo_event(SLAGizmoEventType::Moving, mouse_pos,
mouse_event.ShiftDown(), mouse_event.AltDown(),
false);
gizmo_event(SLAGizmoEventType::Moving, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), false);
return false;
}
// when control is down we allow scene pan and rotation even when clicking
@ -927,79 +918,52 @@ bool GLGizmoPainterBase::on_mouse(const wxMouseEvent &mouse_event)
const Selection &selection = m_parent.get_selection();
int selected_object_idx = selection.get_object_idx();
if (mouse_event.LeftDown() && (!control_down || grabber_contains_mouse)) {
if ((current_type == GLGizmosManager::FdmSupports ||
current_type == GLGizmosManager::Seam ||
current_type == GLGizmosManager::MmuSegmentation ||
current_type == GLGizmosManager::Text ||
current_type == GLGizmosManager::Cut ||
current_type == GLGizmosManager::MeshBoolean) &&
gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos,
mouse_event.ShiftDown(), mouse_event.AltDown(), false))
if (mouse_event.LeftDown()) {
if ((!control_down || grabber_contains_mouse) &&
gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), false))
// the gizmo got the event and took some action, there is no need
// to do anything more
return true;
} else if (mouse_event.RightDown() && !control_down && selected_object_idx != -1 &&
(current_type == GLGizmosManager::FdmSupports ||
current_type == GLGizmosManager::Seam ||
current_type == GLGizmosManager::MmuSegmentation ||
current_type == GLGizmosManager::Cut) &&
gizmo_event(SLAGizmoEventType::RightDown, mouse_pos, false, false, false)) {
// event was taken care of by the FdmSupports / Seam / MMUPainting / Cut gizmo
} else if (mouse_event.RightDown()){
if (!control_down && selected_object_idx != -1 &&
gizmo_event(SLAGizmoEventType::RightDown, mouse_pos, false, false, false))
// event was taken care of
return true;
} else if (mouse_event.Dragging() &&
m_parent.get_move_volume_id() != -1 &&
(current_type == GLGizmosManager::FdmSupports ||
current_type == GLGizmosManager::Seam ||
current_type == GLGizmosManager::MmuSegmentation))
} else if (mouse_event.Dragging()) {
if (m_parent.get_move_volume_id() != -1)
// don't allow dragging objects with the Sla gizmo on
return true;
else if (mouse_event.Dragging() && !control_down &&
(current_type == GLGizmosManager::FdmSupports ||
current_type == GLGizmosManager::Seam ||
current_type == GLGizmosManager::MmuSegmentation ||
current_type == GLGizmosManager::Cut) &&
gizmo_event(SLAGizmoEventType::Dragging, mouse_pos,
mouse_event.ShiftDown(), mouse_event.AltDown(), false)) {
if (!control_down && gizmo_event(SLAGizmoEventType::Dragging,
mouse_pos, mouse_event.ShiftDown(),
mouse_event.AltDown(), false)) {
// the gizmo got the event and took some action, no need to do
// anything more here
m_parent.set_as_dirty();
return true;
} else if (mouse_event.Dragging() && control_down &&
(mouse_event.LeftIsDown() || mouse_event.RightIsDown())) {
}
if(control_down && (mouse_event.LeftIsDown() || mouse_event.RightIsDown()))
{
// CTRL has been pressed while already dragging -> stop current action
if (mouse_event.LeftIsDown())
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos,
mouse_event.ShiftDown(), mouse_event.AltDown(), true);
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), true);
else if (mouse_event.RightIsDown())
gizmo_event(SLAGizmoEventType::RightUp, mouse_pos,
mouse_event.ShiftDown(), mouse_event.AltDown(), true);
} else if (mouse_event.LeftUp() &&
(current_type == GLGizmosManager::FdmSupports ||
current_type == GLGizmosManager::Seam ||
current_type == GLGizmosManager::MmuSegmentation ||
current_type == GLGizmosManager::Cut) &&
!m_parent.is_mouse_dragging()) {
// in case SLA/FDM gizmo is selected, we just pass the LeftUp event
// and stop processing - neither object moving or selecting is
// suppressed in that case
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos,
mouse_event.ShiftDown(), mouse_event.AltDown(),
control_down);
gizmo_event(SLAGizmoEventType::RightUp, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), true);
return false;
}
} else if (mouse_event.LeftUp()) {
if (!m_parent.is_mouse_dragging()) {
// in case SLA/FDM gizmo is selected, we just pass the LeftUp
// event and stop processing - neither object moving or selecting
// is suppressed in that case
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), control_down);
return true;
} else if (mouse_event.RightUp() &&
(current_type == GLGizmosManager::FdmSupports ||
current_type == GLGizmosManager::Seam ||
current_type == GLGizmosManager::MmuSegmentation ||
current_type == GLGizmosManager::Cut) &&
!m_parent.is_mouse_dragging()) {
gizmo_event(SLAGizmoEventType::RightUp, mouse_pos,
mouse_event.ShiftDown(), mouse_event.AltDown(),
control_down);
}
} else if (mouse_event.RightUp()) {
if (!m_parent.is_mouse_dragging()) {
gizmo_event(SLAGizmoEventType::RightUp, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), control_down);
return true;
}
}
return false;
}

View file

@ -21,6 +21,7 @@ enum class SLAGizmoEventType : unsigned char;
class ClippingPlane;
struct Camera;
class GLGizmoMmuSegmentation;
class Selection;
enum class PainterGizmoType {
FDM_SUPPORTS,
@ -188,7 +189,7 @@ private:
public:
GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
virtual ~GLGizmoPainterBase() override;
virtual void set_painter_gizmo_data(const Selection& selection);
void data_changed() override;
virtual bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
// Following function renders the triangles and cursor. Having this separated

View file

@ -29,7 +29,16 @@ const float GLGizmoRotate::GrabberOffset = 0.15f; // in percent of radius
GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis)
: GLGizmoBase(parent, "", -1)
, m_axis(axis)
{}
, m_drag_color(DEFAULT_DRAG_COLOR)
, m_highlight_color(DEFAULT_HIGHLIGHT_COLOR)
{
m_group_id = static_cast<int>(axis);
}
void GLGizmoRotate::set_highlight_color(const ColorRGBA &color)
{
m_highlight_color = color;
}
void GLGizmoRotate::set_angle(double angle)
{
@ -58,6 +67,21 @@ bool GLGizmoRotate::on_mouse(const wxMouseEvent &mouse_event)
void GLGizmoRotate::dragging(const UpdateData &data) { on_dragging(data); }
void GLGizmoRotate::start_dragging()
{
m_grabbers[0].dragging = true;
on_start_dragging();
}
void GLGizmoRotate::stop_dragging()
{
m_grabbers[0].dragging = false;
on_stop_dragging();
}
void GLGizmoRotate::enable_grabber() { m_grabbers[0].enabled = true; }
void GLGizmoRotate::disable_grabber() { m_grabbers[0].enabled = false; }
bool GLGizmoRotate::on_init()
{
m_grabbers.push_back(Grabber());
@ -456,10 +480,6 @@ GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_fil
//BBS: GUI refactor: add obj manipulation
, m_object_manipulation(obj_manipulation)
{
for (unsigned int i = 0; i < 3; ++i) {
m_gizmos[i].set_group_id(i);
}
load_rotoptimize_state();
}
@ -475,6 +495,25 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event) {
return use_grabbers(mouse_event);
}
void GLGizmoRotate3D::data_changed() {
const Selection &selection = m_parent.get_selection();
bool is_wipe_tower = selection.is_wipe_tower();
if (is_wipe_tower) {
DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
float wipe_tower_rotation_angle =
dynamic_cast<const ConfigOptionFloat *>(
config.option("wipe_tower_rotation_angle"))
->value;
set_rotation(Vec3d(0., 0., (M_PI / 180.) * wipe_tower_rotation_angle));
m_gizmos[0].disable_grabber();
m_gizmos[1].disable_grabber();
} else {
set_rotation(Vec3d::Zero());
m_gizmos[0].enable_grabber();
m_gizmos[1].enable_grabber();
}
}
bool GLGizmoRotate3D::on_init()
{
for (GLGizmoRotate& g : m_gizmos)

View file

@ -9,7 +9,7 @@
namespace Slic3r {
namespace GUI {
class Selection;
class GLGizmoRotate : public GLGizmoBase
{
static const float Offset;
@ -24,9 +24,9 @@ class GLGizmoRotate : public GLGizmoBase
public:
enum Axis : unsigned char
{
X,
Y,
Z
X=0,
Y=1,
Z=2
};
private:
@ -40,6 +40,9 @@ private:
float m_snap_fine_in_radius{ 0.0f };
float m_snap_fine_out_radius{ 0.0f };
ColorRGBA m_drag_color;
ColorRGBA m_highlight_color;
GLModel m_circle;
GLModel m_scale;
GLModel m_snap_radii;
@ -66,6 +69,14 @@ public:
void set_center(const Vec3d &point) { m_custom_center = point; }
void start_dragging();
void stop_dragging();
void enable_grabber();
void disable_grabber();
void set_highlight_color(const ColorRGBA &color);
/// <summary>
/// Postpone to Grabber for move
/// Detect move of object by dragging
@ -136,6 +147,7 @@ public:
/// <returns>Return True when use the information otherwise False.</returns>
bool on_mouse(const wxMouseEvent &mouse_event) override;
void data_changed() override;
protected:
bool on_init() override;
std::string on_get_name() const override;
@ -147,14 +159,7 @@ protected:
for (int i = 0; i < 3; ++i)
m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1);
}
void on_enable_grabber(unsigned int id) override {
if (id < 3)
m_gizmos[id].enable_grabber(0);
}
void on_disable_grabber(unsigned int id) override {
if (id < 3)
m_gizmos[id].disable_grabber(0);
}
bool on_is_activable() const override;
void on_start_dragging() override;
void on_stop_dragging() override;

View file

@ -27,6 +27,9 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filen
: GLGizmoBase(parent, icon_filename, sprite_id)
//BBS: GUI refactor: add obj manipulation
, m_object_manipulation(obj_manipulation)
, m_base_color(DEFAULT_BASE_COLOR)
, m_drag_color(DEFAULT_DRAG_COLOR)
, m_highlight_color(DEFAULT_HIGHLIGHT_COLOR)
{
m_grabber_connections[0].grabber_indices = { 0, 1 };
m_grabber_connections[1].grabber_indices = { 2, 3 };
@ -90,6 +93,29 @@ bool GLGizmoScale3D::on_mouse(const wxMouseEvent &mouse_event)
return use_grabbers(mouse_event);
}
void GLGizmoScale3D::data_changed()
{
const Selection &selection = m_parent.get_selection();
bool enable_scale_xyz = selection.is_single_full_instance() ||
selection.is_single_volume() ||
selection.is_single_modifier();
for (unsigned int i = 0; i < 6; ++i)
m_grabbers[i].enabled = enable_scale_xyz;
if (enable_scale_xyz) {
// all volumes in the selection belongs to the same instance, any of
// them contains the needed data, so we take the first
const GLVolume *volume = selection.get_volume(*selection.get_volume_idxs().begin());
if (selection.is_single_full_instance()) {
set_scale(volume->get_instance_scaling_factor());
} else if (selection.is_single_volume() ||
selection.is_single_modifier()) {
set_scale(volume->get_volume_scaling_factor());
}
} else {
set_scale(Vec3d::Ones());
}
}
bool GLGizmoScale3D::on_init()
{

View file

@ -37,6 +37,10 @@ class GLGizmoScale3D : public GLGizmoBase
double m_snap_step{ 0.05 };
StartingData m_starting;
ColorRGBA m_base_color;
ColorRGBA m_drag_color;
ColorRGBA m_highlight_color;
struct GrabberConnection
{
GLModel model;
@ -71,6 +75,7 @@ public:
/// <returns>Return True when use the information otherwise False.</returns>
bool on_mouse(const wxMouseEvent &mouse_event) override;
void data_changed() override;
protected:
virtual bool on_init() override;
virtual std::string on_get_name() const override;

View file

@ -308,8 +308,8 @@ void GLGizmosManager::refresh_on_off_state()
if (m_serializing || m_current == Undefined || m_gizmos.empty())
return;
if (m_current != Undefined
&& ! m_gizmos[m_current]->is_activable() && activate_gizmo(Undefined))
// FS: Why update data after Undefined gizmo activation?
if (!m_gizmos[m_current]->is_activable() && activate_gizmo(Undefined))
update_data();
}
@ -361,17 +361,6 @@ void GLGizmosManager::set_hover_id(int id)
m_gizmos[m_current]->set_hover_id(id);
}
void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable)
{
if (!m_enabled || type == Undefined || m_gizmos.empty())
return;
if (enable)
m_gizmos[type]->enable_grabber(id);
else
m_gizmos[type]->disable_grabber(id);
}
void GLGizmosManager::update_assemble_view_data()
{
if (m_assemble_view_data) {
@ -382,73 +371,14 @@ void GLGizmosManager::update_assemble_view_data()
}
}
// TODO: divide into gizmo: on init + on selection change
void GLGizmosManager::update_data()
{
if (!m_enabled)
return;
const Selection& selection = m_parent.get_selection();
bool is_wipe_tower = selection.is_wipe_tower();
enable_grabber(Move, 2, !is_wipe_tower);
enable_grabber(Rotate, 0, !is_wipe_tower);
enable_grabber(Rotate, 1, !is_wipe_tower);
// BBS: when select multiple objects, uniform scale can be deselected, display the 0-5 grabbers
//bool enable_scale_xyz = selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier();
//for (unsigned int i = 0; i < 6; ++i)
//{
// enable_grabber(Scale, i, enable_scale_xyz);
//}
if (m_common_gizmos_data) {
if (!m_enabled) return;
if (m_common_gizmos_data)
m_common_gizmos_data->update(get_current()
? get_current()->get_requirements()
: CommonGizmosDataID(0));
}
if (selection.is_single_full_instance())
{
// all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
set_scale(volume->get_instance_scaling_factor());
set_rotation(Vec3d::Zero());
// BBS
finish_cut_rotation();
ModelObject* model_object = selection.get_model()->objects[selection.get_object_idx()];
set_flattening_data(model_object);
//set_sla_support_data(model_object);
set_painter_gizmo_data();
}
else if (selection.is_single_volume() || selection.is_single_modifier())
{
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
set_scale(volume->get_volume_scaling_factor());
set_rotation(Vec3d::Zero());
// BBS
finish_cut_rotation();
set_flattening_data(nullptr);
//set_sla_support_data(nullptr);
set_painter_gizmo_data();
}
else if (is_wipe_tower)
{
DynamicPrintConfig& proj_cfg = wxGetApp().preset_bundle->project_config;
set_scale(Vec3d::Ones());
set_rotation(Vec3d(0., 0., (M_PI/180.) * dynamic_cast<const ConfigOptionFloat*>(proj_cfg.option("wipe_tower_rotation_angle"))->value));
set_flattening_data(nullptr);
//set_sla_support_data(nullptr);
set_painter_gizmo_data();
}
else
{
set_scale(Vec3d::Ones());
set_rotation(Vec3d::Zero());
set_flattening_data(selection.is_from_single_object() ? selection.get_model()->objects[selection.get_object_idx()] : nullptr);
//set_sla_support_data(selection.is_from_single_instance() ? selection.get_model()->objects[selection.get_object_idx()] : nullptr);
set_painter_gizmo_data();
}
if (m_current != Undefined) m_gizmos[m_current]->data_changed();
//BBS: GUI refactor: add object manipulation in gizmo
m_object_manipulation.update_ui_from_settings();
@ -492,91 +422,6 @@ bool GLGizmosManager::is_dragging() const
return m_gizmos[m_current]->is_dragging();
}
void GLGizmosManager::start_dragging()
{
if (! m_enabled || m_current == Undefined)
return;
m_gizmos[m_current]->start_dragging();
}
void GLGizmosManager::stop_dragging()
{
if (! m_enabled || m_current == Undefined)
return;
m_gizmos[m_current]->stop_dragging();
}
Vec3d GLGizmosManager::get_scale() const
{
if (!m_enabled)
return Vec3d::Ones();
return dynamic_cast<GLGizmoScale3D*>(m_gizmos[Scale].get())->get_scale();
}
void GLGizmosManager::set_scale(const Vec3d& scale)
{
if (!m_enabled || m_gizmos.empty())
return;
dynamic_cast<GLGizmoScale3D*>(m_gizmos[Scale].get())->set_scale(scale);
}
Vec3d GLGizmosManager::get_rotation() const
{
if (!m_enabled || m_gizmos.empty())
return Vec3d::Zero();
return dynamic_cast<GLGizmoRotate3D*>(m_gizmos[Rotate].get())->get_rotation();
}
void GLGizmosManager::set_rotation(const Vec3d& rotation)
{
if (!m_enabled || m_gizmos.empty())
return;
dynamic_cast<GLGizmoRotate3D*>(m_gizmos[Rotate].get())->set_rotation(rotation);
}
// BBS
void GLGizmosManager::finish_cut_rotation()
{
dynamic_cast<GLGizmoAdvancedCut*>(m_gizmos[Cut].get())->finish_rotation();
}
void GLGizmosManager::set_flattening_data(const ModelObject* model_object)
{
if (!m_enabled || m_gizmos.empty())
return;
dynamic_cast<GLGizmoFlatten*>(m_gizmos[Flatten].get())->set_flattening_data(model_object);
}
/*
void GLGizmosManager::set_sla_support_data(ModelObject* model_object)
{
if (! m_enabled
|| m_gizmos.empty()
|| wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA)
return;
auto* gizmo_hollow = dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get());
auto* gizmo_supports = dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get());
gizmo_hollow->set_sla_support_data(model_object, m_parent.get_selection());
gizmo_supports->set_sla_support_data(model_object, m_parent.get_selection());
}
*/
void GLGizmosManager::set_painter_gizmo_data()
{
if (!m_enabled || m_gizmos.empty())
return;
dynamic_cast<GLGizmoFdmSupports*>(m_gizmos[FdmSupports].get())->set_painter_gizmo_data(m_parent.get_selection());
dynamic_cast<GLGizmoSeam*>(m_gizmos[Seam].get())->set_painter_gizmo_data(m_parent.get_selection());
dynamic_cast<GLGizmoMmuSegmentation*>(m_gizmos[MmuSegmentation].get())->set_painter_gizmo_data(m_parent.get_selection());
}
// 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)
{
@ -1446,12 +1291,6 @@ bool GLGizmosManager::is_hiding_instances() const
&& m_common_gizmos_data->instances_hider()->is_valid());
}
int GLGizmosManager::get_shortcut_key(GLGizmosManager::EType type) const
{
return m_gizmos[type]->get_shortcut_key();
}
std::string get_name_from_gizmo_etype(GLGizmosManager::EType type)
{
switch (type) {

View file

@ -225,8 +225,11 @@ public:
bool check_gizmos_closed_except(EType) const;
void set_hover_id(int id);
void enable_grabber(EType type, unsigned int id, bool enable);
/// <summary>
/// Distribute information about different data into active gizmo
/// Should be called when selection changed
/// </summary>
void update_data();
void update_assemble_view_data();
@ -239,17 +242,6 @@ public:
bool handle_shortcut(int key);
bool is_dragging() const;
void start_dragging();
void stop_dragging();
Vec3d get_scale() const;
void set_scale(const Vec3d& scale);
Vec3d get_rotation() const;
void set_rotation(const Vec3d& rotation);
// BBS
void finish_cut_rotation();
//BBS
void* get_icon_texture_id(MENU_ICON_NAME icon) {
@ -265,13 +257,6 @@ public:
return nullptr;
}
void set_flattening_data(const ModelObject* model_object);
//void set_sla_support_data(ModelObject* model_object);
void set_painter_gizmo_data();
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false, bool alt_down = false, bool control_down = false);
ClippingPlane get_clipping_plane() const;
ClippingPlane get_assemble_view_clipping_plane() const;
bool wants_reslice_supports_on_undo() const;
@ -298,7 +283,6 @@ public:
void update_after_undo_redo(const UndoRedo::Snapshot& snapshot);
int get_selectable_icons_cnt() const { return get_selectable_idxs().size(); }
int get_shortcut_key(GLGizmosManager::EType) const;
// To end highlight set gizmo = undefined
void set_highlight(EType gizmo, bool highlight_shown) { m_highlight = std::pair<EType, bool>(gizmo, highlight_shown); }
@ -311,6 +295,12 @@ public:
bool get_uniform_scaling() const { return m_object_manipulation.get_uniform_scaling();}
private:
bool gizmo_event(SLAGizmoEventType action,
const Vec2d & mouse_position = Vec2d::Zero(),
bool shift_down = false,
bool alt_down = false,
bool control_down = false);
void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const;
void do_render_overlay() const;

View file

@ -259,7 +259,7 @@ void GizmoObjectManipulation::change_position_value(int axis, double value)
position(axis) = value;
Selection& selection = m_glcanvas.get_selection();
selection.start_dragging();
selection.setup_cache();
selection.translate(position - m_cache.position, selection.requires_local_axes());
m_glcanvas.do_move(L("Set Position"));
@ -287,7 +287,7 @@ void GizmoObjectManipulation::change_rotation_value(int axis, double value)
transformation_type.set_local();
}
selection.start_dragging();
selection.setup_cache();
selection.rotate(
(M_PI / 180.0) * (transformation_type.absolute() ? rotation : rotation - m_cache.rotation),
transformation_type);
@ -363,7 +363,7 @@ void GizmoObjectManipulation::do_scale(int axis, const Vec3d &scale) const
if (m_uniform_scale/* || selection.requires_uniform_scale()*/)
scaling_factor = scale(axis) * Vec3d::Ones();
selection.start_dragging();
selection.setup_cache();
selection.scale(scaling_factor * 0.01, transformation_type);
m_glcanvas.do_scale(L("Set Scale"));
}

View file

@ -117,7 +117,6 @@ Selection::Selection()
, m_type(Empty)
, m_valid(false)
, m_scale_factor(1.0f)
, m_dragging(false)
{
this->set_bounding_boxes_dirty();
}
@ -812,12 +811,11 @@ const BoundingBoxf3& Selection::get_scaled_instance_bounding_box() const
return *m_scaled_instance_bounding_box;
}
void Selection::start_dragging()
void Selection::setup_cache()
{
if (!m_valid)
return;
m_dragging = true;
set_caches();
}
@ -1166,12 +1164,12 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume)
type.set_joint();
// apply scale
start_dragging();
setup_cache();
scale(s * Vec3d::Ones(), type);
wxGetApp().plater()->canvas3D()->do_scale(""); // avoid storing another snapshot
// center selection on print bed
start_dragging();
setup_cache();
offset.z() = -get_bounding_box().min.z();
translate(offset);
wxGetApp().plater()->canvas3D()->do_move(""); // avoid storing another snapshot

View file

@ -229,7 +229,6 @@ private:
Planes m_planes;
float m_scale_factor;
bool m_dragging;
// BBS
EMode m_volume_selection_mode{ Instance };
@ -334,9 +333,7 @@ public:
const BoundingBoxf3& get_unscaled_instance_bounding_box() const;
const BoundingBoxf3& get_scaled_instance_bounding_box() const;
void start_dragging();
void stop_dragging() { m_dragging = false; }
bool is_dragging() const { return m_dragging; }
void setup_cache();
void translate(const Vec3d& displacement, bool local = false);
void move_to_center(const Vec3d& displacement, bool local = false);