mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-23 16:51:21 -06:00
QoL: 3D navigator (#4181)
* Initial integration of ImGuizmo * Fix mouse capture * Fix frame update * Update face color * Show current camera rotation * Fix coord mapping * Update camera rotation from 3d navigator * Use orthographic * Render axis * Make the axis color lighter if at back * Show axis label * Fix linux build * Move to separate method * Refine * Add option to show/hide 3d navigator * Add license info * Handle dpi scaling --------- Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
parent
4991a3d312
commit
bf4d59a676
15 changed files with 3695 additions and 1 deletions
|
@ -573,7 +573,7 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SLIC3R_GUI_SOURCES})
|
|||
|
||||
encoding_check(libslic3r_gui)
|
||||
|
||||
target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui minilzo GLEW::GLEW OpenGL::GL hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto)
|
||||
target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo GLEW::GLEW OpenGL::GL hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto)
|
||||
#target_link_libraries(libslic3r_gui libslic3r cereal imgui minilzo GLEW::GLEW OpenGL::GL hidapi libcurl OpenSSL::SSL OpenSSL::Crypto ${wxWidgets_LIBRARIES} glfw)
|
||||
|
||||
if (MSVC)
|
||||
|
|
|
@ -100,6 +100,7 @@ void CopyrightsDialog::fill_entries()
|
|||
{ "GLFW", "", "https://www.glfw.org" },
|
||||
{ "GNU gettext", "", "https://www.gnu.org/software/gettext" },
|
||||
{ "ImGUI", "", "https://github.com/ocornut/imgui" },
|
||||
{ "ImGuizmo", "", "https://github.com/CedricGuillemet/ImGuizmo" },
|
||||
{ "Libigl", "", "https://libigl.github.io" },
|
||||
{ "libnest2d", "", "https://github.com/tamasmeszaros/libnest2d" },
|
||||
{ "lib_fts", "", "https://www.forrestthewoods.com" },
|
||||
|
|
|
@ -419,6 +419,15 @@ void Camera::rotate_local_around_target(const Vec3d& rotation_rad)
|
|||
}
|
||||
}
|
||||
|
||||
void Camera::set_rotation(const Transform3d& rotation)
|
||||
{
|
||||
const Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_target;
|
||||
m_view_rotation = Eigen::Quaterniond(rotation.matrix().template block<3, 3>(0, 0));
|
||||
m_view_rotation.normalize();
|
||||
m_view_matrix.fromPositionOrientationScale(m_view_rotation * (-m_target) + translation, m_view_rotation, Vec3d(1., 1., 1.));
|
||||
update_zenit();
|
||||
}
|
||||
|
||||
std::pair<double, double> Camera::calc_tight_frustrum_zs_around(const BoundingBoxf3& box)
|
||||
{
|
||||
std::pair<double, double> ret;
|
||||
|
|
|
@ -146,6 +146,8 @@ public:
|
|||
// rotate the camera around three axes parallel to the camera local axes and passing through m_target
|
||||
void rotate_local_around_target(const Vec3d& rotation_rad);
|
||||
|
||||
void set_rotation(const Transform3d& rotation);
|
||||
|
||||
// returns true if the camera z axis (forward) is pointing in the negative direction of the world z axis
|
||||
bool is_looking_downward() const { return get_dir_forward().dot(Vec3d::UnitZ()) < 0.0; }
|
||||
|
||||
|
|
|
@ -85,6 +85,8 @@
|
|||
#endif
|
||||
#include <imgui/imgui_internal.h>
|
||||
|
||||
#include <imguizmo/ImGuizmo.h>
|
||||
|
||||
static constexpr const float TRACKBALLSIZE = 0.8f;
|
||||
|
||||
static Slic3r::ColorRGBA DEFAULT_BG_LIGHT_COLOR = { 0.906f, 0.906f, 0.906f, 1.0f };
|
||||
|
@ -5535,6 +5537,70 @@ bool GLCanvas3D::_render_arrange_menu(float left, float right, float bottom, flo
|
|||
return settings_changed;
|
||||
}
|
||||
|
||||
static float identityMatrix[16] = {1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f};
|
||||
static const float cameraProjection[16] = {1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f};
|
||||
|
||||
void GLCanvas3D::_render_3d_navigator()
|
||||
{
|
||||
if (!wxGetApp().show_3d_navigator()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuizmo::BeginFrame();
|
||||
ImGuizmo::AllowAxisFlip(false);
|
||||
|
||||
auto& style = ImGuizmo::GetStyle();
|
||||
style.Colors[ImGuizmo::COLOR::DIRECTION_X] = ImGuiWrapper::to_ImVec4(ColorRGBA::Y());
|
||||
style.Colors[ImGuizmo::COLOR::DIRECTION_Y] = ImGuiWrapper::to_ImVec4(ColorRGBA::Z());
|
||||
style.Colors[ImGuizmo::COLOR::DIRECTION_Z] = ImGuiWrapper::to_ImVec4(ColorRGBA::X());
|
||||
strcpy(style.AxisLabels[ImGuizmo::Axis::Axis_X], "y");
|
||||
strcpy(style.AxisLabels[ImGuizmo::Axis::Axis_Y], "z");
|
||||
strcpy(style.AxisLabels[ImGuizmo::Axis::Axis_Z], "x");
|
||||
|
||||
float sc = get_scale();
|
||||
#ifdef WIN32
|
||||
const int dpi = get_dpi_for_window(wxGetApp().GetTopWindow());
|
||||
sc *= (float) dpi / (float) DPI_DEFAULT;
|
||||
#endif // WIN32
|
||||
|
||||
const ImGuiIO& io = ImGui::GetIO();
|
||||
const float viewManipulateLeft = 0;
|
||||
const float viewManipulateTop = io.DisplaySize.y;
|
||||
const float camDistance = 8.f;
|
||||
ImGuizmo::SetID(0);
|
||||
|
||||
Camera& camera = wxGetApp().plater()->get_camera();
|
||||
Transform3d m = Transform3d::Identity();
|
||||
m.matrix().block(0, 0, 3, 3) = camera.get_view_rotation().toRotationMatrix();
|
||||
// Rotate along X and Z axis for 90 degrees to have Y-up
|
||||
const auto coord_mapping_transform = Geometry::rotation_transform(Vec3d(0.5 * PI, 0, 0.5 * PI));
|
||||
m = m * coord_mapping_transform;
|
||||
float cameraView[16];
|
||||
for (unsigned int c = 0; c < 4; ++c) {
|
||||
for (unsigned int r = 0; r < 4; ++r) {
|
||||
cameraView[c * 4 + r] = m(r, c);
|
||||
}
|
||||
}
|
||||
|
||||
const float size = 128 * sc;
|
||||
const bool dirty = ImGuizmo::ViewManipulate(cameraView, cameraProjection, ImGuizmo::OPERATION::ROTATE, ImGuizmo::MODE::WORLD,
|
||||
identityMatrix, camDistance, ImVec2(viewManipulateLeft, viewManipulateTop - size),
|
||||
ImVec2(size, size), 0x10101010);
|
||||
|
||||
if (dirty) {
|
||||
for (unsigned int c = 0; c < 4; ++c) {
|
||||
for (unsigned int r = 0; r < 4; ++r) {
|
||||
m(r, c) = cameraView[c * 4 + r];
|
||||
}
|
||||
}
|
||||
// Rotate back
|
||||
m = m * (coord_mapping_transform.inverse());
|
||||
camera.set_rotation(m);
|
||||
|
||||
request_extra_frame();
|
||||
}
|
||||
}
|
||||
|
||||
#define ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT 0
|
||||
#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT
|
||||
static void debug_output_thumbnail(const ThumbnailData& thumbnail_data)
|
||||
|
@ -7324,6 +7390,8 @@ void GLCanvas3D::_render_overlays()
|
|||
}*/
|
||||
}
|
||||
m_labels.render(sorted_instances);
|
||||
|
||||
_render_3d_navigator();
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_style_editor()
|
||||
|
|
|
@ -1181,6 +1181,7 @@ private:
|
|||
//BBS: GUI refactor: adjust main toolbar position
|
||||
bool _render_orient_menu(float left, float right, float bottom, float top);
|
||||
bool _render_arrange_menu(float left, float right, float bottom, float top);
|
||||
void _render_3d_navigator();
|
||||
// render thumbnail using the default framebuffer
|
||||
void render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<ColorRGBA>& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type);
|
||||
|
||||
|
|
|
@ -329,6 +329,9 @@ private:
|
|||
bool show_gcode_window() const { return m_show_gcode_window; }
|
||||
void toggle_show_gcode_window();
|
||||
|
||||
bool show_3d_navigator() const { return app_config->get_bool("show_3d_navigator"); }
|
||||
void toggle_show_3d_navigator() const { app_config->set_bool("show_3d_navigator", !show_3d_navigator()); }
|
||||
|
||||
wxString get_inf_dialog_contect () {return m_info_dialog_content;};
|
||||
|
||||
std::vector<std::string> split_str(std::string src, std::string separator);
|
||||
|
|
|
@ -2567,6 +2567,15 @@ void MainFrame::init_menubar_as_editor()
|
|||
this, [this]() { return m_tabpanel->GetSelection() == tpPreview; },
|
||||
[this]() { return wxGetApp().show_gcode_window(); }, this);
|
||||
|
||||
append_menu_check_item(
|
||||
viewMenu, wxID_ANY, _L("Show 3D Navigator"), _L("Show 3D navigator in Prepare and Preview scene"),
|
||||
[this](wxCommandEvent&) {
|
||||
wxGetApp().toggle_show_3d_navigator();
|
||||
m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT));
|
||||
},
|
||||
this, [this]() { return m_tabpanel->GetSelection() == TabPosition::tp3DEditor || m_tabpanel->GetSelection() == TabPosition::tpPreview; },
|
||||
[this]() { return wxGetApp().show_3d_navigator(); }, this);
|
||||
|
||||
append_menu_item(
|
||||
viewMenu, wxID_ANY, _L("Reset Window Layout"), _L("Reset to default window layout"),
|
||||
[this](wxCommandEvent&) { m_plater->reset_window_layout(); }, "", this,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue