diff --git a/src/libseqarrange/include/libseqarrange/seq_interface.hpp b/src/libseqarrange/include/libseqarrange/seq_interface.hpp index 3e269bcc96..cfca3f6d28 100644 --- a/src/libseqarrange/include/libseqarrange/seq_interface.hpp +++ b/src/libseqarrange/include/libseqarrange/seq_interface.hpp @@ -137,6 +137,21 @@ bool check_ScheduledObjectsForSequentialPrintability(const SolverConfiguration const std::vector &objects_to_print, const std::vector &scheduled_plates); +/* + This is a variant of the interface for checking sequential printability. + + If not sequentially printable returns a pair of object IDs that are in conflict, + that is, when the second object is printed the extruder will collide with the + first object. The returned conflict is not necessarily the first collision to + occur when printing the object according to the given input schedule. + + Note: The function always succeeds, does not throw any exception. + */ +std::optional > check_ScheduledObjectsForSequentialConflict(const SolverConfiguration &solver_configuration, + const PrinterGeometry &printer_geometry, + const std::vector &objects_to_print, + const std::vector &scheduled_plates); + /*----------------------------------------------------------------*/ /* @@ -160,15 +175,13 @@ bool check_ScheduledObjectsForSequentialPrintability(const SolverConfiguration std::vector schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_configuration, const PrinterGeometry &printer_geometry, const std::vector &objects_to_print, - std::function progress_callback = [](int progress){}, - bool trans_bed_glue = false); + std::function progress_callback = [](int progress){}); void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_configuration, const PrinterGeometry &printer_geometry, const std::vector &objects_to_print, std::vector &scheduled_plates, - std::function progress_callback = [](int progress){}, - bool trans_bed_glue = false); + std::function progress_callback = [](int progress){}); /*----------------------------------------------------------------*/ @@ -179,8 +192,7 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_configuration, const std::vector &objects_to_print, std::vector &scheduled_plates, - std::function progress_callback = [](int progress){}, - bool trans_bed_glue = false); + std::function progress_callback = [](int progress){}); void setup_ExtruderUnreachableZones(const SolverConfiguration &solver_configuration, std::vector > &convex_unreachable_zones, @@ -191,8 +203,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration const std::vector > &convex_unreachable_zones, const std::vector > &box_unreachable_zones, std::vector &scheduled_plates, - std::function progress_callback = [](int progress){}, - bool trans_bed_glue = false); + std::function progress_callback = [](int progress){}); /*----------------------------------------------------------------*/ diff --git a/src/libseqarrange/src/seq_interface.cpp b/src/libseqarrange/src/seq_interface.cpp index 1e44da9b16..89165ca9f4 100644 --- a/src/libseqarrange/src/seq_interface.cpp +++ b/src/libseqarrange/src/seq_interface.cpp @@ -176,10 +176,27 @@ void SolverConfiguration::set_ObjectGroupSize(int _object_group_size) /*----------------------------------------------------------------*/ + bool check_ScheduledObjectsForSequentialPrintability(const SolverConfiguration &solver_configuration, const PrinterGeometry &printer_geometry, const std::vector &objects_to_print, const std::vector &scheduled_plates) +{ + if (check_ScheduledObjectsForSequentialConflict(solver_configuration, + printer_geometry, + objects_to_print, + scheduled_plates)) + { + return false; + } + return true; +} + + +std::optional > check_ScheduledObjectsForSequentialConflict(const SolverConfiguration &solver_configuration, + const PrinterGeometry &printer_geometry, + const std::vector &objects_to_print, + const std::vector &scheduled_plates) { std::vector polygons; std::vector > unreachable_polygons; @@ -268,15 +285,15 @@ bool check_ScheduledObjectsForSequentialPrintability(const SolverConfiguration { printf("Point check ...\n"); } - #endif - - if (!check_PointsOutsidePolygons(dec_values_X, - dec_values_Y, - dec_values_T, - plate_polygons, - plate_unreachable_polygons)) + #endif + + if (auto conflict = check_PointsOutsidePolygons(dec_values_X, + dec_values_Y, + dec_values_T, + plate_polygons, + plate_unreachable_polygons)) { - return false; + return std::pair(objects_to_print[conflict.value().first].id, objects_to_print[conflict.value().second].id); } #ifdef DEBUG { @@ -290,13 +307,13 @@ bool check_ScheduledObjectsForSequentialPrintability(const SolverConfiguration } #endif - if (!check_PolygonLineIntersections(dec_values_X, - dec_values_Y, - dec_values_T, - plate_polygons, - plate_unreachable_polygons)) + if (auto conflict = check_PolygonLineIntersections(dec_values_X, + dec_values_Y, + dec_values_T, + plate_polygons, + plate_unreachable_polygons)) { - return false; + return std::pair(objects_to_print[conflict.value().first].id, objects_to_print[conflict.value().second].id); } #ifdef DEBUG { @@ -310,17 +327,16 @@ bool check_ScheduledObjectsForSequentialPrintability(const SolverConfiguration } #endif - return true; + return {}; } - + /*----------------------------------------------------------------*/ std::vector schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_configuration, const PrinterGeometry &printer_geometry, const std::vector &objects_to_print, - std::function progress_callback, - bool trans_bed_glue) + std::function progress_callback) { std::vector scheduled_plates; @@ -328,8 +344,7 @@ std::vector schedule_ObjectsForSequentialPrint(const SolverConfi printer_geometry, objects_to_print, scheduled_plates, - progress_callback, - trans_bed_glue); + progress_callback); return scheduled_plates; } @@ -351,8 +366,7 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver const PrinterGeometry &printer_geometry, const std::vector &objects_to_print, std::vector &scheduled_plates, - std::function progress_callback, - bool trans_bed_glue) + std::function progress_callback) { #ifdef PROFILE clock_t start, finish; @@ -424,7 +438,7 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver int progress_object_phases_done = 0; int progress_object_phases_total = SEQ_MAKE_EXTRA_PROGRESS((objects_to_print.size() * SEQ_PROGRESS_PHASES_PER_OBJECT)); - bool trans_bed_lepox = trans_bed_glue; + bool trans_bed_lepox = false; do { @@ -591,8 +605,7 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_configuration, const std::vector &objects_to_print, std::vector &scheduled_plates, - std::function progress_callback, - bool trans_bed_glue) + std::function progress_callback) { #ifdef PROFILE clock_t start, finish; @@ -842,7 +855,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_ int progress_object_phases_done = 0; int progress_object_phases_total = SEQ_MAKE_EXTRA_PROGRESS((objects_to_print.size() * SEQ_PROGRESS_PHASES_PER_OBJECT)); - bool trans_bed_lepox = trans_bed_glue; + bool trans_bed_lepox = false; do { @@ -1044,8 +1057,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration const std::vector > &convex_unreachable_zones, const std::vector > &box_unreachable_zones, std::vector &scheduled_plates, - std::function progress_callback, - bool trans_bed_glue) + std::function progress_callback) { #ifdef PROFILE clock_t start, finish; @@ -1181,7 +1193,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration int progress_object_phases_done = 0; int progress_object_phases_total = SEQ_MAKE_EXTRA_PROGRESS((objects_to_print.size() * SEQ_PROGRESS_PHASES_PER_OBJECT)); - bool trans_bed_lepox = trans_bed_glue; + bool trans_bed_lepox = false; do { diff --git a/src/libseqarrange/src/seq_sequential.cpp b/src/libseqarrange/src/seq_sequential.cpp index 3a35bd6776..7a104378b6 100644 --- a/src/libseqarrange/src/seq_sequential.cpp +++ b/src/libseqarrange/src/seq_sequential.cpp @@ -6443,11 +6443,11 @@ bool refine_ConsequentialPolygonWeakNonoverlapping(z3::solver /*----------------------------------------------------------------*/ -bool check_PointsOutsidePolygons(const std::vector &dec_values_X, - const std::vector &dec_values_Y, - const std::vector &dec_values_T, - const std::vector &polygons, - const std::vector > &unreachable_polygons) +std::optional > check_PointsOutsidePolygons(const std::vector &dec_values_X, + const std::vector &dec_values_Y, + const std::vector &dec_values_T, + const std::vector &polygons, + const std::vector > &unreachable_polygons) { #ifdef DEBUG { @@ -6653,7 +6653,7 @@ bool check_PointsOutsidePolygons(const std::vector } if (always_inside_halfplane) { - return false; + return std::pair(j, i); } } } @@ -6716,7 +6716,7 @@ bool check_PointsOutsidePolygons(const std::vector } if (always_inside_halfplane) { - return false; + return std::pair(i, j); } } } @@ -6740,15 +6740,15 @@ bool check_PointsOutsidePolygons(const std::vector } #endif - return true; + return {}; } -bool check_PolygonLineIntersections(const std::vector &dec_values_X, - const std::vector &dec_values_Y, - const std::vector &dec_values_T, - const std::vector &polygons, - const std::vector > &unreachable_polygons) +std::optional > check_PolygonLineIntersections(const std::vector &dec_values_X, + const std::vector &dec_values_Y, + const std::vector &dec_values_T, + const std::vector &polygons, + const std::vector > &unreachable_polygons) { if (!polygons.empty()) { @@ -6814,7 +6814,7 @@ bool check_PolygonLineIntersections(const std::vector } #endif - return false; + return std::pair(j, i); } } } @@ -6878,7 +6878,7 @@ bool check_PolygonLineIntersections(const std::vector } #endif - return false; + return std::pair(i, j); } } } @@ -6904,7 +6904,7 @@ bool check_PolygonLineIntersections(const std::vector } #endif - return true; + return {}; } diff --git a/src/libseqarrange/src/seq_sequential.hpp b/src/libseqarrange/src/seq_sequential.hpp index 0ed4799796..dbb15c3398 100644 --- a/src/libseqarrange/src/seq_sequential.hpp +++ b/src/libseqarrange/src/seq_sequential.hpp @@ -1223,17 +1223,17 @@ bool refine_ConsequentialPolygonWeakNonoverlapping(z3::solver /*----------------------------------------------------------------*/ -bool check_PointsOutsidePolygons(const std::vector &dec_values_X, - const std::vector &dec_values_Y, - const std::vector &dec_values_T, - const std::vector &polygons, - const std::vector > &unreachable_polygons); +std::optional > check_PointsOutsidePolygons(const std::vector &dec_values_X, + const std::vector &dec_values_Y, + const std::vector &dec_values_T, + const std::vector &polygons, + const std::vector > &unreachable_polygons); -bool check_PolygonLineIntersections(const std::vector &dec_values_X, - const std::vector &dec_values_Y, - const std::vector &dec_values_T, - const std::vector &polygons, - const std::vector > &unreachable_polygons); +std::optional > check_PolygonLineIntersections(const std::vector &dec_values_X, + const std::vector &dec_values_Y, + const std::vector &dec_values_T, + const std::vector &polygons, + const std::vector > &unreachable_polygons); /*----------------------------------------------------------------*/ diff --git a/src/libslic3r/ArrangeHelper.cpp b/src/libslic3r/ArrangeHelper.cpp index a18a565183..339aa42dfe 100644 --- a/src/libslic3r/ArrangeHelper.cpp +++ b/src/libslic3r/ArrangeHelper.cpp @@ -338,10 +338,17 @@ void SeqArrange::apply_seq_arrange(Model& model) const - - - bool check_seq_printability(const Model& model, const ConfigBase& config) +{ + if (auto conflict = check_seq_conflict(model, config)) + { + return false; + } + return true; +} + + +std::optional > check_seq_conflict(const Model& model, const ConfigBase& config) { Sequential::PrinterGeometry printer_geometry = get_printer_geometry(config); Sequential::SolverConfiguration solver_config = get_solver_config(printer_geometry); @@ -350,7 +357,7 @@ bool check_seq_printability(const Model& model, const ConfigBase& config) if (printer_geometry.extruder_slices.empty()) { // If there are no data for extruder (such as extruder_clearance_radius set to 0), // consider it printable. - return true; + return {}; } Sequential::ScheduledPlate plate; @@ -373,7 +380,8 @@ bool check_seq_printability(const Model& model, const ConfigBase& config) } } - return Sequential::check_ScheduledObjectsForSequentialPrintability(solver_config, printer_geometry, objects, std::vector(1, plate)); + //return Sequential::check_ScheduledObjectsForSequentialPrintability(solver_config, printer_geometry, objects, std::vector(1, plate)); + return Sequential::check_ScheduledObjectsForSequentialConflict(solver_config, printer_geometry, objects, std::vector(1, plate)); } diff --git a/src/libslic3r/ArrangeHelper.hpp b/src/libslic3r/ArrangeHelper.hpp index 4e600d834b..e9e6213877 100644 --- a/src/libslic3r/ArrangeHelper.hpp +++ b/src/libslic3r/ArrangeHelper.hpp @@ -14,7 +14,9 @@ namespace Slic3r { class ExceptionCannotApplySeqArrange : public std::exception {}; void arrange_model_sequential(Model& model, const ConfigBase& config); + bool check_seq_printability(const Model& model, const ConfigBase& config); + std::optional > check_seq_conflict(const Model& model, const ConfigBase& config); // This is just a helper class to collect data for seq. arrangement, running the arrangement // and applying the results to model. It is here so the processing itself can be offloaded @@ -38,4 +40,4 @@ namespace Slic3r { } -#endif // slic3r_Arrange_Helper_hpp \ No newline at end of file +#endif // slic3r_Arrange_Helper_hpp