Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_labels

This commit is contained in:
Enrico Turri 2020-01-29 12:31:50 +01:00
commit 504413cc91
9 changed files with 200 additions and 70 deletions

View File

@ -233,20 +233,30 @@ cmake_policy(SET CMP0011 NEW)
find_package(CGAL REQUIRED) find_package(CGAL REQUIRED)
cmake_policy(POP) cmake_policy(POP)
set(_cgal_defines "") add_library(libslic3r_cgal STATIC MeshBoolean.cpp MeshBoolean.hpp)
if (MSVC AND "${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") # 32 bit MSVC workaround target_include_directories(libslic3r_cgal PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
set(_cgal_defines CGAL_DO_NOT_USE_MPZF)
endif ()
add_library(libslic3r_cgal OBJECT MeshBoolean.cpp MeshBoolean.hpp) # Reset compile options of libslic3r_cgal. Despite it being linked privately, CGAL options
target_include_directories(libslic3r_cgal PRIVATE # (-frounding-math) still propagate to dependent libs which is not desired.
${CMAKE_CURRENT_BINARY_DIR} get_target_property(_cgal_tgt CGAL::CGAL ALIASED_TARGET)
$<TARGET_PROPERTY:libigl,INTERFACE_INCLUDE_DIRECTORIES> if (NOT TARGET ${_cgal_tgt})
$<TARGET_PROPERTY:CGAL::CGAL,INTERFACE_INCLUDE_DIRECTORIES>) set (_cgal_tgt CGAL::CGAL)
target_compile_definitions(libslic3r_cgal PRIVATE ${_cgal_defines} endif ()
$<TARGET_PROPERTY:CGAL::CGAL,INTERFACE_COMPILE_DEFINITIONS>) get_target_property(_opts ${_cgal_tgt} INTERFACE_COMPILE_OPTIONS)
target_compile_options(libslic3r_cgal PRIVATE if (_opts)
$<TARGET_PROPERTY:CGAL::CGAL,INTERFACE_COMPILE_OPTIONS>) set(_opts_bad "${_opts}")
set(_opts_good "${_opts}")
list(FILTER _opts_bad INCLUDE REGEX frounding-math)
list(FILTER _opts_good EXCLUDE REGEX frounding-math)
set_target_properties(${_cgal_tgt} PROPERTIES INTERFACE_COMPILE_OPTIONS "${_opts_good}")
target_compile_options(libslic3r_cgal PRIVATE "${_opts_bad}")
endif()
target_link_libraries(libslic3r_cgal PRIVATE ${_cgal_tgt} libigl)
if (MSVC AND "${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") # 32 bit MSVC workaround
target_compile_definitions(libslic3r_cgal PRIVATE CGAL_DO_NOT_USE_MPZF)
endif ()
encoding_check(libslic3r) encoding_check(libslic3r)
@ -268,7 +278,7 @@ target_link_libraries(libslic3r
qhull qhull
semver semver
TBB::tbb TBB::tbb
$<TARGET_PROPERTY:CGAL::CGAL,INTERFACE_LINK_LIBRARIES> libslic3r_cgal
${CMAKE_DL_LIBS} ${CMAKE_DL_LIBS}
) )
@ -287,5 +297,3 @@ endif()
if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY) if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY)
add_precompiled_header(libslic3r pchheader.hpp FORCEINCLUDE) add_precompiled_header(libslic3r pchheader.hpp FORCEINCLUDE)
endif () endif ()
target_sources(libslic3r PRIVATE $<TARGET_OBJECTS:libslic3r_cgal>)

View File

@ -111,7 +111,7 @@ static TriangleMesh cgal_to_triangle_mesh(const _CGALMesh &cgalmesh)
auto vtc = cgalmesh.vertices_around_face(cgalmesh.halfedge(face)); auto vtc = cgalmesh.vertices_around_face(cgalmesh.halfedge(face));
int i = 0; int i = 0;
Vec3crd trface; Vec3crd trface;
for (auto v : vtc) trface(i++) = int(v.idx()); for (auto v : vtc) trface(i++) = static_cast<unsigned>(v);
facets.emplace_back(trface); facets.emplace_back(trface);
} }

View File

