diff --git a/src/libslic3r/GCode/ConflictChecker.cpp b/src/libslic3r/GCode/ConflictChecker.cpp index 3cf1aa49a4..8f36d65d96 100644 --- a/src/libslic3r/GCode/ConflictChecker.cpp +++ b/src/libslic3r/GCode/ConflictChecker.cpp @@ -201,6 +201,7 @@ ConflictRet ConflictChecker::find_inter_of_lines(const LineWithIDs &lines) ConflictRet ConflictChecker::find_inter_of_lines_in_diff_objs(PrintObjectPtrs objs) // find the first intersection point of lines in different objects { + if (objs.size() <= 1) { return {}; } LinesBucketQueue conflictQueue; for (PrintObject *obj : objs) { auto layers = getAllLayersExtrusionPathsFromObject(obj); diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index ed304fc572..96dedabb82 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -90,6 +90,29 @@ namespace Slic3r { struct GCodeProcessorResult { + //BBS + struct ConflictResult + { + bool conflicted; + std::string obj1Name; + std::string obj2Name; + + void set(const std::string &o1, const std::string &o2) + { + conflicted = true; + obj1Name = o1; + obj2Name = o2; + } + + void reset() { + conflicted = false; + obj1Name.clear(); + obj2Name.clear(); + } + + ConflictResult() = default; + ConflictResult(const ConflictResult &) = default; + }conflict_result; struct SettingsIds { diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 9647b3e412..02755f8dba 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1669,20 +1669,20 @@ void Print::process(bool use_cache) // BBS if(!m_no_check) { - this->set_started(psConflictCheck); - this->set_status(70, L("Checking gcode path conflicts.")); using Clock = std::chrono::high_resolution_clock; auto startTime = Clock::now(); auto conflictRes = ConflictChecker::find_inter_of_lines_in_diff_objs(m_objects); auto endTime = Clock::now(); volatile double seconds = std::chrono::duration_cast(endTime - startTime).count() / (double) 1000; + BOOST_LOG_TRIVIAL(info) << "gcode path conflicts check takes " << seconds << " secs."; + if (conflictRes.has_value()) { + m_conflict_result.set(conflictRes.value()._obj1, conflictRes.value()._obj2); auto objName1 = conflictRes.value()._obj1->m_model_object->name; auto objName2 = conflictRes.value()._obj2->m_model_object->name; - //throw Slic3r::SlicingError((boost::format(L("Conflicts of gcode paths have been found. Please separate the conflicted objects (%s + %s) farther.")) % objName1% objName2).str()); - this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, (boost::format(L("Conflicts of gcode paths have been found. Please separate the conflicted objects (%s <-> %s) farther.")) % objName1 % objName2).str()); + } else { + m_conflict_result.reset(); } - this->set_done(psConflictCheck); } BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info(); @@ -1713,6 +1713,12 @@ std::string Print::export_gcode(const std::string& path_template, GCodeProcessor const Vec3d origin = this->get_plate_origin(); gcode.set_gcode_offset(origin(0), origin(1)); gcode.do_export(this, path.c_str(), result, thumbnail_cb); + //BBS + if (m_conflict_result.conflicted) { + result->conflict_result.set(m_conflict_result.obj1->m_model_object->name, m_conflict_result.obj2->m_model_object->name); + } else { + result->conflict_result.reset(); + } return path.c_str(); } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 4509162718..b68d0a95af 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -774,6 +774,28 @@ private: Vec3d m_origin; //BBS: modified_count int m_modified_count {0}; + //BBS + struct ConflictResult + { + bool conflicted; + PrintObject *obj1; + PrintObject *obj2; + //TODO + //the actual loaction + + void set(PrintObject *o1, PrintObject *o2) + { + conflicted = true; + obj1 = o1; + obj2 = o2; + } + void reset() + { + conflicted = false; + obj1 = nullptr; + obj2 = nullptr; + } + }m_conflict_result; // To allow GCode to set the Print's GCodeExport step status. friend class GCode; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 121e85083c..fad67e19c9 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1097,6 +1097,9 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr m_layers_slider->set_as_dirty(); m_moves_slider->set_as_dirty(); + //BBS + m_conflict_result = gcode_result.conflict_result; + //BBS: add mutex for protection of gcode result gcode_result.unlock(); //BBS: add logs diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 05cca2039c..4642061817 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -722,6 +722,9 @@ public: Count }; + //BBS + GCodeProcessorResult::ConflictResult m_conflict_result; + private: std::vector m_plater_extruder; bool m_gl_data_initialized{ false }; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 90c41cb8ff..fa636b4cc7 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2706,6 +2706,7 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, co //BBS: always load shell at preview, do this in load_shells //m_gcode_viewer.update_shells_color_by_extruder(m_config); _set_warning_notification_if_needed(EWarning::ToolpathOutside); + _set_warning_notification_if_needed(EWarning::GCodeConflict); } m_gcode_viewer.refresh(gcode_result, str_tool_colors); @@ -8785,7 +8786,10 @@ void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning) else { if (wxGetApp().is_editor()) { if (current_printer_technology() != ptSLA) - show = m_gcode_viewer.has_data() && !m_gcode_viewer.is_contained_in_bed(); + if (warning == EWarning::ToolpathOutside) + show = m_gcode_viewer.has_data() && !m_gcode_viewer.is_contained_in_bed(); + else if (warning==EWarning::GCodeConflict) + show = m_gcode_viewer.has_data() && m_gcode_viewer.is_contained_in_bed() && m_gcode_viewer.m_conflict_result.conflicted; } } @@ -8824,6 +8828,13 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state) std::string text; ErrorType error = ErrorType::PLATER_WARNING; switch (warning) { + case EWarning::GCodeConflict: { + std::string objName1 = m_gcode_viewer.m_conflict_result.obj1Name; + std::string objName2 = m_gcode_viewer.m_conflict_result.obj2Name; + text = (boost::format(L("Conflicts of gcode paths have been found. Please separate the conflicted objects farther (%s <-> %s).")) % objName1 % objName2).str(); + error = ErrorType::SLICING_ERROR; + break; + } case EWarning::ObjectOutside: text = _u8L("An object is layed over the boundary of plate."); break; case EWarning::ToolpathOutside: text = _u8L("A G-code path goes beyond the boundary of plate."); error = ErrorType::SLICING_ERROR; break; // BBS: remove _u8L() for SLA diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index a3628de6dd..0325cf6e28 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -372,7 +372,8 @@ class GLCanvas3D ToolpathOutside, SlaSupportsOutside, SomethingNotShown, - ObjectClashed + ObjectClashed, + GCodeConflict }; class RenderStats diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index 4076df6fa6..0046a29187 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -381,7 +381,7 @@ public: { bool result = m_slice_result_valid; if (result) - result = m_gcode_result ? (!m_gcode_result->toolpath_outside) : false; + result = m_gcode_result ? (!m_gcode_result->toolpath_outside && !m_gcode_result->conflict_result.conflicted) : false; return result; }