From 1259d59098bb478f0bfc6f67c4a6c6312420220a Mon Sep 17 00:00:00 2001 From: surynek Date: Wed, 12 Feb 2025 13:36:42 +0100 Subject: [PATCH] Revisited scheduling of object instances via object gluing, added object gluing across multple beds. --- src/libseqarrange/src/seq_interface.cpp | 91 ++++++++- src/libseqarrange/src/seq_sequential.cpp | 207 +++++++++++++++++---- src/libseqarrange/src/seq_sequential.hpp | 6 +- src/libseqarrange/src/sequential_prusa.cpp | 35 +++- 4 files changed, 301 insertions(+), 38 deletions(-) diff --git a/src/libseqarrange/src/seq_interface.cpp b/src/libseqarrange/src/seq_interface.cpp index b546ab682d..fa147f288d 100644 --- a/src/libseqarrange/src/seq_interface.cpp +++ b/src/libseqarrange/src/seq_interface.cpp @@ -331,7 +331,20 @@ std::vector schedule_ObjectsForSequentialPrint(const SolverConfi return scheduled_plates; } - + +bool is_scheduled(int i, const std::vector &decided_polygons) +{ + for (unsigned int j = 0; j < decided_polygons.size(); ++j) + { + if (decided_polygons[j] == i) + { + return true; + } + } + return false; +} + + void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_configuration, const PrinterGeometry &printer_geometry, const std::vector &objects_to_print, @@ -350,8 +363,6 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver #endif std::map original_index_map; - std::vector lepox_to_next; - std::vector solvable_objects; #ifdef DEBUG @@ -410,6 +421,8 @@ 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 = false; + do { ScheduledPlate scheduled_plate; @@ -430,6 +443,7 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver poly_positions_Y, times_T, solvable_objects, + trans_bed_lepox, decided_polygons, remaining_polygons, progress_object_phases_done, @@ -464,9 +478,30 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver } #endif - std::map scheduled_polygons; + bool split = false; for (unsigned int i = 0; i < decided_polygons.size(); ++i) { + if (solvable_objects[i].lepox_to_next && !is_scheduled(i + 1, decided_polygons)) + { + split = true; + } + } + if (split) + { + trans_bed_lepox = true; + #ifdef DEBUG + { + printf("Lopoxed group split, implies trans-bed lepox\n"); + } + #endif + } + else + { + trans_bed_lepox = false; + } + std::map scheduled_polygons; + for (unsigned int i = 0; i < decided_polygons.size(); ++i) + { scheduled_polygons.insert(std::pair(times_T[decided_polygons[i]].as_double(), decided_polygons[i])); } @@ -802,6 +837,8 @@ 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 = false; + do { ScheduledPlate scheduled_plate; @@ -822,6 +859,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_ poly_positions_Y, times_T, solvable_objects, + trans_bed_lepox, decided_polygons, remaining_polygons, progress_object_phases_done, @@ -856,6 +894,27 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_ } #endif + bool split = false; + for (unsigned int i = 0; i < decided_polygons.size(); ++i) + { + if (solvable_objects[i].lepox_to_next && !is_scheduled(i + 1, decided_polygons)) + { + split = true; + } + } + if (split) + { + trans_bed_lepox = true; + #ifdef DEBUG + { + printf("Lopoxed group split, implies trans-bed lepox\n"); + } + #endif + } + else + { + trans_bed_lepox = false; + } std::map scheduled_polygons; for (unsigned int i = 0; i < decided_polygons.size(); ++i) { @@ -1115,6 +1174,8 @@ 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 = false; + do { ScheduledPlate scheduled_plate; @@ -1135,6 +1196,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration poly_positions_Y, times_T, solvable_objects, + trans_bed_lepox, decided_polygons, remaining_polygons, progress_object_phases_done, @@ -1170,6 +1232,27 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration } #endif + bool split = false; + for (unsigned int i = 0; i < decided_polygons.size(); ++i) + { + if (solvable_objects[i].lepox_to_next && !is_scheduled(i + 1, decided_polygons)) + { + split = true; + } + } + if (split) + { + trans_bed_lepox = true; + #ifdef DEBUG + { + printf("Lopoxed group split, implies trans-bed lepox\n"); + } + #endif + } + else + { + trans_bed_lepox = false; + } std::map scheduled_polygons; for (unsigned int i = 0; i < decided_polygons.size(); ++i) { diff --git a/src/libseqarrange/src/seq_sequential.cpp b/src/libseqarrange/src/seq_sequential.cpp index 1becaa9c21..54849e19b6 100644 --- a/src/libseqarrange/src/seq_sequential.cpp +++ b/src/libseqarrange/src/seq_sequential.cpp @@ -377,6 +377,44 @@ void introduce_ConsequentialTemporalOrderingAgainstFixed(z3::solver } +bool is_undecided(int i, const std::vector &undecided) +{ + for (unsigned int j = 0; j < undecided.size(); ++j) + { + if (undecided[j] == i) + { + return true; + } + } + return false; +} + + +bool is_fixed(int i, const std::vector &fixed) +{ + for (unsigned int j = 0; j < fixed.size(); ++j) + { + if (fixed[j] == i) + { + return true; + } + } + return false; +} + + +bool is_targeted_by_undecided(int i, const std::vector &fixed, const std::vector &lepox_to_next) +{ + return (i > 0 && lepox_to_next[i - 1] && is_undecided(i - 1, fixed)); +} + + +bool is_targeted_by_fixed(int i, const std::vector &fixed, const std::vector &lepox_to_next) +{ + return (i > 0 && lepox_to_next[i - 1] && is_fixed(i - 1, fixed)); +} + + void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver &Solver, z3::context &Context, const z3::expr_vector &dec_vars_T, @@ -385,48 +423,147 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver const std::vector &undecided, int temporal_spread, const std::vector &SEQ_UNUSED(polygons), - const std::vector &lepox_to_next) + const std::vector &lepox_to_next, + bool trans_bed_lepox) { - for (unsigned int i = 0; i < undecided.size(); ++i) + #ifdef DEBUG { - if (i == 0) + if (trans_bed_lepox) { - if ((undecided[0] - 1) >= 0) + printf("Trans bed lepox.\n"); + } + printf("Undecided:\n"); + for (unsigned int i = 0; i < undecided.size(); ++i) + { + printf("%d", undecided[i]); + if (lepox_to_next[undecided[i]]) { - if (lepox_to_next[undecided[0] - 1]) - { - for (unsigned int j = 1; j < undecided.size(); ++j) - { - Solver.add(dec_vars_T[undecided[0]] + temporal_spread < dec_vars_T[undecided[j]]); - } - if (!fixed.empty()) - { - int prev_fix_i = fixed[fixed.size() - 1]; - Solver.add(Context.real_val(dec_values_T[prev_fix_i].numerator, dec_values_T[prev_fix_i].denominator) + temporal_spread < dec_vars_T[undecided[0]]); - } - } + printf("-> "); + } + printf(" "); + } + printf("\n"); + + printf("Fixed:\n"); + for (unsigned int i = 0; i < fixed.size(); ++i) + { + printf("%d", fixed[i]); + if (lepox_to_next[fixed[i]]) + { + printf("-> "); + } + printf(" "); + } + printf("\n"); + } + #endif + + /* Bed --> Bed */ + if (trans_bed_lepox) + { + if (is_undecided(0, undecided)) + { + #ifdef DEBUG + { + printf("Bed --> Bed: undecided 0 first\n"); + } + #endif + for (unsigned int j = 1; j < undecided.size(); ++j) + { + Solver.add(dec_vars_T[0] + temporal_spread < dec_vars_T[undecided[j]]); } } + else if (is_fixed(0, fixed)) + { + #ifdef DEBUG + { + printf("Bed --> Bed: fixed 0 still first\n"); + } + #endif + for (unsigned int j = 0; j < undecided.size(); ++j) + { + Solver.add(Context.real_val(dec_values_T[0].numerator, dec_values_T[0].denominator) + temporal_spread < dec_vars_T[undecided[j]]); + } + } + else + { + // should not happen + assert(false); + } + } + + for (unsigned int i = 0; i < undecided.size(); ++i) + { if (lepox_to_next[undecided[i]]) { - if (undecided.size() > i + 1) + int next_i = undecided[i] + 1; + + /* Undecided --> Undecided */ + if (is_undecided(next_i, undecided)) { - int next_i = undecided[i + 1]; + #ifdef DEBUG + { + printf("Undecided --> Undecided: %d --> %d standard\n", undecided[i], next_i); + } + #endif Solver.add(dec_vars_T[undecided[i]] + temporal_spread < dec_vars_T[next_i] && dec_vars_T[undecided[i]] + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]); } + /* Undecided --> missing */ else { - if (!undecided.empty()) + #ifdef DEBUG { - for (unsigned int j = 0; j < undecided.size() - 1; ++j) + printf("Undecided --> Undecided: %d missing\n", undecided[i]); + } + #endif + for (unsigned int j = 0; j < undecided.size(); ++j) + { + if (i != j) { Solver.add(dec_vars_T[undecided[j]] + temporal_spread < dec_vars_T[undecided[i]]); } } + for (unsigned int j = 0; j < fixed.size(); ++j) + { + Solver.add(Context.real_val(dec_values_T[fixed[j]].numerator, dec_values_T[fixed[j]].denominator) + temporal_spread < dec_vars_T[undecided[i]]); + } } } } + for (unsigned int i = 0; i < fixed.size(); ++i) + { + if (lepox_to_next[fixed[i]]) + { + int next_i = fixed[i] + 1; + /* Fixed --> Undecided */ + if (is_undecided(next_i, undecided)) + { + #ifdef DEBUG + { + printf("Fixed --> Undecided: %d --> %d standard\n", fixed[i], next_i); + } + #endif + Solver.add( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread < dec_vars_T[next_i] + && Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]); + } + /* Fixed --> Fixed */ + else if (is_fixed(next_i, fixed)) + { + #ifdef DEBUG + { + printf("All out of the link: %d --> %d\n", fixed[i], next_i); + } + #endif + for (unsigned int j = 0; j < undecided.size(); ++j) + { + Solver.add( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) > dec_vars_T[undecided[j]] + temporal_spread + || Context.real_val(dec_values_T[next_i].numerator, dec_values_T[next_i].denominator) < dec_vars_T[undecided[j]] + temporal_spread); + } + } + } + } + #ifdef DEBUG { printf("Origo\n"); @@ -10902,6 +11039,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So const std::vector &polygons, const std::vector &unreachable_polygons, const std::vector &lepox_to_next, + bool trans_bed_lepox, const std::vector &undecided_polygons, std::vector &decided_polygons, std::vector &remaining_polygons, @@ -10924,6 +11062,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So polygons, _unreachable_polygons, lepox_to_next, + trans_bed_lepox, undecided_polygons, decided_polygons, remaining_polygons, @@ -10940,6 +11079,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So const std::vector &polygons, const std::vector > &unreachable_polygons, const std::vector &lepox_to_next, + bool trans_bed_lepox, const std::vector &undecided_polygons, std::vector &decided_polygons, std::vector &remaining_polygons, @@ -11039,7 +11179,8 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So undecided, solver_configuration.temporal_spread, polygons, - lepox_to_next); + lepox_to_next, + trans_bed_lepox); std::vector missing; std::vector remaining_local; @@ -11195,16 +11336,17 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So } -bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const SolverConfiguration &solver_configuration, - std::vector &dec_values_X, - std::vector &dec_values_Y, - std::vector &dec_values_T, - const std::vector &solvable_objects, - std::vector &decided_polygons, - std::vector &remaining_polygons, - int &progress_object_phases_done, - int progress_total_object_phases, - std::function progress_callback) +bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const SolverConfiguration &solver_configuration, + std::vector &dec_values_X, + std::vector &dec_values_Y, + std::vector &dec_values_T, + const std::vector &solvable_objects, + bool trans_bed_lepox, + std::vector &decided_polygons, + std::vector &remaining_polygons, + int &progress_object_phases_done, + int progress_total_object_phases, + std::function progress_callback) { std::vector undecided; @@ -11333,7 +11475,8 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So undecided, solver_configuration.temporal_spread, polygons, - lepox_to_next); + lepox_to_next, + trans_bed_lepox); std::vector missing; std::vector remaining_local; diff --git a/src/libseqarrange/src/seq_sequential.hpp b/src/libseqarrange/src/seq_sequential.hpp index 7f1701594b..f9ec99fb14 100644 --- a/src/libseqarrange/src/seq_sequential.hpp +++ b/src/libseqarrange/src/seq_sequential.hpp @@ -344,7 +344,8 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver const std::vector &undecided, int temporal_spread, const std::vector &SEQ_UNUSED(polygons), - const std::vector &lepox_to_next); + const std::vector &lepox_to_next, + bool trans_bed_lepox); /*----------------------------------------------------------------*/ @@ -1642,6 +1643,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So const std::vector &polygons, const std::vector &unreachable_polygons, const std::vector &lepox_to_next, + bool trans_bed_lepox, const std::vector &undecided_polygons, std::vector &decided_polygons, std::vector &remaining_polygons, @@ -1656,6 +1658,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So const std::vector &polygons, const std::vector > &unreachable_polygons, const std::vector &lepox_to_next, + bool trans_bed_lepox, const std::vector &undecided_polygons, std::vector &decided_polygons, std::vector &remaining_polygons, @@ -1668,6 +1671,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So std::vector &dec_values_Y, std::vector &dec_values_T, const std::vector &solvable_objects, + bool trans_bed_lepox, std::vector &decided_polygons, std::vector &remaining_polygons, int &progress_object_phases_done, diff --git a/src/libseqarrange/src/sequential_prusa.cpp b/src/libseqarrange/src/sequential_prusa.cpp index 5c311baec8..365af39339 100644 --- a/src/libseqarrange/src/sequential_prusa.cpp +++ b/src/libseqarrange/src/sequential_prusa.cpp @@ -185,6 +185,19 @@ string convert_Index2Suffix(int index) } +bool is_scheduled(int i, const std::vector &decided_polygons) +{ + for (unsigned int j = 0; j < decided_polygons.size(); ++j) + { + if (decided_polygons[j] == i) + { + return true; + } + } + return false; +} + + int solve_SequentialPrint(const CommandParameters &command_parameters) { clock_t start, finish; @@ -383,7 +396,9 @@ int solve_SequentialPrint(const CommandParameters &command_parameters) int plate_index = 0; int progress_objects_done = 0; - int progress_objects_total = objects_to_print.size(); + int progress_objects_total = objects_to_print.size(); + + bool trans_bed_lepox = false; do { @@ -402,6 +417,7 @@ int solve_SequentialPrint(const CommandParameters &command_parameters) polygons, unreachable_polygons, lepox_to_next, + trans_bed_lepox, polygon_index_map, decided_polygons, remaining_polygons, @@ -443,6 +459,23 @@ int solve_SequentialPrint(const CommandParameters &command_parameters) printf(" ID:%d\n", original_index_map[remaining_polygons[i]]); } + bool split = false; + for (unsigned int i = 0; i < decided_polygons.size(); ++i) + { + if (lepox_to_next[i] && !is_scheduled(i + 1, decided_polygons)) + { + split = true; + } + } + if (split) + { + trans_bed_lepox = true; + printf("Lopoxed group split, potential danger!!!\n"); + } + else + { + trans_bed_lepox = false; + } std::map scheduled_polygons; for (unsigned int i = 0; i < decided_polygons.size(); ++i) {