@ -49,12 +49,20 @@ static wxBitmap wxImage_to_wxBitmap_with_alpha(wxImage &&image, float scale = 1.
#endif #endif
} }
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_t height) wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_t height, float scale/* = 1.0f*/)
{ {
wxBitmap *bitmap = nullptr; wxBitmap *bitmap = nullptr;
auto it = m_map.find(bitmap_key); auto it = m_map.find(bitmap_key);
if (it == m_map.end()) { if (it == m_map.end()) {
bitmap = new wxBitmap(width, height); bitmap = new wxBitmap(width, height);
#ifdef __APPLE__
// Contrary to intuition, the `scale` argument isn't "please scale this to such and such"
// but rather "the wxImage is sized for backing scale such and such".
// So, We need to let the Mac OS wxBitmap implementation
// know that the image may already be scaled appropriately for Retina,
// and thereby that it's not supposed to upscale it.
bitmap->CreateScaled(width, height, -1, scale);
#endif
m_map[bitmap_key] = bitmap; m_map[bitmap_key] = bitmap;
} else { } else {
bitmap = it->second; bitmap = it->second;
@ -95,7 +103,7 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp
return this->insert(bitmap_key, bmps, bmps + 3); return this->insert(bitmap_key, bmps, bmps + 3);
} }
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *begin, const wxBitmap *end) wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *begin, const wxBitmap *end, float scale/* = 1.0f*/)
{ {
size_t width = 0; size_t width = 0;
size_t height = 0; size_t height = 0;
@ -158,7 +166,13 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *beg
#else #else
wxBitmap *bitmap = this->insert(bitmap_key, width, height); #ifdef __APPLE__
// Note, for this moment width and height are scaled, so divide them by scale to avoid one more multiplication inside CreateScaled()
width *= 1.0 / scale;
height *= 1.0 / scale;
#endif
wxBitmap *bitmap = this->insert(bitmap_key, width, height, scale);
wxMemoryDC memDC; wxMemoryDC memDC;
memDC.SelectObject(*bitmap); memDC.SelectObject(*bitmap);
memDC.SetBackground(*wxTRANSPARENT_BRUSH); memDC.SetBackground(*wxTRANSPARENT_BRUSH);
@ -167,7 +181,8 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *beg
for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) { for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
if (bmp->GetWidth() > 0) if (bmp->GetWidth() > 0)
memDC.DrawBitmap(*bmp, x, 0, true); memDC.DrawBitmap(*bmp, x, 0, true);
x += bmp->GetWidth(); // we should "move" with step equal to non-scaled width
x += bmp->GetWidth()/scale;
} }
memDC.SelectObject(wxNullBitmap); memDC.SelectObject(wxNullBitmap);
return bitmap; return bitmap;

View File

@ -23,12 +23,12 @@ public:
wxBitmap* find(const std::string &name) { auto it = m_map.find(name); return (it == m_map.end()) ? nullptr : it->second; } wxBitmap* find(const std::string &name) { auto it = m_map.find(name); return (it == m_map.end()) ? nullptr : it->second; }
const wxBitmap* find(const std::string &name) const { return const_cast<BitmapCache*>(this)->find(name); } const wxBitmap* find(const std::string &name) const { return const_cast<BitmapCache*>(this)->find(name); }
wxBitmap* insert(const std::string &name, size_t width, size_t height); wxBitmap* insert(const std::string &name, size_t width, size_t height, float scale = 1.0f);
wxBitmap* insert(const std::string &name, const wxBitmap &bmp); wxBitmap* insert(const std::string &name, const wxBitmap &bmp);
wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2); wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2);
wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3); wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3);
wxBitmap* insert(const std::string &name, const std::vector<wxBitmap> &bmps) { return this->insert(name, &bmps.front(), &bmps.front() + bmps.size()); } wxBitmap* insert(const std::string &name, const std::vector<wxBitmap> &bmps, float scale = 1.0f) { return this->insert(name, &bmps.front(), &bmps.front() + bmps.size(), scale); }
wxBitmap* insert(const std::string &name, const wxBitmap *begin, const wxBitmap *end); wxBitmap* insert(const std::string &name, const wxBitmap *begin, const wxBitmap *end, float scale = 1.0f);
wxBitmap* insert_raw_rgba(const std::string &bitmap_key, unsigned width, unsigned height, const unsigned char *raw_data, float scale = 1.0f, const bool grayscale = false); wxBitmap* insert_raw_rgba(const std::string &bitmap_key, unsigned width, unsigned height, const unsigned char *raw_data, float scale = 1.0f, const bool grayscale = false);
// Load png from resources/icons. bitmap_key is given without the .png suffix. Bitmap will be rescaled to provided height/width if nonzero. // Load png from resources/icons. bitmap_key is given without the .png suffix. Bitmap will be rescaled to provided height/width if nonzero.

View File

