mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-19 04:37:52 -06:00
Allow wipe tower rotation by the rotation gizmo
This commit is contained in:
parent
045879f68a
commit
5f226c5d7f
7 changed files with 135 additions and 89 deletions
|
@ -709,12 +709,15 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
||||||
brim_mesh.translate(-brim_width, -brim_width, 0.f);
|
brim_mesh.translate(-brim_width, -brim_width, 0.f);
|
||||||
mesh.merge(brim_mesh);
|
mesh.merge(brim_mesh);
|
||||||
|
|
||||||
mesh.rotate(rotation_angle, &origin_of_rotation); // rotates the box according to the config rotation setting
|
//mesh.rotate(rotation_angle, &origin_of_rotation); // rotates the box according to the config rotation setting
|
||||||
|
|
||||||
|
|
||||||
this->volumes.emplace_back(new GLVolume(color));
|
this->volumes.emplace_back(new GLVolume(color));
|
||||||
GLVolume &v = *this->volumes.back();
|
GLVolume &v = *this->volumes.back();
|
||||||
v.indexed_vertex_array.load_mesh(mesh, use_VBOs);
|
v.indexed_vertex_array.load_mesh(mesh, use_VBOs);
|
||||||
v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0));
|
v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0));
|
||||||
|
v.set_volume_rotation(Vec3d(0., 0., (M_PI/180.) * rotation_angle));
|
||||||
|
|
||||||
// finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry().
|
// finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry().
|
||||||
v.bounding_box = v.indexed_vertex_array.bounding_box();
|
v.bounding_box = v.indexed_vertex_array.bounding_box();
|
||||||
v.indexed_vertex_array.finalize_geometry(use_VBOs);
|
v.indexed_vertex_array.finalize_geometry(use_VBOs);
|
||||||
|
|
|
@ -1201,6 +1201,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
|
||||||
|
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
|
wxDEFINE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>);
|
wxDEFINE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent);
|
||||||
|
@ -3090,6 +3091,10 @@ void GLCanvas3D::do_rotate()
|
||||||
for (const GLVolume* v : m_volumes.volumes)
|
for (const GLVolume* v : m_volumes.volumes)
|
||||||
{
|
{
|
||||||
int object_idx = v->object_idx();
|
int object_idx = v->object_idx();
|
||||||
|
if (object_idx == 1000) { // the wipe tower
|
||||||
|
Vec3d offset = v->get_volume_offset();
|
||||||
|
post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset(0), offset(1), v->get_volume_rotation()(2))));
|
||||||
|
}
|
||||||
if ((object_idx < 0) || ((int)m_model->objects.size() <= object_idx))
|
if ((object_idx < 0) || ((int)m_model->objects.size() <= object_idx))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -4289,6 +4294,7 @@ void GLCanvas3D::_render_selection_sidebar_hints() const
|
||||||
m_shader.stop_using();
|
m_shader.stop_using();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLCanvas3D::_update_volumes_hover_state() const
|
void GLCanvas3D::_update_volumes_hover_state() const
|
||||||
{
|
{
|
||||||
for (GLVolume* v : m_volumes.volumes)
|
for (GLVolume* v : m_volumes.volumes)
|
||||||
|
|
|
@ -116,6 +116,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
|
||||||
|
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
|
wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>);
|
wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>);
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent);
|
||||||
|
|
|
@ -102,7 +102,7 @@ protected:
|
||||||
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 bool on_is_activable(const Selection& selection) const { return !selection.is_wipe_tower(); }
|
virtual bool on_is_activable(const Selection& selection) const { return true; }
|
||||||
virtual void on_enable_grabber(unsigned int id)
|
virtual void on_enable_grabber(unsigned int id)
|
||||||
{
|
{
|
||||||
if ((0 <= id) && (id < 3))
|
if ((0 <= id) && (id < 3))
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "slic3r/GUI/3DScene.hpp"
|
#include "slic3r/GUI/3DScene.hpp"
|
||||||
#include "slic3r/GUI/GUI_App.hpp"
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
|
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
|
||||||
|
#include "slic3r/GUI/PresetBundle.hpp"
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <wx/glcanvas.h>
|
#include <wx/glcanvas.h>
|
||||||
|
@ -264,8 +265,12 @@ void GLGizmosManager::update_data(GLCanvas3D& canvas)
|
||||||
|
|
||||||
const Selection& selection = canvas.get_selection();
|
const Selection& selection = canvas.get_selection();
|
||||||
|
|
||||||
bool enable_move_z = !selection.is_wipe_tower();
|
bool is_wipe_tower = selection.is_wipe_tower();
|
||||||
enable_grabber(Move, 2, enable_move_z);
|
enable_grabber(Move, 2, !is_wipe_tower);
|
||||||
|
enable_grabber(Move, 2, !is_wipe_tower);
|
||||||
|
enable_grabber(Rotate, 0, !is_wipe_tower);
|
||||||
|
enable_grabber(Rotate, 1, !is_wipe_tower);
|
||||||
|
|
||||||
bool enable_scale_xyz = selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier();
|
bool enable_scale_xyz = selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier();
|
||||||
for (int i = 0; i < 6; ++i)
|
for (int i = 0; i < 6; ++i)
|
||||||
{
|
{
|
||||||
|
@ -290,6 +295,14 @@ void GLGizmosManager::update_data(GLCanvas3D& canvas)
|
||||||
set_flattening_data(nullptr);
|
set_flattening_data(nullptr);
|
||||||
set_sla_support_data(nullptr, selection);
|
set_sla_support_data(nullptr, selection);
|
||||||
}
|
}
|
||||||
|
else if (is_wipe_tower)
|
||||||
|
{
|
||||||
|
DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||||
|
set_scale(Vec3d::Ones());
|
||||||
|
set_rotation(Vec3d(0., 0., (M_PI/180.) * dynamic_cast<const ConfigOptionFloat*>(config.option("wipe_tower_rotation_angle"))->value));
|
||||||
|
set_flattening_data(nullptr);
|
||||||
|
set_sla_support_data(nullptr, selection);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
set_scale(Vec3d::Ones());
|
set_scale(Vec3d::Ones());
|
||||||
|
|
|
@ -1307,6 +1307,7 @@ struct Plater::priv
|
||||||
void on_object_select(SimpleEvent&);
|
void on_object_select(SimpleEvent&);
|
||||||
void on_right_click(Vec2dEvent&);
|
void on_right_click(Vec2dEvent&);
|
||||||
void on_wipetower_moved(Vec3dEvent&);
|
void on_wipetower_moved(Vec3dEvent&);
|
||||||
|
void on_wipetower_rotated(Vec3dEvent&);
|
||||||
void on_update_geometry(Vec3dsEvent<2>&);
|
void on_update_geometry(Vec3dsEvent<2>&);
|
||||||
void on_3dcanvas_mouse_dragging_finished(SimpleEvent&);
|
void on_3dcanvas_mouse_dragging_finished(SimpleEvent&);
|
||||||
|
|
||||||
|
@ -1437,6 +1438,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||||
{ if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); });
|
{ if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this);
|
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this);
|
||||||
|
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_ROTATED, &priv::on_wipetower_rotated, this);
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_SCALED, [this](SimpleEvent&) { update(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_SCALED, [this](SimpleEvent&) { update(); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event<bool> &evt) { this->sidebar->enable_buttons(evt.data); });
|
view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event<bool> &evt) { this->sidebar->enable_buttons(evt.data); });
|
||||||
|
@ -1444,6 +1446,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, &priv::on_3dcanvas_mouse_dragging_finished, this);
|
view3D_canvas->Bind(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, &priv::on_3dcanvas_mouse_dragging_finished, this);
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_RESETGIZMOS, [this](SimpleEvent&) { reset_all_gizmos(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_RESETGIZMOS, [this](SimpleEvent&) { reset_all_gizmos(); });
|
||||||
|
|
||||||
// 3DScene/Toolbar:
|
// 3DScene/Toolbar:
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this);
|
view3D_canvas->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this);
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); });
|
||||||
|
@ -2851,6 +2854,15 @@ void Plater::priv::on_wipetower_moved(Vec3dEvent &evt)
|
||||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg);
|
wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Plater::priv::on_wipetower_rotated(Vec3dEvent& evt)
|
||||||
|
{
|
||||||
|
DynamicPrintConfig cfg;
|
||||||
|
cfg.opt<ConfigOptionFloat>("wipe_tower_x", true)->value = evt.data(0);
|
||||||
|
cfg.opt<ConfigOptionFloat>("wipe_tower_y", true)->value = evt.data(1);
|
||||||
|
cfg.opt<ConfigOptionFloat>("wipe_tower_rotation_angle", true)->value = Geometry::rad2deg(evt.data(2));
|
||||||
|
wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
void Plater::priv::on_update_geometry(Vec3dsEvent<2>&)
|
void Plater::priv::on_update_geometry(Vec3dsEvent<2>&)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
|
|
@ -492,6 +492,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
||||||
// Only relative rotation values are allowed in the world coordinate system.
|
// Only relative rotation values are allowed in the world coordinate system.
|
||||||
assert(!transformation_type.world() || transformation_type.relative());
|
assert(!transformation_type.world() || transformation_type.relative());
|
||||||
|
|
||||||
|
if (!is_wipe_tower()) {
|
||||||
int rot_axis_max = 0;
|
int rot_axis_max = 0;
|
||||||
if (rotation.isApprox(Vec3d::Zero()))
|
if (rotation.isApprox(Vec3d::Zero()))
|
||||||
{
|
{
|
||||||
|
@ -510,8 +511,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else { // this is not the wipe tower
|
||||||
{
|
|
||||||
//FIXME this does not work for absolute rotations (transformation_type.absolute() is true)
|
//FIXME this does not work for absolute rotations (transformation_type.absolute() is true)
|
||||||
rotation.cwiseAbs().maxCoeff(&rot_axis_max);
|
rotation.cwiseAbs().maxCoeff(&rot_axis_max);
|
||||||
|
|
||||||
|
@ -580,12 +580,23 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !DISABLE_INSTANCES_SYNCH
|
#if !DISABLE_INSTANCES_SYNCH
|
||||||
if (m_mode == Instance)
|
if (m_mode == Instance)
|
||||||
synchronize_unselected_instances((rot_axis_max == 2) ? SYNC_ROTATION_NONE : SYNC_ROTATION_GENERAL);
|
synchronize_unselected_instances((rot_axis_max == 2) ? SYNC_ROTATION_NONE : SYNC_ROTATION_GENERAL);
|
||||||
else if (m_mode == Volume)
|
else if (m_mode == Volume)
|
||||||
synchronize_unselected_volumes();
|
synchronize_unselected_volumes();
|
||||||
#endif // !DISABLE_INSTANCES_SYNCH
|
#endif // !DISABLE_INSTANCES_SYNCH
|
||||||
|
}
|
||||||
|
else { // it's the wipe tower that's selected and being rotated
|
||||||
|
GLVolume& volume = *((*m_volumes)[*m_list.begin()]); // the wipe tower is always alone in the selection
|
||||||
|
|
||||||
|
// make sure the wipe tower rotates around its center, not origin
|
||||||
|
// we can assume that only Z rotation changes
|
||||||
|
Vec3d center_local = volume.transformed_bounding_box().center() - volume.get_volume_offset();
|
||||||
|
Vec3d center_local_new = Eigen::AngleAxisd(rotation(2)-volume.get_volume_rotation()(2), Vec3d(0, 0, 1)) * center_local;
|
||||||
|
volume.set_volume_rotation(rotation);
|
||||||
|
volume.set_volume_offset(volume.get_volume_offset() + center_local - center_local_new);
|
||||||
|
}
|
||||||
|
|
||||||
m_bounding_box_dirty = true;
|
m_bounding_box_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue