Fixed conflicts after merge with branch et_perpsective_camera
This commit is contained in:
commit
5766e9e915
14 changed files with 471 additions and 253 deletions
|
@ -13,6 +13,8 @@
|
||||||
#define ENABLE_RENDER_SELECTION_CENTER 0
|
#define ENABLE_RENDER_SELECTION_CENTER 0
|
||||||
// Shows an imgui dialog with render related data
|
// Shows an imgui dialog with render related data
|
||||||
#define ENABLE_RENDER_STATISTICS 0
|
#define ENABLE_RENDER_STATISTICS 0
|
||||||
|
// Shows an imgui dialog with camera related data
|
||||||
|
#define ENABLE_CAMERA_STATISTICS 1
|
||||||
|
|
||||||
|
|
||||||
//====================
|
//====================
|
||||||
|
|
|
@ -212,7 +212,7 @@ const double Bed3D::Axes::ArrowLength = 5.0;
|
||||||
|
|
||||||
Bed3D::Axes::Axes()
|
Bed3D::Axes::Axes()
|
||||||
: origin(Vec3d::Zero())
|
: origin(Vec3d::Zero())
|
||||||
, length(Vec3d::Zero())
|
, length(25.0 * Vec3d::Ones())
|
||||||
{
|
{
|
||||||
m_quadric = ::gluNewQuadric();
|
m_quadric = ::gluNewQuadric();
|
||||||
if (m_quadric != nullptr)
|
if (m_quadric != nullptr)
|
||||||
|
@ -292,7 +292,7 @@ bool Bed3D::set_shape(const Pointfs& shape)
|
||||||
m_shape = shape;
|
m_shape = shape;
|
||||||
m_type = new_type;
|
m_type = new_type;
|
||||||
|
|
||||||
calc_bounding_box();
|
calc_bounding_boxes();
|
||||||
|
|
||||||
ExPolygon poly;
|
ExPolygon poly;
|
||||||
for (const Vec2d& p : m_shape)
|
for (const Vec2d& p : m_shape)
|
||||||
|
@ -313,7 +313,7 @@ bool Bed3D::set_shape(const Pointfs& shape)
|
||||||
|
|
||||||
// Set the origin and size for painting of the coordinate system axes.
|
// Set the origin and size for painting of the coordinate system axes.
|
||||||
m_axes.origin = Vec3d(0.0, 0.0, (double)GROUND_Z);
|
m_axes.origin = Vec3d(0.0, 0.0, (double)GROUND_Z);
|
||||||
m_axes.length = 0.1 * get_bounding_box().max_size() * Vec3d::Ones();
|
m_axes.length = 0.1 * m_bounding_box.max_size() * Vec3d::Ones();
|
||||||
|
|
||||||
// Let the calee to update the UI.
|
// Let the calee to update the UI.
|
||||||
return true;
|
return true;
|
||||||
|
@ -401,13 +401,22 @@ void Bed3D::render_axes() const
|
||||||
m_axes.render();
|
m_axes.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bed3D::calc_bounding_box()
|
void Bed3D::calc_bounding_boxes() const
|
||||||
{
|
{
|
||||||
m_bounding_box = BoundingBoxf3();
|
m_bounding_box = BoundingBoxf3();
|
||||||
for (const Vec2d& p : m_shape)
|
for (const Vec2d& p : m_shape)
|
||||||
{
|
{
|
||||||
m_bounding_box.merge(Vec3d(p(0), p(1), 0.0));
|
m_bounding_box.merge(Vec3d(p(0), p(1), 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_extended_bounding_box = m_bounding_box;
|
||||||
|
|
||||||
|
// extend to contain axes
|
||||||
|
m_extended_bounding_box.merge(m_axes.length + Axes::ArrowLength * Vec3d::Ones());
|
||||||
|
|
||||||
|
// extend to contain model, if any
|
||||||
|
if (!m_model.get_filename().empty())
|
||||||
|
m_extended_bounding_box.merge(m_model.get_transformed_bounding_box());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bed3D::calc_triangles(const ExPolygon& poly)
|
void Bed3D::calc_triangles(const ExPolygon& poly)
|
||||||
|
@ -550,6 +559,9 @@ void Bed3D::render_prusa(GLCanvas3D* canvas, const std::string &key, bool bottom
|
||||||
offset += Vec3d(0.0, 0.0, -0.03);
|
offset += Vec3d(0.0, 0.0, -0.03);
|
||||||
|
|
||||||
m_model.center_around(offset);
|
m_model.center_around(offset);
|
||||||
|
|
||||||
|
// update extended bounding box
|
||||||
|
calc_bounding_boxes();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_model.get_filename().empty())
|
if (!m_model.get_filename().empty())
|
||||||
|
|
|
@ -87,7 +87,8 @@ public:
|
||||||
private:
|
private:
|
||||||
EType m_type;
|
EType m_type;
|
||||||
Pointfs m_shape;
|
Pointfs m_shape;
|
||||||
BoundingBoxf3 m_bounding_box;
|
mutable BoundingBoxf3 m_bounding_box;
|
||||||
|
mutable BoundingBoxf3 m_extended_bounding_box;
|
||||||
Polygon m_polygon;
|
Polygon m_polygon;
|
||||||
GeometryBuffer m_triangles;
|
GeometryBuffer m_triangles;
|
||||||
GeometryBuffer m_gridlines;
|
GeometryBuffer m_gridlines;
|
||||||
|
@ -123,7 +124,7 @@ public:
|
||||||
// Return true if the bed shape changed, so the calee will update the UI.
|
// Return true if the bed shape changed, so the calee will update the UI.
|
||||||
bool set_shape(const Pointfs& shape);
|
bool set_shape(const Pointfs& shape);
|
||||||
|
|
||||||
const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; }
|
const BoundingBoxf3& get_bounding_box(bool extended) const { return extended ? m_extended_bounding_box : m_bounding_box; }
|
||||||
bool contains(const Point& point) const;
|
bool contains(const Point& point) const;
|
||||||
Point point_projection(const Point& point) const;
|
Point point_projection(const Point& point) const;
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ public:
|
||||||
void render_axes() const;
|
void render_axes() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void calc_bounding_box();
|
void calc_bounding_boxes() const;
|
||||||
void calc_triangles(const ExPolygon& poly);
|
void calc_triangles(const ExPolygon& poly);
|
||||||
void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox);
|
void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox);
|
||||||
EType detect_type(const Pointfs& shape) const;
|
EType detect_type(const Pointfs& shape) const;
|
||||||
|
|
|
@ -555,6 +555,7 @@ public:
|
||||||
|
|
||||||
const std::string& get_filename() const { return m_filename; }
|
const std::string& get_filename() const { return m_filename; }
|
||||||
const BoundingBoxf3& get_bounding_box() const { return m_volume.bounding_box; }
|
const BoundingBoxf3& get_bounding_box() const { return m_volume.bounding_box; }
|
||||||
|
const BoundingBoxf3& get_transformed_bounding_box() const { return m_volume.transformed_bounding_box(); }
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,9 @@ void AppConfig::set_defaults()
|
||||||
if (get("custom_toolbar_size").empty())
|
if (get("custom_toolbar_size").empty())
|
||||||
set("custom_toolbar_size", "100");
|
set("custom_toolbar_size", "100");
|
||||||
|
|
||||||
|
if (get("camera_type").empty())
|
||||||
|
set("camera_type", "1");
|
||||||
|
|
||||||
// Remove legacy window positions/sizes
|
// Remove legacy window positions/sizes
|
||||||
erase("", "main_frame_maximized");
|
erase("", "main_frame_maximized");
|
||||||
erase("", "main_frame_pos");
|
erase("", "main_frame_pos");
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "Camera.hpp"
|
#include "Camera.hpp"
|
||||||
#include "3DScene.hpp"
|
#include "3DScene.hpp"
|
||||||
|
#include "GUI_App.hpp"
|
||||||
|
#include "AppConfig.hpp"
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
@ -19,32 +21,71 @@ static const float VIEW_REAR[2] = { 180.0f, 90.0f };
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
const double Camera::DefaultDistance = 1000.0;
|
||||||
|
double Camera::FrustrumMinZSize = 50.0;
|
||||||
|
double Camera::FrustrumZMargin = 10.0;
|
||||||
|
double Camera::FovMinDeg = 5.0;
|
||||||
|
double Camera::FovMaxDeg = 75.0;
|
||||||
|
|
||||||
Camera::Camera()
|
Camera::Camera()
|
||||||
: type(Ortho)
|
: phi(45.0f)
|
||||||
, zoom(1.0f)
|
|
||||||
, phi(45.0f)
|
|
||||||
// , distance(0.0f)
|
|
||||||
, requires_zoom_to_bed(false)
|
, requires_zoom_to_bed(false)
|
||||||
, inverted_phi(false)
|
, inverted_phi(false)
|
||||||
, m_theta(45.0f)
|
, m_type(Ortho)
|
||||||
, m_target(Vec3d::Zero())
|
, m_target(Vec3d::Zero())
|
||||||
|
, m_theta(45.0f)
|
||||||
|
, m_zoom(1.0)
|
||||||
|
, m_distance(DefaultDistance)
|
||||||
|
, m_gui_scale(1.0)
|
||||||
|
, m_view_matrix(Transform3d::Identity())
|
||||||
|
, m_projection_matrix(Transform3d::Identity())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Camera::get_type_as_string() const
|
std::string Camera::get_type_as_string() const
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
default:
|
|
||||||
case Unknown:
|
case Unknown:
|
||||||
return "unknown";
|
return "unknown";
|
||||||
// case Perspective:
|
case Perspective:
|
||||||
// return "perspective";
|
return "perspective";
|
||||||
|
default:
|
||||||
case Ortho:
|
case Ortho:
|
||||||
return "ortho";
|
return "orthographic";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::set_type(EType type)
|
||||||
|
{
|
||||||
|
if (m_type != type)
|
||||||
|
{
|
||||||
|
m_type = type;
|
||||||
|
|
||||||
|
wxGetApp().app_config->set("camera_type", std::to_string(m_type));
|
||||||
|
wxGetApp().app_config->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::set_type(const std::string& type)
|
||||||
|
{
|
||||||
|
if (!type.empty() && (type != "1"))
|
||||||
|
{
|
||||||
|
unsigned char type_id = atoi(type.c_str());
|
||||||
|
if (((unsigned char)Ortho < type_id) && (type_id < (unsigned char)Num_types))
|
||||||
|
set_type((Camera::EType)type_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::select_next_type()
|
||||||
|
{
|
||||||
|
unsigned char next = (unsigned char)m_type + 1;
|
||||||
|
if (next == (unsigned char)Num_types)
|
||||||
|
next = 1;
|
||||||
|
|
||||||
|
set_type((EType)next);
|
||||||
|
}
|
||||||
|
|
||||||
void Camera::set_target(const Vec3d& target)
|
void Camera::set_target(const Vec3d& target)
|
||||||
{
|
{
|
||||||
m_target = target;
|
m_target = target;
|
||||||
|
@ -65,9 +106,20 @@ void Camera::set_theta(float theta, bool apply_limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::set_scene_box(const BoundingBoxf3& box)
|
void Camera::set_zoom(double zoom, const BoundingBoxf3& max_box, int canvas_w, int canvas_h)
|
||||||
{
|
{
|
||||||
m_scene_box = box;
|
zoom = std::max(std::min(zoom, 4.0), -4.0) / 10.0;
|
||||||
|
zoom = m_zoom / (1.0 - zoom);
|
||||||
|
|
||||||
|
// Don't allow to zoom too far outside the scene.
|
||||||
|
double zoom_min = calc_zoom_to_bounding_box_factor(max_box, canvas_w, canvas_h);
|
||||||
|
if (zoom_min > 0.0)
|
||||||
|
zoom = std::max(zoom, zoom_min * 0.7);
|
||||||
|
|
||||||
|
// Don't allow to zoom too close to the scene.
|
||||||
|
zoom = std::min(zoom, 100.0);
|
||||||
|
|
||||||
|
m_zoom = zoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Camera::select_view(const std::string& direction)
|
bool Camera::select_view(const std::string& direction)
|
||||||
|
@ -99,6 +151,18 @@ bool Camera::select_view(const std::string& direction)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Camera::get_fov() const
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case Perspective:
|
||||||
|
return 2.0 * Geometry::rad2deg(std::atan(1.0 / m_projection_matrix.matrix()(1, 1)));
|
||||||
|
default:
|
||||||
|
case Ortho:
|
||||||
|
return 0.0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h) const
|
void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h) const
|
||||||
{
|
{
|
||||||
glsafe(::glViewport(0, 0, w, h));
|
glsafe(::glViewport(0, 0, w, h));
|
||||||
|
@ -107,27 +171,268 @@ void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h) const
|
||||||
|
|
||||||
void Camera::apply_view_matrix() const
|
void Camera::apply_view_matrix() const
|
||||||
{
|
{
|
||||||
|
double theta_rad = Geometry::deg2rad(-(double)m_theta);
|
||||||
|
double phi_rad = Geometry::deg2rad((double)phi);
|
||||||
|
double sin_theta = ::sin(theta_rad);
|
||||||
|
Vec3d camera_pos = m_target + m_distance * Vec3d(sin_theta * ::sin(phi_rad), sin_theta * ::cos(phi_rad), ::cos(theta_rad));
|
||||||
|
|
||||||
glsafe(::glMatrixMode(GL_MODELVIEW));
|
glsafe(::glMatrixMode(GL_MODELVIEW));
|
||||||
glsafe(::glLoadIdentity());
|
glsafe(::glLoadIdentity());
|
||||||
|
|
||||||
glsafe(::glRotatef(-m_theta, 1.0f, 0.0f, 0.0f)); // pitch
|
glsafe(::glRotatef(-m_theta, 1.0f, 0.0f, 0.0f)); // pitch
|
||||||
glsafe(::glRotatef(phi, 0.0f, 0.0f, 1.0f)); // yaw
|
glsafe(::glRotatef(phi, 0.0f, 0.0f, 1.0f)); // yaw
|
||||||
glsafe(::glTranslated(-m_target(0), -m_target(1), -m_target(2)));
|
|
||||||
|
glsafe(::glTranslated(-camera_pos(0), -camera_pos(1), -camera_pos(2)));
|
||||||
|
|
||||||
glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, m_view_matrix.data()));
|
glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, m_view_matrix.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::apply_ortho_projection(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max) const
|
void Camera::apply_projection(const BoundingBoxf3& box) const
|
||||||
{
|
{
|
||||||
|
m_distance = DefaultDistance;
|
||||||
|
double w = 0.0;
|
||||||
|
double h = 0.0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
m_frustrum_zs = calc_tight_frustrum_zs_around(box);
|
||||||
|
|
||||||
|
w = (double)m_viewport[2];
|
||||||
|
h = (double)m_viewport[3];
|
||||||
|
|
||||||
|
double two_zoom = 2.0 * m_zoom;
|
||||||
|
if (two_zoom != 0.0)
|
||||||
|
{
|
||||||
|
double inv_two_zoom = 1.0 / two_zoom;
|
||||||
|
w *= inv_two_zoom;
|
||||||
|
h *= inv_two_zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case Ortho:
|
||||||
|
{
|
||||||
|
m_gui_scale = 1.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Perspective:
|
||||||
|
{
|
||||||
|
// scale near plane to keep w and h constant on the plane at z = m_distance
|
||||||
|
double scale = m_frustrum_zs.first / m_distance;
|
||||||
|
w *= scale;
|
||||||
|
h *= scale;
|
||||||
|
m_gui_scale = scale;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_type == Perspective)
|
||||||
|
{
|
||||||
|
double fov_rad = 2.0 * std::atan(h / m_frustrum_zs.first);
|
||||||
|
double fov_deg = Geometry::rad2deg(fov_rad);
|
||||||
|
|
||||||
|
// adjust camera distance to keep fov in a limited range
|
||||||
|
if (fov_deg > FovMaxDeg + 0.001)
|
||||||
|
{
|
||||||
|
double new_near_z = h / ::tan(0.5 * Geometry::deg2rad(FovMaxDeg));
|
||||||
|
m_distance += (new_near_z - m_frustrum_zs.first);
|
||||||
|
apply_view_matrix();
|
||||||
|
}
|
||||||
|
else if (fov_deg < FovMinDeg - 0.001)
|
||||||
|
{
|
||||||
|
double new_near_z = h / ::tan(0.5 * Geometry::deg2rad(FovMinDeg));
|
||||||
|
m_distance += (new_near_z - m_frustrum_zs.first);
|
||||||
|
apply_view_matrix();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
glsafe(::glMatrixMode(GL_PROJECTION));
|
glsafe(::glMatrixMode(GL_PROJECTION));
|
||||||
glsafe(::glLoadIdentity());
|
glsafe(::glLoadIdentity());
|
||||||
|
|
||||||
glsafe(::glOrtho(x_min, x_max, y_min, y_max, z_min, z_max));
|
switch (m_type)
|
||||||
glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, m_projection_matrix.data()));
|
{
|
||||||
|
default:
|
||||||
|
case Ortho:
|
||||||
|
{
|
||||||
|
glsafe(::glOrtho(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Perspective:
|
||||||
|
{
|
||||||
|
glsafe(::glFrustum(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, m_projection_matrix.data()));
|
||||||
glsafe(::glMatrixMode(GL_MODELVIEW));
|
glsafe(::glMatrixMode(GL_MODELVIEW));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h)
|
||||||
|
{
|
||||||
|
// Calculate the zoom factor needed to adjust the view around the given box.
|
||||||
|
double zoom = calc_zoom_to_bounding_box_factor(box, canvas_w, canvas_h);
|
||||||
|
if (zoom > 0.0)
|
||||||
|
{
|
||||||
|
m_zoom = zoom;
|
||||||
|
// center view around box center
|
||||||
|
m_target = box.center();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ENABLE_CAMERA_STATISTICS
|
||||||
|
void Camera::debug_render() const
|
||||||
|
{
|
||||||
|
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||||
|
imgui.set_next_window_bg_alpha(0.5f);
|
||||||
|
imgui.begin(std::string("Camera statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||||
|
|
||||||
|
std::string type = get_type_as_string();
|
||||||
|
Vec3f position = get_position().cast<float>();
|
||||||
|
Vec3f target = m_target.cast<float>();
|
||||||
|
float distance = (float)get_distance();
|
||||||
|
Vec3f forward = get_dir_forward().cast<float>();
|
||||||
|
Vec3f right = get_dir_right().cast<float>();
|
||||||
|
Vec3f up = get_dir_up().cast<float>();
|
||||||
|
float nearZ = (float)m_frustrum_zs.first;
|
||||||
|
float farZ = (float)m_frustrum_zs.second;
|
||||||
|
float deltaZ = farZ - nearZ;
|
||||||
|
float zoom = (float)m_zoom;
|
||||||
|
float fov = (float)get_fov();
|
||||||
|
float gui_scale = (float)get_gui_scale();
|
||||||
|
|
||||||
|
ImGui::InputText("Type", const_cast<char*>(type.data()), type.length(), ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::InputFloat3("Position", position.data(), "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::InputFloat3("Target", target.data(), "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::InputFloat("Distance", &distance, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::InputFloat3("Forward", forward.data(), "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::InputFloat3("Right", right.data(), "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::InputFloat3("Up", up.data(), "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::InputFloat("Near Z", &nearZ, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::InputFloat("Far Z", &farZ, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::InputFloat("Delta Z", &deltaZ, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::InputFloat("Zoom", &zoom, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::InputFloat("Fov", &fov, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::InputFloat("GUI scale", &gui_scale, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly);
|
||||||
|
imgui.end();
|
||||||
|
}
|
||||||
|
#endif // ENABLE_CAMERA_STATISTICS
|
||||||
|
|
||||||
|
std::pair<double, double> Camera::calc_tight_frustrum_zs_around(const BoundingBoxf3& box) const
|
||||||
|
{
|
||||||
|
std::pair<double, double> ret = std::make_pair(DBL_MAX, -DBL_MAX);
|
||||||
|
|
||||||
|
Vec3d bb_min = box.min;
|
||||||
|
Vec3d bb_max = box.max;
|
||||||
|
|
||||||
|
// box vertices in world space
|
||||||
|
std::vector<Vec3d> vertices;
|
||||||
|
vertices.reserve(8);
|
||||||
|
vertices.push_back(bb_min);
|
||||||
|
vertices.emplace_back(bb_max(0), bb_min(1), bb_min(2));
|
||||||
|
vertices.emplace_back(bb_max(0), bb_max(1), bb_min(2));
|
||||||
|
vertices.emplace_back(bb_min(0), bb_max(1), bb_min(2));
|
||||||
|
vertices.emplace_back(bb_min(0), bb_min(1), bb_max(2));
|
||||||
|
vertices.emplace_back(bb_max(0), bb_min(1), bb_max(2));
|
||||||
|
vertices.push_back(bb_max);
|
||||||
|
vertices.emplace_back(bb_min(0), bb_max(1), bb_max(2));
|
||||||
|
|
||||||
|
// set the Z range in eye coordinates (negative Zs are in front of the camera)
|
||||||
|
for (const Vec3d& v : vertices)
|
||||||
|
{
|
||||||
|
double z = -(m_view_matrix * v)(2);
|
||||||
|
ret.first = std::min(ret.first, z);
|
||||||
|
ret.second = std::max(ret.second, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply margin
|
||||||
|
ret.first -= FrustrumZMargin;
|
||||||
|
ret.second += FrustrumZMargin;
|
||||||
|
|
||||||
|
// ensure min size
|
||||||
|
if (ret.second - ret.first < FrustrumMinZSize)
|
||||||
|
{
|
||||||
|
double mid_z = 0.5 * (ret.first + ret.second);
|
||||||
|
double half_size = 0.5 * FrustrumMinZSize;
|
||||||
|
ret.first = mid_z - half_size;
|
||||||
|
ret.second = mid_z + half_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h) const
|
||||||
|
{
|
||||||
|
double max_bb_size = box.max_size();
|
||||||
|
if (max_bb_size == 0.0)
|
||||||
|
return -1.0;
|
||||||
|
|
||||||
|
// project the box vertices on a plane perpendicular to the camera forward axis
|
||||||
|
// then calculates the vertices coordinate on this plane along the camera xy axes
|
||||||
|
|
||||||
|
// ensure that the view matrix is updated
|
||||||
|
apply_view_matrix();
|
||||||
|
|
||||||
|
Vec3d right = get_dir_right();
|
||||||
|
Vec3d up = get_dir_up();
|
||||||
|
Vec3d forward = get_dir_forward();
|
||||||
|
|
||||||
|
Vec3d bb_min = box.min;
|
||||||
|
Vec3d bb_max = box.max;
|
||||||
|
Vec3d bb_center = box.center();
|
||||||
|
|
||||||
|
// box vertices in world space
|
||||||
|
std::vector<Vec3d> vertices;
|
||||||
|
vertices.reserve(8);
|
||||||
|
vertices.push_back(bb_min);
|
||||||
|
vertices.emplace_back(bb_max(0), bb_min(1), bb_min(2));
|
||||||
|
vertices.emplace_back(bb_max(0), bb_max(1), bb_min(2));
|
||||||
|
vertices.emplace_back(bb_min(0), bb_max(1), bb_min(2));
|
||||||
|
vertices.emplace_back(bb_min(0), bb_min(1), bb_max(2));
|
||||||
|
vertices.emplace_back(bb_max(0), bb_min(1), bb_max(2));
|
||||||
|
vertices.push_back(bb_max);
|
||||||
|
vertices.emplace_back(bb_min(0), bb_max(1), bb_max(2));
|
||||||
|
|
||||||
|
double max_x = 0.0;
|
||||||
|
double max_y = 0.0;
|
||||||
|
|
||||||
|
// margin factor to give some empty space around the box
|
||||||
|
double margin_factor = 1.25;
|
||||||
|
|
||||||
|
for (const Vec3d& v : vertices)
|
||||||
|
{
|
||||||
|
// project vertex on the plane perpendicular to camera forward axis
|
||||||
|
Vec3d pos(v(0) - bb_center(0), v(1) - bb_center(1), v(2) - bb_center(2));
|
||||||
|
Vec3d proj_on_plane = pos - pos.dot(forward) * forward;
|
||||||
|
|
||||||
|
// calculates vertex coordinate along camera xy axes
|
||||||
|
double x_on_plane = proj_on_plane.dot(right);
|
||||||
|
double y_on_plane = proj_on_plane.dot(up);
|
||||||
|
|
||||||
|
max_x = std::max(max_x, std::abs(x_on_plane));
|
||||||
|
max_y = std::max(max_y, std::abs(y_on_plane));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((max_x == 0.0) || (max_y == 0.0))
|
||||||
|
return -1.0f;
|
||||||
|
|
||||||
|
max_x *= margin_factor;
|
||||||
|
max_y *= margin_factor;
|
||||||
|
|
||||||
|
return std::min((double)canvas_w / (2.0 * max_x), (double)canvas_h / (2.0 * max_y));
|
||||||
|
}
|
||||||
|
|
||||||
} // GUI
|
} // GUI
|
||||||
} // Slic3r
|
} // Slic3r
|
||||||
|
|
||||||
|
|
|
@ -9,44 +9,64 @@ namespace GUI {
|
||||||
|
|
||||||
struct Camera
|
struct Camera
|
||||||
{
|
{
|
||||||
|
static const double DefaultDistance;
|
||||||
|
static double FrustrumMinZSize;
|
||||||
|
static double FrustrumZMargin;
|
||||||
|
static double FovMinDeg;
|
||||||
|
static double FovMaxDeg;
|
||||||
|
|
||||||
enum EType : unsigned char
|
enum EType : unsigned char
|
||||||
{
|
{
|
||||||
Unknown,
|
Unknown,
|
||||||
// Perspective,
|
|
||||||
Ortho,
|
Ortho,
|
||||||
|
Perspective,
|
||||||
Num_types
|
Num_types
|
||||||
};
|
};
|
||||||
|
|
||||||
EType type;
|
|
||||||
float zoom;
|
|
||||||
float phi;
|
float phi;
|
||||||
// float distance;
|
|
||||||
bool requires_zoom_to_bed;
|
bool requires_zoom_to_bed;
|
||||||
bool inverted_phi;
|
bool inverted_phi;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
EType m_type;
|
||||||
Vec3d m_target;
|
Vec3d m_target;
|
||||||
float m_theta;
|
float m_theta;
|
||||||
|
double m_zoom;
|
||||||
|
// Distance between camera position and camera target measured along the camera Z axis
|
||||||
|
mutable double m_distance;
|
||||||
|
mutable double m_gui_scale;
|
||||||
|
|
||||||
mutable std::array<int, 4> m_viewport;
|
mutable std::array<int, 4> m_viewport;
|
||||||
mutable Transform3d m_view_matrix;
|
mutable Transform3d m_view_matrix;
|
||||||
mutable Transform3d m_projection_matrix;
|
mutable Transform3d m_projection_matrix;
|
||||||
|
mutable std::pair<double, double> m_frustrum_zs;
|
||||||
|
|
||||||
BoundingBoxf3 m_scene_box;
|
BoundingBoxf3 m_scene_box;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Camera();
|
Camera();
|
||||||
|
|
||||||
|
EType get_type() const { return m_type; }
|
||||||
std::string get_type_as_string() const;
|
std::string get_type_as_string() const;
|
||||||
|
void set_type(EType type);
|
||||||
|
void set_type(const std::string& type);
|
||||||
|
void select_next_type();
|
||||||
|
|
||||||
const Vec3d& get_target() const { return m_target; }
|
const Vec3d& get_target() const { return m_target; }
|
||||||
void set_target(const Vec3d& target);
|
void set_target(const Vec3d& target);
|
||||||
|
|
||||||
|
double get_distance() const { return m_distance; }
|
||||||
|
double get_gui_scale() const { return m_gui_scale; }
|
||||||
|
|
||||||
float get_theta() const { return m_theta; }
|
float get_theta() const { return m_theta; }
|
||||||
void set_theta(float theta, bool apply_limit);
|
void set_theta(float theta, bool apply_limit);
|
||||||
|
|
||||||
|
double get_zoom() const { return m_zoom; }
|
||||||
|
void set_zoom(double zoom, const BoundingBoxf3& max_box, int canvas_w, int canvas_h);
|
||||||
|
void set_zoom(double zoom) { m_zoom = zoom; }
|
||||||
|
|
||||||
const BoundingBoxf3& get_scene_box() const { return m_scene_box; }
|
const BoundingBoxf3& get_scene_box() const { return m_scene_box; }
|
||||||
void set_scene_box(const BoundingBoxf3& box);
|
void set_scene_box(const BoundingBoxf3& box) { m_scene_box = box; }
|
||||||
|
|
||||||
bool select_view(const std::string& direction);
|
bool select_view(const std::string& direction);
|
||||||
|
|
||||||
|
@ -60,9 +80,26 @@ public:
|
||||||
|
|
||||||
Vec3d get_position() const { return m_view_matrix.matrix().inverse().block(0, 3, 3, 1); }
|
Vec3d get_position() const { return m_view_matrix.matrix().inverse().block(0, 3, 3, 1); }
|
||||||
|
|
||||||
|
double get_near_z() const { return m_frustrum_zs.first; }
|
||||||
|
double get_far_z() const { return m_frustrum_zs.second; }
|
||||||
|
|
||||||
|
double get_fov() const;
|
||||||
|
|
||||||
void apply_viewport(int x, int y, unsigned int w, unsigned int h) const;
|
void apply_viewport(int x, int y, unsigned int w, unsigned int h) const;
|
||||||
void apply_view_matrix() const;
|
void apply_view_matrix() const;
|
||||||
void apply_ortho_projection(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max) const;
|
void apply_projection(const BoundingBoxf3& box) const;
|
||||||
|
|
||||||
|
void zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h);
|
||||||
|
|
||||||
|
#if ENABLE_CAMERA_STATISTICS
|
||||||
|
void debug_render() const;
|
||||||
|
#endif // ENABLE_CAMERA_STATISTICS
|
||||||
|
|
||||||
|
private:
|
||||||
|
// returns tight values for nearZ and farZ plane around the given bounding box
|
||||||
|
// the camera MUST be outside of the bounding box in eye coordinate of the given box
|
||||||
|
std::pair<double, double> calc_tight_frustrum_zs_around(const BoundingBoxf3& box) const;
|
||||||
|
double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // GUI
|
} // GUI
|
||||||
|
|
|
@ -300,22 +300,10 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
|
||||||
const Rect& bar_rect = get_bar_rect_viewport(canvas);
|
const Rect& bar_rect = get_bar_rect_viewport(canvas);
|
||||||
const Rect& reset_rect = get_reset_rect_viewport(canvas);
|
const Rect& reset_rect = get_reset_rect_viewport(canvas);
|
||||||
|
|
||||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
|
||||||
|
|
||||||
// The viewport and camera are set to complete view and glOrtho(-$x / 2, $x / 2, -$y / 2, $y / 2, -$depth, $depth),
|
|
||||||
// where x, y is the window size divided by $self->_zoom.
|
|
||||||
glsafe(::glPushMatrix());
|
|
||||||
glsafe(::glLoadIdentity());
|
|
||||||
|
|
||||||
_render_tooltip_texture(canvas, bar_rect, reset_rect);
|
_render_tooltip_texture(canvas, bar_rect, reset_rect);
|
||||||
_render_reset_texture(reset_rect);
|
_render_reset_texture(reset_rect);
|
||||||
_render_active_object_annotations(canvas, bar_rect);
|
_render_active_object_annotations(canvas, bar_rect);
|
||||||
_render_profile(bar_rect);
|
_render_profile(bar_rect);
|
||||||
|
|
||||||
// Revert the matrices.
|
|
||||||
glsafe(::glPopMatrix());
|
|
||||||
|
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
|
float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
|
||||||
|
@ -370,7 +358,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
|
||||||
float half_w = 0.5f * (float)cnv_size.get_width();
|
float half_w = 0.5f * (float)cnv_size.get_width();
|
||||||
float half_h = 0.5f * (float)cnv_size.get_height();
|
float half_h = 0.5f * (float)cnv_size.get_height();
|
||||||
|
|
||||||
float zoom = canvas.get_camera().zoom;
|
float zoom = (float)canvas.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
|
|
||||||
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom);
|
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom);
|
||||||
|
@ -382,7 +370,7 @@ Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas
|
||||||
float half_w = 0.5f * (float)cnv_size.get_width();
|
float half_w = 0.5f * (float)cnv_size.get_width();
|
||||||
float half_h = 0.5f * (float)cnv_size.get_height();
|
float half_h = 0.5f * (float)cnv_size.get_height();
|
||||||
|
|
||||||
float zoom = canvas.get_camera().zoom;
|
float zoom = (float)canvas.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
|
|
||||||
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom);
|
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom);
|
||||||
|
@ -413,7 +401,7 @@ void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas
|
||||||
const float width = (float)m_tooltip_texture.get_width() * scale;
|
const float width = (float)m_tooltip_texture.get_width() * scale;
|
||||||
const float height = (float)m_tooltip_texture.get_height() * scale;
|
const float height = (float)m_tooltip_texture.get_height() * scale;
|
||||||
|
|
||||||
float zoom = canvas.get_camera().zoom;
|
float zoom = (float)canvas.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
float gap = 10.0f * inv_zoom;
|
float gap = 10.0f * inv_zoom;
|
||||||
|
|
||||||
|
@ -882,12 +870,8 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const
|
||||||
|
|
||||||
if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0))
|
if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0))
|
||||||
{
|
{
|
||||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
|
||||||
glsafe(::glPushMatrix());
|
|
||||||
glsafe(::glLoadIdentity());
|
|
||||||
|
|
||||||
const Size& cnv_size = canvas.get_canvas_size();
|
const Size& cnv_size = canvas.get_canvas_size();
|
||||||
float zoom = canvas.get_camera().zoom;
|
float zoom = (float)canvas.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
float left = (-0.5f * (float)m_original_width) * inv_zoom;
|
float left = (-0.5f * (float)m_original_width) * inv_zoom;
|
||||||
float top = (-0.5f * (float)cnv_size.get_height() + (float)m_original_height + 2.0f) * inv_zoom;
|
float top = (-0.5f * (float)cnv_size.get_height() + (float)m_original_height + 2.0f) * inv_zoom;
|
||||||
|
@ -906,9 +890,6 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const
|
||||||
uvs.right_top = { uv_right, uv_top };
|
uvs.right_top = { uv_right, uv_top };
|
||||||
|
|
||||||
GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs);
|
GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs);
|
||||||
|
|
||||||
glsafe(::glPopMatrix());
|
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1165,12 +1146,8 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const
|
||||||
{
|
{
|
||||||
if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0))
|
if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0))
|
||||||
{
|
{
|
||||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
|
||||||
glsafe(::glPushMatrix());
|
|
||||||
glsafe(::glLoadIdentity());
|
|
||||||
|
|
||||||
const Size& cnv_size = canvas.get_canvas_size();
|
const Size& cnv_size = canvas.get_canvas_size();
|
||||||
float zoom = canvas.get_camera().zoom;
|
float zoom = (float)canvas.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
float left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom;
|
float left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom;
|
||||||
float top = (0.5f * (float)cnv_size.get_height()) * inv_zoom;
|
float top = (0.5f * (float)cnv_size.get_height()) * inv_zoom;
|
||||||
|
@ -1189,9 +1166,6 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const
|
||||||
uvs.right_top = { uv_right, uv_top };
|
uvs.right_top = { uv_right, uv_top };
|
||||||
|
|
||||||
GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs);
|
GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs);
|
||||||
|
|
||||||
glsafe(::glPopMatrix());
|
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1476,7 +1450,7 @@ BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const
|
||||||
BoundingBoxf3 GLCanvas3D::scene_bounding_box() const
|
BoundingBoxf3 GLCanvas3D::scene_bounding_box() const
|
||||||
{
|
{
|
||||||
BoundingBoxf3 bb = volumes_bounding_box();
|
BoundingBoxf3 bb = volumes_bounding_box();
|
||||||
bb.merge(m_bed.get_bounding_box());
|
bb.merge(m_bed.get_bounding_box(false));
|
||||||
|
|
||||||
if (m_config != nullptr)
|
if (m_config != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -1484,6 +1458,7 @@ BoundingBoxf3 GLCanvas3D::scene_bounding_box() const
|
||||||
bb.min(2) = std::min(bb.min(2), -h);
|
bb.min(2) = std::min(bb.min(2), -h);
|
||||||
bb.max(2) = std::max(bb.max(2), h);
|
bb.max(2) = std::max(bb.max(2), h);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1559,20 +1534,20 @@ void GLCanvas3D::allow_multisample(bool allow)
|
||||||
|
|
||||||
void GLCanvas3D::zoom_to_bed()
|
void GLCanvas3D::zoom_to_bed()
|
||||||
{
|
{
|
||||||
_zoom_to_bounding_box(m_bed.get_bounding_box());
|
_zoom_to_box(m_bed.get_bounding_box(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::zoom_to_volumes()
|
void GLCanvas3D::zoom_to_volumes()
|
||||||
{
|
{
|
||||||
m_apply_zoom_to_volumes_filter = true;
|
m_apply_zoom_to_volumes_filter = true;
|
||||||
_zoom_to_bounding_box(volumes_bounding_box());
|
_zoom_to_box(volumes_bounding_box());
|
||||||
m_apply_zoom_to_volumes_filter = false;
|
m_apply_zoom_to_volumes_filter = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::zoom_to_selection()
|
void GLCanvas3D::zoom_to_selection()
|
||||||
{
|
{
|
||||||
if (!m_selection.is_empty())
|
if (!m_selection.is_empty())
|
||||||
_zoom_to_bounding_box(m_selection.get_bounding_box());
|
_zoom_to_box(m_selection.get_bounding_box());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::select_view(const std::string& direction)
|
void GLCanvas3D::select_view(const std::string& direction)
|
||||||
|
@ -1633,6 +1608,7 @@ void GLCanvas3D::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_camera.apply_view_matrix();
|
m_camera.apply_view_matrix();
|
||||||
|
m_camera.apply_projection(_max_bounding_box(true));
|
||||||
|
|
||||||
GLfloat position_cam[4] = { 1.0f, 0.0f, 1.0f, 0.0f };
|
GLfloat position_cam[4] = { 1.0f, 0.0f, 1.0f, 0.0f };
|
||||||
glsafe(::glLightfv(GL_LIGHT1, GL_POSITION, position_cam));
|
glsafe(::glLightfv(GL_LIGHT1, GL_POSITION, position_cam));
|
||||||
|
@ -1694,16 +1670,7 @@ void GLCanvas3D::render()
|
||||||
m_rectangle_selection.render(*this);
|
m_rectangle_selection.render(*this);
|
||||||
|
|
||||||
// draw overlays
|
// draw overlays
|
||||||
_render_gizmos_overlay();
|
_render_overlays();
|
||||||
_render_warning_texture();
|
|
||||||
_render_legend_texture();
|
|
||||||
#if !ENABLE_SVG_ICONS
|
|
||||||
_resize_toolbars();
|
|
||||||
#endif // !ENABLE_SVG_ICONS
|
|
||||||
_render_toolbar();
|
|
||||||
_render_view_toolbar();
|
|
||||||
if ((m_layers_editing.last_object_id >= 0) && (m_layers_editing.object_max_z() > 0.0f))
|
|
||||||
m_layers_editing.render_overlay(*this);
|
|
||||||
|
|
||||||
#if ENABLE_RENDER_STATISTICS
|
#if ENABLE_RENDER_STATISTICS
|
||||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||||
|
@ -1724,6 +1691,10 @@ void GLCanvas3D::render()
|
||||||
imgui.end();
|
imgui.end();
|
||||||
#endif // ENABLE_RENDER_STATISTICS
|
#endif // ENABLE_RENDER_STATISTICS
|
||||||
|
|
||||||
|
#if ENABLE_CAMERA_STATISTICS
|
||||||
|
m_camera.debug_render();
|
||||||
|
#endif // ENABLE_CAMERA_STATISTICS
|
||||||
|
|
||||||
wxGetApp().imgui()->render();
|
wxGetApp().imgui()->render();
|
||||||
|
|
||||||
m_canvas->SwapBuffers();
|
m_canvas->SwapBuffers();
|
||||||
|
@ -2426,9 +2397,11 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
|
||||||
case 'B':
|
case 'B':
|
||||||
case 'b': { zoom_to_bed(); break; }
|
case 'b': { zoom_to_bed(); break; }
|
||||||
case 'I':
|
case 'I':
|
||||||
case 'i': { set_camera_zoom(1.0f); break; }
|
case 'i': { set_camera_zoom(1.0); break; }
|
||||||
|
case 'K':
|
||||||
|
case 'k': { m_camera.select_next_type(); m_dirty = true; break; }
|
||||||
case 'O':
|
case 'O':
|
||||||
case 'o': { set_camera_zoom(-1.0f); break; }
|
case 'o': { set_camera_zoom(-1.0); break; }
|
||||||
case 'Z':
|
case 'Z':
|
||||||
case 'z': { m_selection.is_empty() ? zoom_to_volumes() : zoom_to_selection(); break; }
|
case 'z': { m_selection.is_empty() ? zoom_to_volumes() : zoom_to_selection(); break; }
|
||||||
default: { evt.Skip(); break; }
|
default: { evt.Skip(); break; }
|
||||||
|
@ -2560,8 +2533,7 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Calculate the zoom delta and apply it to the current zoom factor
|
// Calculate the zoom delta and apply it to the current zoom factor
|
||||||
float zoom = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta();
|
set_camera_zoom((double)evt.GetWheelRotation() / (double)evt.GetWheelDelta());
|
||||||
set_camera_zoom(zoom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::on_timer(wxTimerEvent& evt)
|
void GLCanvas3D::on_timer(wxTimerEvent& evt)
|
||||||
|
@ -3313,21 +3285,11 @@ void GLCanvas3D::do_mirror()
|
||||||
post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::set_camera_zoom(float zoom)
|
void GLCanvas3D::set_camera_zoom(double zoom)
|
||||||
{
|
{
|
||||||
zoom = std::max(std::min(zoom, 4.0f), -4.0f) / 10.0f;
|
const Size& cnv_size = get_canvas_size();
|
||||||
zoom = m_camera.zoom / (1.0f - zoom);
|
m_camera.set_zoom(zoom, _max_bounding_box(false), cnv_size.get_width(), cnv_size.get_height());
|
||||||
|
m_dirty = true;
|
||||||
// Don't allow to zoom too far outside the scene.
|
|
||||||
float zoom_min = _get_zoom_to_bounding_box_factor(_max_bounding_box());
|
|
||||||
if (zoom_min > 0.0f)
|
|
||||||
zoom = std::max(zoom, zoom_min * 0.7f);
|
|
||||||
|
|
||||||
// Don't allow to zoom too close to the scene.
|
|
||||||
zoom = std::min(zoom, 100.0f);
|
|
||||||
|
|
||||||
m_camera.zoom = zoom;
|
|
||||||
_refresh_if_shown_on_screen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::update_gizmos_on_off_state()
|
void GLCanvas3D::update_gizmos_on_off_state()
|
||||||
|
@ -3361,8 +3323,7 @@ void GLCanvas3D::update_ui_from_settings()
|
||||||
if (new_scaling != orig_scaling) {
|
if (new_scaling != orig_scaling) {
|
||||||
BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Scaling factor: " << new_scaling;
|
BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Scaling factor: " << new_scaling;
|
||||||
|
|
||||||
m_camera.zoom /= orig_scaling;
|
m_camera.set_zoom(m_camera.get_zoom() * new_scaling / orig_scaling);
|
||||||
m_camera.zoom *= new_scaling;
|
|
||||||
_refresh_if_shown_on_screen();
|
_refresh_if_shown_on_screen();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3409,7 +3370,7 @@ Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos)
|
||||||
|
|
||||||
double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const
|
double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const
|
||||||
{
|
{
|
||||||
return factor * m_bed.get_bounding_box().max_size();
|
return factor * m_bed.get_bounding_box(false).max_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::set_cursor(ECursorType type)
|
void GLCanvas3D::set_cursor(ECursorType type)
|
||||||
|
@ -3640,143 +3601,25 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
|
||||||
|
|
||||||
// ensures that this canvas is current
|
// ensures that this canvas is current
|
||||||
_set_current();
|
_set_current();
|
||||||
|
|
||||||
|
// updates camera
|
||||||
m_camera.apply_viewport(0, 0, w, h);
|
m_camera.apply_viewport(0, 0, w, h);
|
||||||
|
|
||||||
const BoundingBoxf3& bbox = _max_bounding_box();
|
|
||||||
|
|
||||||
switch (m_camera.type)
|
|
||||||
{
|
|
||||||
case Camera::Ortho:
|
|
||||||
{
|
|
||||||
float w2 = w;
|
|
||||||
float h2 = h;
|
|
||||||
float two_zoom = 2.0f * m_camera.zoom;
|
|
||||||
if (two_zoom != 0.0f)
|
|
||||||
{
|
|
||||||
float inv_two_zoom = 1.0f / two_zoom;
|
|
||||||
w2 *= inv_two_zoom;
|
|
||||||
h2 *= inv_two_zoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: calculate a tighter value for depth will improve z-fighting
|
|
||||||
// Set at least some minimum depth in case the bounding box is empty to avoid an OpenGL driver error.
|
|
||||||
float depth = std::max(1.f, 5.0f * (float)bbox.max_size());
|
|
||||||
m_camera.apply_ortho_projection(-w2, w2, -h2, h2, -depth, depth);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// case Camera::Perspective:
|
|
||||||
// {
|
|
||||||
// float bbox_r = (float)bbox.radius();
|
|
||||||
// float fov = PI * 45.0f / 180.0f;
|
|
||||||
// float fov_tan = tan(0.5f * fov);
|
|
||||||
// float cam_distance = 0.5f * bbox_r / fov_tan;
|
|
||||||
// m_camera.distance = cam_distance;
|
|
||||||
//
|
|
||||||
// float nr = cam_distance - bbox_r * 1.1f;
|
|
||||||
// float fr = cam_distance + bbox_r * 1.1f;
|
|
||||||
// if (nr < 1.0f)
|
|
||||||
// nr = 1.0f;
|
|
||||||
//
|
|
||||||
// if (fr < nr + 1.0f)
|
|
||||||
// fr = nr + 1.0f;
|
|
||||||
//
|
|
||||||
// float h2 = fov_tan * nr;
|
|
||||||
// float w2 = h2 * w / h;
|
|
||||||
// ::glFrustum(-w2, w2, -h2, h2, nr, fr);
|
|
||||||
//
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Invalid camera type.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBoxf3 GLCanvas3D::_max_bounding_box() const
|
BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_bed_model) const
|
||||||
{
|
{
|
||||||
BoundingBoxf3 bb = volumes_bounding_box();
|
BoundingBoxf3 bb = volumes_bounding_box();
|
||||||
bb.merge(m_bed.get_bounding_box());
|
bb.merge(m_bed.get_bounding_box(include_bed_model));
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox)
|
void GLCanvas3D::_zoom_to_box(const BoundingBoxf3& box)
|
||||||
{
|
{
|
||||||
// Calculate the zoom factor needed to adjust viewport to bounding box.
|
|
||||||
float zoom = _get_zoom_to_bounding_box_factor(bbox);
|
|
||||||
if (zoom > 0.0f)
|
|
||||||
{
|
|
||||||
m_camera.zoom = zoom;
|
|
||||||
// center view around bounding box center
|
|
||||||
m_camera.set_target(bbox.center());
|
|
||||||
m_dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const
|
|
||||||
{
|
|
||||||
float max_bb_size = bbox.max_size();
|
|
||||||
if (max_bb_size == 0.0f)
|
|
||||||
return -1.0f;
|
|
||||||
|
|
||||||
// project the bbox vertices on a plane perpendicular to the camera forward axis
|
|
||||||
// then calculates the vertices coordinate on this plane along the camera xy axes
|
|
||||||
|
|
||||||
// we need the view matrix, we let opengl calculate it (same as done in render())
|
|
||||||
m_camera.apply_view_matrix();
|
|
||||||
|
|
||||||
Vec3d right = m_camera.get_dir_right();
|
|
||||||
Vec3d up = m_camera.get_dir_up();
|
|
||||||
Vec3d forward = m_camera.get_dir_forward();
|
|
||||||
|
|
||||||
Vec3d bb_min = bbox.min;
|
|
||||||
Vec3d bb_max = bbox.max;
|
|
||||||
Vec3d bb_center = bbox.center();
|
|
||||||
|
|
||||||
// bbox vertices in world space
|
|
||||||
std::vector<Vec3d> vertices;
|
|
||||||
vertices.reserve(8);
|
|
||||||
vertices.push_back(bb_min);
|
|
||||||
vertices.emplace_back(bb_max(0), bb_min(1), bb_min(2));
|
|
||||||
vertices.emplace_back(bb_max(0), bb_max(1), bb_min(2));
|
|
||||||
vertices.emplace_back(bb_min(0), bb_max(1), bb_min(2));
|
|
||||||
vertices.emplace_back(bb_min(0), bb_min(1), bb_max(2));
|
|
||||||
vertices.emplace_back(bb_max(0), bb_min(1), bb_max(2));
|
|
||||||
vertices.push_back(bb_max);
|
|
||||||
vertices.emplace_back(bb_min(0), bb_max(1), bb_max(2));
|
|
||||||
|
|
||||||
double max_x = 0.0;
|
|
||||||
double max_y = 0.0;
|
|
||||||
|
|
||||||
// margin factor to give some empty space around the bbox
|
|
||||||
double margin_factor = 1.25;
|
|
||||||
|
|
||||||
for (const Vec3d& v : vertices)
|
|
||||||
{
|
|
||||||
// project vertex on the plane perpendicular to camera forward axis
|
|
||||||
Vec3d pos(v(0) - bb_center(0), v(1) - bb_center(1), v(2) - bb_center(2));
|
|
||||||
Vec3d proj_on_plane = pos - pos.dot(forward) * forward;
|
|
||||||
|
|
||||||
// calculates vertex coordinate along camera xy axes
|
|
||||||
double x_on_plane = proj_on_plane.dot(right);
|
|
||||||
double y_on_plane = proj_on_plane.dot(up);
|
|
||||||
|
|
||||||
max_x = std::max(max_x, margin_factor * std::abs(x_on_plane));
|
|
||||||
max_y = std::max(max_y, margin_factor * std::abs(y_on_plane));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((max_x == 0.0) || (max_y == 0.0))
|
|
||||||
return -1.0f;
|
|
||||||
|
|
||||||
max_x *= 2.0;
|
|
||||||
max_y *= 2.0;
|
|
||||||
|
|
||||||
const Size& cnv_size = get_canvas_size();
|
const Size& cnv_size = get_canvas_size();
|
||||||
return (float)std::min((double)cnv_size.get_width() / max_x, (double)cnv_size.get_height() / max_y);
|
m_camera.zoom_to_box(box, cnv_size.get_width(), cnv_size.get_height());
|
||||||
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::_refresh_if_shown_on_screen()
|
void GLCanvas3D::_refresh_if_shown_on_screen()
|
||||||
|
@ -3991,7 +3834,7 @@ void GLCanvas3D::_render_objects() const
|
||||||
|
|
||||||
if (m_config != nullptr)
|
if (m_config != nullptr)
|
||||||
{
|
{
|
||||||
const BoundingBoxf3& bed_bb = m_bed.get_bounding_box();
|
const BoundingBoxf3& bed_bb = m_bed.get_bounding_box(false);
|
||||||
m_volumes.set_print_box((float)bed_bb.min(0), (float)bed_bb.min(1), 0.0f, (float)bed_bb.max(0), (float)bed_bb.max(1), (float)m_config->opt_float("max_print_height"));
|
m_volumes.set_print_box((float)bed_bb.min(0), (float)bed_bb.min(1), 0.0f, (float)bed_bb.max(0), (float)bed_bb.max(1), (float)m_config->opt_float("max_print_height"));
|
||||||
m_volumes.check_outside_state(m_config, nullptr);
|
m_volumes.check_outside_state(m_config, nullptr);
|
||||||
}
|
}
|
||||||
|
@ -4073,6 +3916,32 @@ void GLCanvas3D::_render_selection_center() const
|
||||||
}
|
}
|
||||||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||||
|
|
||||||
|
void GLCanvas3D::_render_overlays() const
|
||||||
|
{
|
||||||
|
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||||
|
glsafe(::glPushMatrix());
|
||||||
|
glsafe(::glLoadIdentity());
|
||||||
|
// ensure that the textures are renderered inside the frustrum
|
||||||
|
glsafe(::glTranslated(0.0, 0.0, -(m_camera.get_near_z() + 0.5)));
|
||||||
|
// ensure that the overlay fits the frustrum near z plane
|
||||||
|
double gui_scale = m_camera.get_gui_scale();
|
||||||
|
glsafe(::glScaled(gui_scale, gui_scale, 1.0));
|
||||||
|
|
||||||
|
_render_gizmos_overlay();
|
||||||
|
_render_warning_texture();
|
||||||
|
_render_legend_texture();
|
||||||
|
#if !ENABLE_SVG_ICONS
|
||||||
|
_resize_toolbars();
|
||||||
|
#endif // !ENABLE_SVG_ICONS
|
||||||
|
_render_toolbar();
|
||||||
|
_render_view_toolbar();
|
||||||
|
|
||||||
|
if ((m_layers_editing.last_object_id >= 0) && (m_layers_editing.object_max_z() > 0.0f))
|
||||||
|
m_layers_editing.render_overlay(*this);
|
||||||
|
|
||||||
|
glsafe(::glPopMatrix());
|
||||||
|
}
|
||||||
|
|
||||||
void GLCanvas3D::_render_warning_texture() const
|
void GLCanvas3D::_render_warning_texture() const
|
||||||
{
|
{
|
||||||
m_warning_texture.render(*this);
|
m_warning_texture.render(*this);
|
||||||
|
@ -4169,7 +4038,7 @@ void GLCanvas3D::_render_toolbar() const
|
||||||
#endif // ENABLE_RETINA_GL
|
#endif // ENABLE_RETINA_GL
|
||||||
|
|
||||||
Size cnv_size = get_canvas_size();
|
Size cnv_size = get_canvas_size();
|
||||||
float zoom = m_camera.zoom;
|
float zoom = (float)m_camera.get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
|
|
||||||
GLToolbar::Layout::EOrientation orientation = m_toolbar.get_layout_orientation();
|
GLToolbar::Layout::EOrientation orientation = m_toolbar.get_layout_orientation();
|
||||||
|
@ -4237,7 +4106,7 @@ void GLCanvas3D::_render_view_toolbar() const
|
||||||
#endif // ENABLE_RETINA_GL
|
#endif // ENABLE_RETINA_GL
|
||||||
|
|
||||||
Size cnv_size = get_canvas_size();
|
Size cnv_size = get_canvas_size();
|
||||||
float zoom = m_camera.zoom;
|
float zoom = (float)m_camera.get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
|
|
||||||
// places the toolbar on the bottom-left corner of the 3d scene
|
// places the toolbar on the bottom-left corner of the 3d scene
|
||||||
|
|
|
@ -600,7 +600,7 @@ public:
|
||||||
void do_flatten();
|
void do_flatten();
|
||||||
void do_mirror();
|
void do_mirror();
|
||||||
|
|
||||||
void set_camera_zoom(float zoom);
|
void set_camera_zoom(double zoom);
|
||||||
|
|
||||||
void update_gizmos_on_off_state();
|
void update_gizmos_on_off_state();
|
||||||
void reset_all_gizmos() { m_gizmos.reset_all_states(); }
|
void reset_all_gizmos() { m_gizmos.reset_all_states(); }
|
||||||
|
@ -641,10 +641,9 @@ private:
|
||||||
bool _set_current();
|
bool _set_current();
|
||||||
void _resize(unsigned int w, unsigned int h);
|
void _resize(unsigned int w, unsigned int h);
|
||||||
|
|
||||||
BoundingBoxf3 _max_bounding_box() const;
|
BoundingBoxf3 _max_bounding_box(bool include_bed_model) const;
|
||||||
|
|
||||||
void _zoom_to_bounding_box(const BoundingBoxf3& bbox);
|
void _zoom_to_box(const BoundingBoxf3& box);
|
||||||
float _get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const;
|
|
||||||
|
|
||||||
void _refresh_if_shown_on_screen();
|
void _refresh_if_shown_on_screen();
|
||||||
|
|
||||||
|
@ -658,6 +657,7 @@ private:
|
||||||
#if ENABLE_RENDER_SELECTION_CENTER
|
#if ENABLE_RENDER_SELECTION_CENTER
|
||||||
void _render_selection_center() const;
|
void _render_selection_center() const;
|
||||||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||||
|
void _render_overlays() const;
|
||||||
void _render_warning_texture() const;
|
void _render_warning_texture() const;
|
||||||
void _render_legend_texture() const;
|
void _render_legend_texture() const;
|
||||||
void _render_volumes_for_picking() const;
|
void _render_volumes_for_picking() const;
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace GUI {
|
||||||
if (!is_dragging())
|
if (!is_dragging())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float zoom = canvas.get_camera().zoom;
|
float zoom = (float)canvas.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
|
|
||||||
Size cnv_size = canvas.get_canvas_size();
|
Size cnv_size = canvas.get_canvas_size();
|
||||||
|
|
|
@ -390,19 +390,12 @@ void GLToolbar::render(const GLCanvas3D& parent) const
|
||||||
generate_icons_texture();
|
generate_icons_texture();
|
||||||
#endif // ENABLE_SVG_ICONS
|
#endif // ENABLE_SVG_ICONS
|
||||||
|
|
||||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
|
||||||
|
|
||||||
glsafe(::glPushMatrix());
|
|
||||||
glsafe(::glLoadIdentity());
|
|
||||||
|
|
||||||
switch (m_layout.type)
|
switch (m_layout.type)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case Layout::Horizontal: { render_horizontal(parent); break; }
|
case Layout::Horizontal: { render_horizontal(parent); break; }
|
||||||
case Layout::Vertical: { render_vertical(parent); break; }
|
case Layout::Vertical: { render_vertical(parent); break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
glsafe(::glPopMatrix());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
|
bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
|
||||||
|
@ -614,7 +607,7 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC
|
||||||
{
|
{
|
||||||
// NB: mouse_pos is already scaled appropriately
|
// NB: mouse_pos is already scaled appropriately
|
||||||
|
|
||||||
float zoom = parent.get_camera().zoom;
|
float zoom = (float)parent.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
#if ENABLE_SVG_ICONS
|
#if ENABLE_SVG_ICONS
|
||||||
float factor = m_layout.scale * inv_zoom;
|
float factor = m_layout.scale * inv_zoom;
|
||||||
|
@ -719,7 +712,7 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan
|
||||||
{
|
{
|
||||||
// NB: mouse_pos is already scaled appropriately
|
// NB: mouse_pos is already scaled appropriately
|
||||||
|
|
||||||
float zoom = parent.get_camera().zoom;
|
float zoom = (float)parent.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
#if ENABLE_SVG_ICONS
|
#if ENABLE_SVG_ICONS
|
||||||
float factor = m_layout.scale * inv_zoom;
|
float factor = m_layout.scale * inv_zoom;
|
||||||
|
@ -836,7 +829,7 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3
|
||||||
{
|
{
|
||||||
// NB: mouse_pos is already scaled appropriately
|
// NB: mouse_pos is already scaled appropriately
|
||||||
|
|
||||||
float zoom = parent.get_camera().zoom;
|
float zoom = (float)parent.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
#if ENABLE_SVG_ICONS
|
#if ENABLE_SVG_ICONS
|
||||||
float factor = m_layout.scale * inv_zoom;
|
float factor = m_layout.scale * inv_zoom;
|
||||||
|
@ -919,7 +912,7 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D&
|
||||||
{
|
{
|
||||||
// NB: mouse_pos is already scaled appropriately
|
// NB: mouse_pos is already scaled appropriately
|
||||||
|
|
||||||
float zoom = parent.get_camera().zoom;
|
float zoom = (float)parent.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
#if ENABLE_SVG_ICONS
|
#if ENABLE_SVG_ICONS
|
||||||
float factor = m_layout.scale * inv_zoom;
|
float factor = m_layout.scale * inv_zoom;
|
||||||
|
@ -1015,7 +1008,7 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const
|
||||||
return;
|
return;
|
||||||
#endif // !ENABLE_SVG_ICONS
|
#endif // !ENABLE_SVG_ICONS
|
||||||
|
|
||||||
float zoom = parent.get_camera().zoom;
|
float zoom = (float)parent.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
#if ENABLE_SVG_ICONS
|
#if ENABLE_SVG_ICONS
|
||||||
float factor = inv_zoom * m_layout.scale;
|
float factor = inv_zoom * m_layout.scale;
|
||||||
|
@ -1170,7 +1163,7 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const
|
||||||
return;
|
return;
|
||||||
#endif // !ENABLE_SVG_ICONS
|
#endif // !ENABLE_SVG_ICONS
|
||||||
|
|
||||||
float zoom = parent.get_camera().zoom;
|
float zoom = (float)parent.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
#if ENABLE_SVG_ICONS
|
#if ENABLE_SVG_ICONS
|
||||||
float factor = inv_zoom * m_layout.scale;
|
float factor = inv_zoom * m_layout.scale;
|
||||||
|
|
|
@ -531,18 +531,9 @@ void GLGizmosManager::render_overlay(const GLCanvas3D& canvas, const Selection&
|
||||||
generate_icons_texture();
|
generate_icons_texture();
|
||||||
#endif // ENABLE_SVG_ICONS
|
#endif // ENABLE_SVG_ICONS
|
||||||
|
|
||||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
|
||||||
|
|
||||||
glsafe(::glPushMatrix());
|
|
||||||
glsafe(::glLoadIdentity());
|
|
||||||
|
|
||||||
do_render_overlay(canvas, selection);
|
do_render_overlay(canvas, selection);
|
||||||
|
|
||||||
glsafe(::glPopMatrix());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool GLGizmosManager::on_mouse_wheel(wxMouseEvent& evt, GLCanvas3D& canvas)
|
bool GLGizmosManager::on_mouse_wheel(wxMouseEvent& evt, GLCanvas3D& canvas)
|
||||||
{
|
{
|
||||||
bool processed = false;
|
bool processed = false;
|
||||||
|
@ -939,7 +930,7 @@ void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selectio
|
||||||
|
|
||||||
float cnv_w = (float)canvas.get_canvas_size().get_width();
|
float cnv_w = (float)canvas.get_canvas_size().get_width();
|
||||||
float cnv_h = (float)canvas.get_canvas_size().get_height();
|
float cnv_h = (float)canvas.get_canvas_size().get_height();
|
||||||
float zoom = canvas.get_camera().zoom;
|
float zoom = (float)canvas.get_camera().get_zoom();
|
||||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||||
|
|
||||||
float height = get_total_overlay_height();
|
float height = get_total_overlay_height();
|
||||||
|
|
|
@ -147,6 +147,7 @@ void KBShortcutsDialog::fill_shortcuts()
|
||||||
plater_shortcuts.push_back(Shortcut("F", L("Press to scale selection to fit print volume\nin Gizmo scale")));
|
plater_shortcuts.push_back(Shortcut("F", L("Press to scale selection to fit print volume\nin Gizmo scale")));
|
||||||
plater_shortcuts.push_back(Shortcut(alt, L("Press to activate deselection rectangle\nor to scale or rotate selected objects\naround their own center")));
|
plater_shortcuts.push_back(Shortcut(alt, L("Press to activate deselection rectangle\nor to scale or rotate selected objects\naround their own center")));
|
||||||
plater_shortcuts.push_back(Shortcut(ctrl, L("Press to activate one direction scaling in Gizmo scale")));
|
plater_shortcuts.push_back(Shortcut(ctrl, L("Press to activate one direction scaling in Gizmo scale")));
|
||||||
|
plater_shortcuts.push_back(Shortcut("K", L("Change camera type")));
|
||||||
plater_shortcuts.push_back(Shortcut("B", L("Zoom to Bed")));
|
plater_shortcuts.push_back(Shortcut("B", L("Zoom to Bed")));
|
||||||
plater_shortcuts.push_back(Shortcut("Z", L("Zoom to all objects in scene, if none selected")));
|
plater_shortcuts.push_back(Shortcut("Z", L("Zoom to all objects in scene, if none selected")));
|
||||||
plater_shortcuts.push_back(Shortcut("Z", L("Zoom to selected object")));
|
plater_shortcuts.push_back(Shortcut("Z", L("Zoom to selected object")));
|
||||||
|
|
|
@ -1772,6 +1772,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||||
q->Layout();
|
q->Layout();
|
||||||
|
|
||||||
set_current_panel(view3D);
|
set_current_panel(view3D);
|
||||||
|
|
||||||
|
// updates camera type from .ini file
|
||||||
|
camera.set_type(get_config("camera_type"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::priv::update(bool force_full_scene_refresh)
|
void Plater::priv::update(bool force_full_scene_refresh)
|
||||||
|
|
Loading…
Reference in a new issue