@ -240,17 +240,27 @@ void Camera::apply_view_matrix() const
void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double far_z) const void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double far_z) const
{ {
#if !ENABLE_6DOF_CAMERA
set_distance(DefaultDistance); set_distance(DefaultDistance);
#endif // !ENABLE_6DOF_CAMERA
double w = 0.0; double w = 0.0;
double h = 0.0; double h = 0.0;
#if ENABLE_6DOF_CAMERA
double old_distance = m_distance;
m_frustrum_zs = calc_tight_frustrum_zs_around(box);
if (m_distance != old_distance)
// the camera has been moved re-apply view matrix
apply_view_matrix();
#else
while (true) while (true)
{ {
m_frustrum_zs = calc_tight_frustrum_zs_around(box); m_frustrum_zs = calc_tight_frustrum_zs_around(box);
#endif // !ENABLE_6DOF_CAMERA
if (near_z > 0.0) if (near_z > 0.0)
m_frustrum_zs.first = std::min(m_frustrum_zs.first, near_z); m_frustrum_zs.first = std::max(std::min(m_frustrum_zs.first, near_z), FrustrumMinNearZ);
if (far_z > 0.0) if (far_z > 0.0)
m_frustrum_zs.second = std::max(m_frustrum_zs.second, far_z); m_frustrum_zs.second = std::max(m_frustrum_zs.second, far_z);
@ -281,6 +291,7 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
} }
} }
#if !ENABLE_6DOF_CAMERA
if (m_type == Perspective) if (m_type == Perspective)
{ {
double fov_deg = Geometry::rad2deg(2.0 * std::atan(h / m_frustrum_zs.first)); double fov_deg = Geometry::rad2deg(2.0 * std::atan(h / m_frustrum_zs.first));
@ -300,6 +311,7 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
else else
break; break;
} }
#endif // !ENABLE_6DOF_CAMERA
glsafe(::glMatrixMode(GL_PROJECTION)); glsafe(::glMatrixMode(GL_PROJECTION));
glsafe(::glLoadIdentity()); glsafe(::glLoadIdentity());
@ -324,14 +336,22 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
} }
#if ENABLE_THUMBNAIL_GENERATOR #if ENABLE_THUMBNAIL_GENERATOR
#if ENABLE_6DOF_CAMERA
void Camera::zoom_to_box(const BoundingBoxf3& box, double margin_factor)
#else
void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor) void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor)
#endif // ENABLE_6DOF_CAMERA
#else #else
void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h) void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h)
#endif // ENABLE_THUMBNAIL_GENERATOR #endif // ENABLE_THUMBNAIL_GENERATOR
{ {
// Calculate the zoom factor needed to adjust the view around the given box. // Calculate the zoom factor needed to adjust the view around the given box.
#if ENABLE_THUMBNAIL_GENERATOR #if ENABLE_THUMBNAIL_GENERATOR
#if ENABLE_6DOF_CAMERA
double zoom = calc_zoom_to_bounding_box_factor(box, margin_factor);
#else
double zoom = calc_zoom_to_bounding_box_factor(box, canvas_w, canvas_h, margin_factor); double zoom = calc_zoom_to_bounding_box_factor(box, canvas_w, canvas_h, margin_factor);
#endif // ENABLE_6DOF_CAMERA
#else #else
double zoom = calc_zoom_to_bounding_box_factor(box, canvas_w, canvas_h); double zoom = calc_zoom_to_bounding_box_factor(box, canvas_w, canvas_h);
#endif // ENABLE_THUMBNAIL_GENERATOR #endif // ENABLE_THUMBNAIL_GENERATOR
@ -348,10 +368,18 @@ void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h)
} }
#if ENABLE_THUMBNAIL_GENERATOR #if ENABLE_THUMBNAIL_GENERATOR
#if ENABLE_6DOF_CAMERA
void Camera::zoom_to_volumes(const GLVolumePtrs& volumes, double margin_factor)
#else
void Camera::zoom_to_volumes(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, double margin_factor) void Camera::zoom_to_volumes(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, double margin_factor)
#endif // ENABLE_6DOF_CAMERA
{ {
Vec3d center; Vec3d center;
#if ENABLE_6DOF_CAMERA
double zoom = calc_zoom_to_volumes_factor(volumes, center, margin_factor);
#else
double zoom = calc_zoom_to_volumes_factor(volumes, canvas_w, canvas_h, center, margin_factor); double zoom = calc_zoom_to_volumes_factor(volumes, canvas_w, canvas_h, center, margin_factor);
#endif // ENABLE_6DOF_CAMERA
if (zoom > 0.0) if (zoom > 0.0)
{ {
m_zoom = zoom; m_zoom = zoom;
@ -389,6 +417,7 @@ void Camera::debug_render() const
float deltaZ = farZ - nearZ; float deltaZ = farZ - nearZ;
float zoom = (float)m_zoom; float zoom = (float)m_zoom;
float fov = (float)get_fov(); float fov = (float)get_fov();
std::array<int, 4>viewport = get_viewport();
float gui_scale = (float)get_gui_scale(); float gui_scale = (float)get_gui_scale();
ImGui::InputText("Type", type.data(), type.length(), ImGuiInputTextFlags_ReadOnly); ImGui::InputText("Type", type.data(), type.length(), ImGuiInputTextFlags_ReadOnly);
@ -408,6 +437,8 @@ void Camera::debug_render() const
ImGui::InputFloat("Zoom", &zoom, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly); ImGui::InputFloat("Zoom", &zoom, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly);
ImGui::InputFloat("Fov", &fov, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly); ImGui::InputFloat("Fov", &fov, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly);
ImGui::Separator(); ImGui::Separator();
ImGui::InputInt4("Viewport", viewport.data(), ImGuiInputTextFlags_ReadOnly);
ImGui::Separator();
ImGui::InputFloat("GUI scale", &gui_scale, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly); ImGui::InputFloat("GUI scale", &gui_scale, 0.0f, 0.0f, "%.6f", ImGuiInputTextFlags_ReadOnly);
imgui.end(); imgui.end();
} }
@ -427,10 +458,31 @@ void Camera::translate_world(const Vec3d& displacement)
void Camera::rotate_on_sphere(double delta_azimut_rad, double delta_zenit_rad) void Camera::rotate_on_sphere(double delta_azimut_rad, double delta_zenit_rad)
{ {
// FIXME -> The following is a HACK !!!
// When the value of the zenit rotation is large enough, the following call to rotate() shows
// numerical instability introducing some scaling into m_view_matrix (verified by checking
// that the camera space unit vectors are no more unit).
// See also https://dev.prusa3d.com/browse/SPE-1082
// We split the zenit rotation into a set of smaller rotations which are then applied.
static const double MAX_ALLOWED = Geometry::deg2rad(0.1);
unsigned int zenit_steps_count = 1 + (unsigned int)(std::abs(delta_zenit_rad) / MAX_ALLOWED);
double zenit_step = delta_zenit_rad / (double)zenit_steps_count;
Vec3d target = m_target; Vec3d target = m_target;
translate_world(-target); translate_world(-target);
m_view_matrix.rotate(Eigen::AngleAxisd(delta_zenit_rad, get_dir_right()));
if (zenit_step != 0.0)
{
Vec3d right = get_dir_right();
for (unsigned int i = 0; i < zenit_steps_count; ++i)
{
m_view_matrix.rotate(Eigen::AngleAxisd(zenit_step, right));
}
}
if (delta_azimut_rad != 0.0)
m_view_matrix.rotate(Eigen::AngleAxisd(delta_azimut_rad, Vec3d::UnitZ())); m_view_matrix.rotate(Eigen::AngleAxisd(delta_azimut_rad, Vec3d::UnitZ()));
translate_world(target); translate_world(target);
} }
@ -453,7 +505,11 @@ void Camera::rotate_local_around_pivot(const Vec3d& rotation_rad, const Vec3d& p
double Camera::min_zoom() const double Camera::min_zoom() const
{ {
#if ENABLE_6DOF_CAMERA
return 0.7 * calc_zoom_to_bounding_box_factor(m_scene_box);
#else
return 0.7 * calc_zoom_to_bounding_box_factor(m_scene_box, (int)m_viewport[2], (int)m_viewport[3]); return 0.7 * calc_zoom_to_bounding_box_factor(m_scene_box, (int)m_viewport[2], (int)m_viewport[3]);
#endif // ENABLE_6DOF_CAMERA
} }
#endif // ENABLE_6DOF_CAMERA #endif // ENABLE_6DOF_CAMERA
@ -462,8 +518,10 @@ std::pair<double, double> Camera::calc_tight_frustrum_zs_around(const BoundingBo
std::pair<double, double> ret; std::pair<double, double> ret;
auto& [near_z, far_z] = ret; auto& [near_z, far_z] = ret;
#if !ENABLE_6DOF_CAMERA
while (true) while (true)
{ {
#endif // !ENABLE_6DOF_CAMERA
// box in eye space // box in eye space
BoundingBoxf3 eye_box = box.transformed(m_view_matrix); BoundingBoxf3 eye_box = box.transformed(m_view_matrix);
near_z = -eye_box.max(2); near_z = -eye_box.max(2);
@ -482,18 +540,39 @@ std::pair<double, double> Camera::calc_tight_frustrum_zs_around(const BoundingBo
far_z = mid_z + half_size; far_z = mid_z + half_size;
} }
#if ENABLE_6DOF_CAMERA
if (near_z < FrustrumMinNearZ)
{
float delta = FrustrumMinNearZ - near_z;
set_distance(m_distance + delta);
near_z += delta;
far_z += delta;
}
else if ((near_z > 2.0 * FrustrumMinNearZ) && (m_distance > DefaultDistance))
{
float delta = m_distance - DefaultDistance;
set_distance(DefaultDistance);
near_z -= delta;
far_z -= delta;
}
#else
if (near_z >= FrustrumMinNearZ) if (near_z >= FrustrumMinNearZ)
break; break;
// ensure min Near Z // ensure min near z
set_distance(m_distance + FrustrumMinNearZ - near_z); set_distance(m_distance + FrustrumMinNearZ - near_z);
} }
#endif // ENABLE_6DOF_CAMERA
return ret; return ret;
} }
#if ENABLE_THUMBNAIL_GENERATOR #if ENABLE_THUMBNAIL_GENERATOR
#if ENABLE_6DOF_CAMERA
double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, double margin_factor) const
#else
double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor) const double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor) const
#endif // ENABLE_6DOF_CAMERA
#else #else
double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h) const double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h) const
#endif // ENABLE_THUMBNAIL_GENERATOR #endif // ENABLE_THUMBNAIL_GENERATOR
@ -505,8 +584,10 @@ double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int ca
// project the box vertices on a plane perpendicular to the camera forward axis // 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 // then calculates the vertices coordinate on this plane along the camera xy axes
#if !ENABLE_6DOF_CAMERA
// ensure that the view matrix is updated // ensure that the view matrix is updated
apply_view_matrix(); apply_view_matrix();
#endif // !ENABLE_6DOF_CAMERA
Vec3d right = get_dir_right(); Vec3d right = get_dir_right();
Vec3d up = get_dir_up(); Vec3d up = get_dir_up();
@ -563,11 +644,19 @@ double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int ca
dx *= margin_factor; dx *= margin_factor;
dy *= margin_factor; dy *= margin_factor;
#if ENABLE_6DOF_CAMERA
return std::min((double)m_viewport[2] / dx, (double)m_viewport[3] / dy);
#else
return std::min((double)canvas_w / dx, (double)canvas_h / dy); return std::min((double)canvas_w / dx, (double)canvas_h / dy);
#endif // ENABLE_6DOF_CAMERA
} }
#if ENABLE_THUMBNAIL_GENERATOR #if ENABLE_THUMBNAIL_GENERATOR
#if ENABLE_6DOF_CAMERA
double Camera::calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, Vec3d& center, double margin_factor) const
#else
double Camera::calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, Vec3d& center, double margin_factor) const double Camera::calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, Vec3d& center, double margin_factor) const
#endif // ENABLE_6DOF_CAMERA
{ {
if (volumes.empty()) if (volumes.empty())
return -1.0; return -1.0;
@ -575,8 +664,10 @@ double Camera::calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, int canv
// project the volumes vertices on a plane perpendicular to the camera forward axis // project the volumes vertices on a plane perpendicular to the camera forward axis
// then calculates the vertices coordinate on this plane along the camera xy axes // then calculates the vertices coordinate on this plane along the camera xy axes
#if !ENABLE_6DOF_CAMERA
// ensure that the view matrix is updated // ensure that the view matrix is updated
apply_view_matrix(); apply_view_matrix();
#endif // !ENABLE_6DOF_CAMERA
Vec3d right = get_dir_right(); Vec3d right = get_dir_right();
Vec3d up = get_dir_up(); Vec3d up = get_dir_up();
@ -628,14 +719,26 @@ double Camera::calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, int canv
if ((dx <= 0.0) || (dy <= 0.0)) if ((dx <= 0.0) || (dy <= 0.0))
return -1.0f; return -1.0f;
#if ENABLE_6DOF_CAMERA
return std::min((double)m_viewport[2] / dx, (double)m_viewport[3] / dy);
#else
return std::min((double)canvas_w / dx, (double)canvas_h / dy); return std::min((double)canvas_w / dx, (double)canvas_h / dy);
#endif // ENABLE_6DOF_CAMERA
} }
#endif // ENABLE_THUMBNAIL_GENERATOR #endif // ENABLE_THUMBNAIL_GENERATOR
void Camera::set_distance(double distance) const void Camera::set_distance(double distance) const
{ {
#if ENABLE_6DOF_CAMERA
if (m_distance != distance)
{
m_view_matrix.translate((distance - m_distance) * get_dir_forward());
m_distance = distance;
}
#else
m_distance = distance; m_distance = distance;
apply_view_matrix(); apply_view_matrix();
#endif // ENABLE_6DOF_CAMERA
} }
#if ENABLE_6DOF_CAMERA #if ENABLE_6DOF_CAMERA

