diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index d785a71a..03440bd6 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -1591,11 +1591,26 @@ size_t available_physical_memory() return (size_t) status.ullAvailPhys; #elif defined(__linux__) - struct sysinfo info; - if (sysinfo(&info) == 0) { - return info.freeram * info.mem_unit; + // Prefer MemAvailable (free + reclaimable page/buffer cache) from + // /proc/meminfo. sysinfo().freeram is only MemFree, which Linux keeps + // low by design (idle RAM is used for cache), so it grossly understates + // usable memory and must not be treated as "available". + if (FILE* mi = fopen("/proc/meminfo", "r")) { + char line[256]; + unsigned long long kb = 0; + bool found = false; + while (fgets(line, sizeof(line), mi) != nullptr) { + if (sscanf(line, "MemAvailable: %llu kB", &kb) == 1) { found = true; break; } + } + fclose(mi); + if (found) + return (size_t)kb * (size_t)1024; } - return 0L; + // Fallback for kernels < 3.14 without MemAvailable: free + buffers. + struct sysinfo info; + if (sysinfo(&info) == 0) + return (size_t)(info.freeram + info.bufferram) * (size_t)info.mem_unit; + return 0L; #elif defined(__APPLE__) int mib[2] = {CTL_HW, HW_MEMSIZE}; uint64_t memsize; diff --git a/src/slic3r/GUI/GCodeRenderer/AdvancedRenderer.cpp b/src/slic3r/GUI/GCodeRenderer/AdvancedRenderer.cpp index a5133ae4..92c77b7e 100644 --- a/src/slic3r/GUI/GCodeRenderer/AdvancedRenderer.cpp +++ b/src/slic3r/GUI/GCodeRenderer/AdvancedRenderer.cpp @@ -748,20 +748,12 @@ namespace Slic3r // Import gcode file, preview using normal mode (no lite mode) bool is_lite_mode_cfg = (wxGetApp().app_config->get_bool("gcode_preview_lite_mode") && (!m_only_gcode_in_preview)); - // Auto enable lite mode on Linux if memory is tight or preview is huge. -#if defined(__linux__) - { - size_t avail_bytes = Slic3r::available_physical_memory(); - size_t total_bytes = Slic3r::total_physical_memory(); - const size_t moves_count_local = gcode_result.moves.size(); - const size_t avail_threshold_bytes = size_t(2) * size_t(1024) * size_t(1024) * size_t(1024); // 2 GB - const bool low_available = (avail_bytes > 0 && avail_bytes < avail_threshold_bytes); - const bool low_ratio = (total_bytes > 0 && avail_bytes > 0 && (double) avail_bytes / (double) total_bytes < 0.125); - const bool huge_preview = (moves_count_local > 2000000); - if (!m_only_gcode_in_preview && (low_available || low_ratio || huge_preview)) - is_lite_mode_cfg = true; - } -#endif + // NOTE (#512): Removed the Linux-only auto-enable-lite-mode heuristic. + // It force-enabled lite mode against the user's explicit + // gcode_preview_lite_mode=false setting, and tripped on broken memory + // readings (available/total reported as 0 on some systems), permanently + // hiding infill in the preview on Linux. Lite mode is now strictly + // driven by the gcode_preview_lite_mode config value above. const bool is_lite_mode = m_is_lite_mode = is_lite_mode_cfg; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 2b6e5420..47f2ca5e 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -742,31 +742,11 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode) // import gcode file, preview using normal mode (no lite mode) bool is_lite_mode = wxGetApp().app_config->get_bool("gcode_preview_lite_mode") && (!only_gcode); - // Auto enable lite mode on Linux if memory is tight or preview is huge - // This does NOT affect Windows and does not persist the setting. -#if defined(__linux__) - { - size_t avail_bytes = Slic3r::available_physical_memory(); - size_t total_bytes = Slic3r::total_physical_memory(); - const size_t moves_count = m_gcode_result ? m_gcode_result->moves.size() : 0; - - // Heuristics: - // - Consider memory tight if available < 2 GB or available < 12.5% of total. - // - Consider preview huge if moves exceed 2 million. - const size_t avail_threshold_bytes = size_t(2) * size_t(1024) * size_t(1024) * size_t(1024); // 2 GB - const bool low_available = (avail_bytes > 0 && avail_bytes < avail_threshold_bytes); - const bool low_ratio = (total_bytes > 0 && avail_bytes > 0 && (double)avail_bytes / (double)total_bytes < 0.125); - const bool huge_preview = (moves_count > 2000000); - - if (!only_gcode && (low_available || low_ratio || huge_preview)) { - is_lite_mode = true; - // Also enable shell-only surface rendering to further reduce load. - if (m_gcode_result) { - m_gcode_result->all_surface_with_shell = true; - } - } - } -#endif + // NOTE (#512): removed the Linux auto-enable-lite-mode heuristic + // here (mirrors the advanced renderer). It overrode the user's + // explicit gcode_preview_lite_mode setting and, because + // available_physical_memory() reported MemFree, fired on almost + // every Linux machine. Lite mode now follows the config value above. std::vector> changed_tmp; GCodeProcessorResult* tmp_result = nullptr; if (is_lite_mode) {