diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 690a0ed359..3b7f810268 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -4328,62 +4328,22 @@ void GCodeProcessor::post_process() out.close(); in.close(); + const std::string result_filename = m_result.filename; if (m_binarizer.is_enabled()) { - // updates m_result.lines_ends from binarized gcode file - m_result.lines_ends.clear(); - - FilePtr file(boost::nowide::fopen(out_path.c_str(), "rb")); - if (file.f != nullptr) { - fseek(file.f, 0, SEEK_END); - const long file_size = ftell(file.f); - rewind(file.f); - - // read file header - using namespace bgcode::core; - using namespace bgcode::binarize; - FileHeader file_header; - EResult res = read_header(*file.f, file_header, nullptr); - if (res == EResult::Success) { - // search first GCode block - BlockHeader block_header; - res = read_next_block_header(*file.f, file_header, block_header, EBlockType::GCode, nullptr, 0); - while (res == EResult::Success) { - GCodeBlock block; - res = block.read_data(*file.f, file_header, block_header); - if (res != EResult::Success) - break; - - // extract lines ends from block - std::vector& lines_ends = m_result.lines_ends.emplace_back(std::vector()); - for (size_t i = 0; i < block.raw_data.size(); ++i) { - if (block.raw_data[i] == '\n') - lines_ends.emplace_back(i + 1); - } - - if (ftell(file.f) == file_size) - break; - - // read next block header - res = read_next_block_header(*file.f, file_header, block_header, nullptr, 0); - if (res != EResult::Success) - break; - if (block_header.type != (uint16_t)EBlockType::GCode) { - res = EResult::InvalidBlockType; - break; - } - } - } - - if (res != EResult::Success && !m_result.lines_ends.empty() && !m_result.lines_ends.front().empty()) - // some error occourred, clear lines ends - m_result.lines_ends = { std::vector() }; - } + // The list of lines in the binary gcode is different from the original one. + // This requires to re-process the binarized file to be able to synchronize with it all the data needed by the preview, + // as gcode window, tool position and moves slider which relies on indexing the gcode lines. + reset(); + // the following call modifies m_result.filename + process_binary_file(out_path); + // restore the proper filename + m_result.filename = result_filename; } + else + export_lines.synchronize_moves(m_result); - export_lines.synchronize_moves(m_result); - - if (rename_file(out_path, m_result.filename)) - throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + m_result.filename + '\n' + + if (rename_file(out_path, result_filename)) + throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + result_filename + '\n' + "Is " + out_path + " locked?" + '\n'); } diff --git a/src/platform/osx/Info.plist.in b/src/platform/osx/Info.plist.in index bed2db6ba5..13840b64dc 100644 --- a/src/platform/osx/Info.plist.in +++ b/src/platform/osx/Info.plist.in @@ -109,6 +109,23 @@ LSHandlerRank Alternate + + CFBundleTypeExtensions + + bgcode + BGCODE + + CFBundleTypeIconFile + bgcode.icns + CFBundleTypeName + BGCODE + CFBundleTypeRole + Viewer + LISsAppleDefaultForType + + LSHandlerRank + Alternate + CFBundleURLTypes diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index a56ae818ec..14e73e0484 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -2258,20 +2258,22 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) if (move.type == EMoveType::Seam) ++seams_count; - size_t move_id = i - seams_count; + const size_t move_id = i - seams_count; if (move.type == EMoveType::Extrude) { - if (!move.internal_only) { - // layers zs - const double* const last_z = m_layers.empty() ? nullptr : &m_layers.get_zs().back(); - const double z = static_cast(move.position.z()); - if (last_z == nullptr || z < *last_z - EPSILON || *last_z + EPSILON < z) { - const size_t start_it = (m_layers.empty() && first_travel_s_id != 0) ? first_travel_s_id : last_travel_s_id; - m_layers.append(z, { start_it, move_id }); - } - else - m_layers.get_ranges().back().last = move_id; + // layers zs/ranges + const double* const last_z = m_layers.empty() ? nullptr : &m_layers.get_zs().back(); + const double z = static_cast(move.position.z()); + if (last_z == nullptr || z < *last_z - EPSILON || *last_z + EPSILON < z) { + // start a new layer + const size_t start_it = (m_layers.empty() && first_travel_s_id != 0) ? first_travel_s_id : last_travel_s_id; + m_layers.append(z, { start_it, move_id }); } + else if (!move.internal_only) { + // update last layer + m_layers.get_ranges().back().last = move_id; + } + // extruder ids m_extruder_ids.emplace_back(move.extruder_id); // roles diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 47e7b4ab55..4d760c7e9f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1528,6 +1528,8 @@ bool GLCanvas3D::check_volumes_outside_state(GLVolumeCollection& volumes, ModelI contained_min_one |= !volume->is_outside; } } + else if (volume->is_modifier) + volume->is_outside = false; } for (unsigned int vol_idx = 0; vol_idx < volumes.volumes.size(); ++vol_idx) { @@ -2371,6 +2373,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re volume->extruder_id = extruder_id; volume->is_modifier = !mvs->model_volume->is_model_part(); + volume->shader_outside_printer_detection_enabled = mvs->model_volume->is_model_part(); volume->set_color(color_from_model_volume(*mvs->model_volume)); // force update of render_color alpha channel volume->set_render_color(volume->color.is_transparent()); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 92d7bbfc04..45ce29468f 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -4547,6 +4547,7 @@ void SubstitutionManager::init(DynamicPrintConfig* config, wxWindow* parent, wxF m_em = em_unit(parent); m_substitutions = m_config->option("gcode_substitutions")->values; + m_chb_match_single_lines.clear(); } void SubstitutionManager::validate_length() diff --git a/tests/slic3rutils/slic3r_jobs_tests.cpp b/tests/slic3rutils/slic3r_jobs_tests.cpp index 5dc1b8e05b..abb8b15265 100644 --- a/tests/slic3rutils/slic3r_jobs_tests.cpp +++ b/tests/slic3rutils/slic3r_jobs_tests.cpp @@ -57,11 +57,10 @@ TEMPLATE_LIST_TEST_CASE("State should not be idle while running a job", "[Jobs]" }).wait(); }); - worker.wait_for_idle(); + // make sure that the job starts BEFORE the worker.wait_for_idle() is called + std::this_thread::sleep_for(std::chrono::milliseconds(100)); - // To avoid stalling the job, in case the wait_for_idle is called before - // the job goes into blocking wait - worker.process_events(); + worker.wait_for_idle(); REQUIRE(worker.is_idle()); } @@ -79,13 +78,12 @@ TEMPLATE_LIST_TEST_CASE("Status messages should be received by the main thread d }); worker.wait_for_idle(); - worker.process_events(); REQUIRE(pri->pr == 100); REQUIRE(pri->statustxt == "Running"); } -TEMPLATE_LIST_TEST_CASE("Cancellation should be recognized by the worker", "[Jobs]", TestClasses) { +TEMPLATE_LIST_TEST_CASE("Cancellation should be recognized be the worker", "[Jobs]", TestClasses) { using namespace Slic3r; using namespace Slic3r::GUI; @@ -110,7 +108,6 @@ TEMPLATE_LIST_TEST_CASE("Cancellation should be recognized by the worker", "[Job worker.cancel(); worker.wait_for_current_job(); - worker.process_events(); REQUIRE(pri->pr != 100); } @@ -148,7 +145,6 @@ TEMPLATE_LIST_TEST_CASE("cancel_all should remove all pending jobs", "[Jobs]", T // during the first job's execution. std::this_thread::sleep_for(std::chrono::milliseconds(500)); worker.cancel_all(); - worker.process_events(); REQUIRE(jobres[0] == true); REQUIRE(jobres[1] == false); @@ -177,7 +173,5 @@ TEMPLATE_LIST_TEST_CASE("Exception should be properly forwarded to finalize()", }); worker.wait_for_idle(); - worker.process_events(); - REQUIRE(worker.is_idle()); }