View File

@ -48,11 +48,7 @@ private:
mutable double m_gui_scale; mutable double m_gui_scale;
mutable std::array<int, 4> m_viewport; mutable std::array<int, 4> m_viewport;
#if ENABLE_6DOF_CAMERA
Transform3d m_view_matrix;
#else
mutable Transform3d m_view_matrix; mutable Transform3d m_view_matrix;
#endif // ENABLE_6DOF_CAMERA
mutable Transform3d m_projection_matrix; mutable Transform3d m_projection_matrix;
mutable std::pair<double, double> m_frustrum_zs; mutable std::pair<double, double> m_frustrum_zs;
@ -71,7 +67,11 @@ public:
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);
#if ENABLE_6DOF_CAMERA
double get_distance() const { return (get_position() - m_target).norm(); }
#else
double get_distance() const { return m_distance; } double get_distance() const { return m_distance; }
#endif // ENABLE_6DOF_CAMERA
double get_gui_scale() const { return m_gui_scale; } double get_gui_scale() const { return m_gui_scale; }
#if !ENABLE_6DOF_CAMERA #if !ENABLE_6DOF_CAMERA
@ -115,8 +115,13 @@ public:
void apply_projection(const BoundingBoxf3& box, double near_z = -1.0, double far_z = -1.0) const; void apply_projection(const BoundingBoxf3& box, double near_z = -1.0, double far_z = -1.0) const;
#if ENABLE_THUMBNAIL_GENERATOR #if ENABLE_THUMBNAIL_GENERATOR
#if ENABLE_6DOF_CAMERA
void zoom_to_box(const BoundingBoxf3& box, double margin_factor = DefaultZoomToBoxMarginFactor);
void zoom_to_volumes(const GLVolumePtrs& volumes, double margin_factor = DefaultZoomToVolumesMarginFactor);
#else
void zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToBoxMarginFactor); void zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToBoxMarginFactor);
void zoom_to_volumes(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToVolumesMarginFactor); void zoom_to_volumes(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToVolumesMarginFactor);
#endif // ENABLE_6DOF_CAMERA
#else #else
void zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h); void zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h);
#endif // ENABLE_THUMBNAIL_GENERATOR #endif // ENABLE_THUMBNAIL_GENERATOR
@ -151,8 +156,13 @@ private:
// the camera MUST be outside of the bounding box in eye coordinate of the given 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; std::pair<double, double> calc_tight_frustrum_zs_around(const BoundingBoxf3& box) const;
#if ENABLE_THUMBNAIL_GENERATOR #if ENABLE_THUMBNAIL_GENERATOR
#if ENABLE_6DOF_CAMERA
double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, double margin_factor = DefaultZoomToBoxMarginFactor) const;
double calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, Vec3d& center, double margin_factor = DefaultZoomToVolumesMarginFactor) const;
#else
double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToBoxMarginFactor) const; double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToBoxMarginFactor) const;
double calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, Vec3d& center, double margin_factor = DefaultZoomToVolumesMarginFactor) const; double calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, Vec3d& center, double margin_factor = DefaultZoomToVolumesMarginFactor) const;
#endif // ENABLE_6DOF_CAMERA
#else #else
double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h) const; double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h) const;
#endif // ENABLE_THUMBNAIL_GENERATOR #endif // ENABLE_THUMBNAIL_GENERATOR

View File

@ -1854,11 +1854,16 @@ void GLCanvas3D::render()
} }
const Size& cnv_size = get_canvas_size(); const Size& cnv_size = get_canvas_size();
#if ENABLE_6DOF_CAMERA
m_camera.apply_viewport(0, 0, (unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height());
#endif // ENABLE_6DOF_CAMERA
if (m_camera.requires_zoom_to_bed) if (m_camera.requires_zoom_to_bed)
{ {
zoom_to_bed(); zoom_to_bed();
#if !ENABLE_6DOF_CAMERA
_resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height()); _resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height());
#endif // !ENABLE_6DOF_CAMERA
m_camera.requires_zoom_to_bed = false; m_camera.requires_zoom_to_bed = false;
} }
@ -3962,8 +3967,13 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool
#if ENABLE_6DOF_CAMERA #if ENABLE_6DOF_CAMERA
camera.set_scene_box(scene_bounding_box()); camera.set_scene_box(scene_bounding_box());
#endif // ENABLE_6DOF_CAMERA #endif // ENABLE_6DOF_CAMERA
#if ENABLE_6DOF_CAMERA
camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height);
camera.zoom_to_volumes(visible_volumes);
#else
camera.zoom_to_volumes(visible_volumes, thumbnail_data.width, thumbnail_data.height); camera.zoom_to_volumes(visible_volumes, thumbnail_data.width, thumbnail_data.height);
camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height);
#endif // ENABLE_6DOF_CAMERA
camera.apply_view_matrix(); camera.apply_view_matrix();
double near_z = -1.0; double near_z = -1.0;
@ -4554,8 +4564,10 @@ 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();
#if !ENABLE_6DOF_CAMERA
// updates camera // updates camera
m_camera.apply_viewport(0, 0, w, h); m_camera.apply_viewport(0, 0, w, h);
#endif // !ENABLE_6DOF_CAMERA
} }
BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_gizmos, bool include_bed_model) const BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_gizmos, bool include_bed_model) const
@ -4579,8 +4591,12 @@ BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_gizmos, bool include_be
#if ENABLE_THUMBNAIL_GENERATOR #if ENABLE_THUMBNAIL_GENERATOR
void GLCanvas3D::_zoom_to_box(const BoundingBoxf3& box, double margin_factor) void GLCanvas3D::_zoom_to_box(const BoundingBoxf3& box, double margin_factor)
{ {
#if ENABLE_6DOF_CAMERA
m_camera.zoom_to_box(box, margin_factor);
#else
const Size& cnv_size = get_canvas_size(); const Size& cnv_size = get_canvas_size();
m_camera.zoom_to_box(box, cnv_size.get_width(), cnv_size.get_height(), margin_factor); m_camera.zoom_to_box(box, cnv_size.get_width(), cnv_size.get_height(), margin_factor);
#endif // ENABLE_6DOF_CAMERA
m_dirty = true; m_dirty = true;
} }
#else #else

View File

@ -66,7 +66,7 @@ void enable_menu_item(wxUpdateUIEvent& evt, std::function<bool()> const cb_condi
const auto it = msw_menuitem_bitmaps.find(item->GetId()); const auto it = msw_menuitem_bitmaps.find(item->GetId());
if (it != msw_menuitem_bitmaps.end()) if (it != msw_menuitem_bitmaps.end())
{ {
const wxBitmap& item_icon = create_scaled_bitmap(win, it->second, 16, false, !enable); const wxBitmap& item_icon = create_scaled_bitmap(win, it->second, 16, !enable);
if (item_icon.IsOk()) if (item_icon.IsOk())
item->SetBitmap(item_icon); item->SetBitmap(item_icon);
} }
@ -420,41 +420,25 @@ float get_svg_scale_factor(wxWindow *win)
} }
return win != nullptr ? max_scaling_factor : 1.0f; return win != nullptr ? max_scaling_factor : 1.0f;
#else #else
(void)(win);
return 1.0f; return 1.0f;
#endif #endif
} }
// If an icon has horizontal orientation (width > height) call this function with is_horizontal = true // If an icon has horizontal orientation (width > height) call this function with is_horizontal = true
wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in,
const int px_cnt/* = 16*/, const bool is_horizontal /* = false*/, const bool grayscale/* = false*/) const int px_cnt/* = 16*/, const bool grayscale/* = false*/)
{ {
static Slic3r::GUI::BitmapCache cache; static Slic3r::GUI::BitmapCache cache;
#ifdef __APPLE__ const float scale_factor = get_svg_scale_factor(win);
// Note: win->GetContentScaleFactor() is not used anymore here because it tends to
// return bogus results quite often (such as 1.0 on Retina or even 0.0).
// We're using the max scaling factor across all screens because it's very likely to be good enough.
static float max_scaling_factor = NAN; unsigned int width = 0;
if (std::isnan(max_scaling_factor)) { unsigned int height = (unsigned int)(em_unit(win) * px_cnt * 0.1f + 0.5f);
max_scaling_factor = Slic3r::GUI::mac_max_scaling_factor();
}
const float scale_factor = win != nullptr ? max_scaling_factor : 1.0f;
#else
(void)(win);
const float scale_factor = 1.0f;
#endif
unsigned int height, width = height = 0;
unsigned int& scale_base = is_horizontal ? width : height;
scale_base = (unsigned int)(em_unit(win) * px_cnt * 0.1f + 0.5f);
std::string bmp_name = bmp_name_in; std::string bmp_name = bmp_name_in;
boost::replace_last(bmp_name, ".png", ""); boost::replace_last(bmp_name, ".png", "");
// std::string bmp_name = icon_name_respected_to_mode(bmp_name_in);
// Try loading an SVG first, then PNG if SVG is not found: // Try loading an SVG first, then PNG if SVG is not found:
wxBitmap *bmp = cache.load_svg(bmp_name, width, height, scale_factor, grayscale, Slic3r::GUI::wxGetApp().dark_mode()); wxBitmap *bmp = cache.load_svg(bmp_name, width, height, scale_factor, grayscale, Slic3r::GUI::wxGetApp().dark_mode());
if (bmp == nullptr) { if (bmp == nullptr) {
@ -682,7 +666,7 @@ void ObjectDataViewModelNode::update_settings_digest_bitmaps()
for (auto& cat : m_opt_categories) for (auto& cat : m_opt_categories)
bmps.emplace_back( categories_icon.find(cat) == categories_icon.end() ? bmps.emplace_back( categories_icon.find(cat) == categories_icon.end() ?
wxNullBitmap : categories_icon.at(cat)); wxNullBitmap : categories_icon.at(cat));
bmp = m_bitmap_cache->insert(scaled_bitmap_name, bmps); bmp = m_bitmap_cache->insert(scaled_bitmap_name, bmps, get_svg_scale_factor(m_ctrl));
} }
m_bmp = *bmp; m_bmp = *bmp;
@ -2470,18 +2454,17 @@ void MenuWithSeparators::SetSecondSeparator()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
ScalableBitmap::ScalableBitmap( wxWindow *parent, ScalableBitmap::ScalableBitmap( wxWindow *parent,
const std::string& icon_name/* = ""*/, const std::string& icon_name/* = ""*/,
const int px_cnt/* = 16*/, const int px_cnt/* = 16*/):
const bool is_horizontal/* = false*/):
m_parent(parent), m_icon_name(icon_name), m_parent(parent), m_icon_name(icon_name),
m_px_cnt(px_cnt), m_is_horizontal(is_horizontal) m_px_cnt(px_cnt)
{ {
m_bmp = create_scaled_bitmap(parent, icon_name, px_cnt, is_horizontal); m_bmp = create_scaled_bitmap(parent, icon_name, px_cnt);
} }
void ScalableBitmap::msw_rescale() void ScalableBitmap::msw_rescale()
{ {
m_bmp = create_scaled_bitmap(m_parent, m_icon_name, m_px_cnt, m_is_horizontal); m_bmp = create_scaled_bitmap(m_parent, m_icon_name, m_px_cnt);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -2522,8 +2505,7 @@ ScalableButton::ScalableButton( wxWindow * parent,
long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) : long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) :
m_parent(parent), m_parent(parent),
m_current_icon_name(bitmap.name()), m_current_icon_name(bitmap.name()),
m_px_cnt(bitmap.px_cnt()), m_px_cnt(bitmap.px_cnt())
m_is_horizontal(bitmap.is_horizontal())
{ {
Create(parent, id, label, wxDefaultPosition, wxDefaultSize, style); Create(parent, id, label, wxDefaultPosition, wxDefaultSize, style);
#ifdef __WXMSW__ #ifdef __WXMSW__
@ -2554,9 +2536,9 @@ int ScalableButton::GetBitmapHeight()
void ScalableButton::msw_rescale() void ScalableButton::msw_rescale()
{ {
SetBitmap(create_scaled_bitmap(m_parent, m_current_icon_name, m_px_cnt, m_is_horizontal)); SetBitmap(create_scaled_bitmap(m_parent, m_current_icon_name, m_px_cnt));
if (!m_disabled_icon_name.empty()) if (!m_disabled_icon_name.empty())
SetBitmapDisabled(create_scaled_bitmap(m_parent, m_disabled_icon_name, m_px_cnt, m_is_horizontal)); SetBitmapDisabled(create_scaled_bitmap(m_parent, m_disabled_icon_name, m_px_cnt));
if (m_width > 0 || m_height>0) if (m_width > 0 || m_height>0)
{ {

View File

@ -56,7 +56,7 @@ int em_unit(wxWindow* win);
float get_svg_scale_factor(wxWindow* win); float get_svg_scale_factor(wxWindow* win);
wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name, wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name,
const int px_cnt = 16, const bool is_horizontal = false, const bool grayscale = false); const int px_cnt = 16, const bool grayscale = false);
std::vector<wxBitmap*> get_extruder_color_icons(bool thin_icon = false); std::vector<wxBitmap*> get_extruder_color_icons(bool thin_icon = false);
void apply_extruder_selector(wxBitmapComboBox** ctrl, void apply_extruder_selector(wxBitmapComboBox** ctrl,
@ -729,8 +729,7 @@ public:
ScalableBitmap() {}; ScalableBitmap() {};
ScalableBitmap( wxWindow *parent, ScalableBitmap( wxWindow *parent,
const std::string& icon_name = "", const std::string& icon_name = "",
const int px_cnt = 16, const int px_cnt = 16);
const bool is_horizontal = false);
~ScalableBitmap() {} ~ScalableBitmap() {}
@ -741,14 +740,12 @@ public:
const std::string& name() const{ return m_icon_name; } const std::string& name() const{ return m_icon_name; }
int px_cnt()const {return m_px_cnt;} int px_cnt()const {return m_px_cnt;}
bool is_horizontal()const {return m_is_horizontal;}
private: private:
wxWindow* m_parent{ nullptr }; wxWindow* m_parent{ nullptr };
wxBitmap m_bmp = wxBitmap(); wxBitmap m_bmp = wxBitmap();
std::string m_icon_name = ""; std::string m_icon_name = "";
int m_px_cnt {16}; int m_px_cnt {16};
bool m_is_horizontal {false};
}; };
@ -832,7 +829,6 @@ private:
// bitmap dimensions // bitmap dimensions
int m_px_cnt{ 16 }; int m_px_cnt{ 16 };
bool m_is_horizontal{ false };
}; };