From e75ff22438409820ef4c2a6085852dc41a6dd3e3 Mon Sep 17 00:00:00 2001 From: surynek Date: Tue, 22 Oct 2024 00:36:58 +0200 Subject: [PATCH] Scheduling solving process speed improvement and bug fix. --- .../include/libseqarrange/seq_interface.hpp | 1 + src/libseqarrange/src/seq_interface.cpp | 52 ++---- src/libseqarrange/src/seq_preprocess.cpp | 29 ++++ src/libseqarrange/src/seq_preprocess.hpp | 2 + src/libseqarrange/src/seq_sequential.cpp | 153 +++++++++--------- src/libseqarrange/src/seq_sequential.hpp | 1 - 6 files changed, 116 insertions(+), 122 deletions(-) diff --git a/src/libseqarrange/include/libseqarrange/seq_interface.hpp b/src/libseqarrange/include/libseqarrange/seq_interface.hpp index 3d62409b66..cea7d80d07 100644 --- a/src/libseqarrange/include/libseqarrange/seq_interface.hpp +++ b/src/libseqarrange/include/libseqarrange/seq_interface.hpp @@ -75,6 +75,7 @@ struct SolverConfiguration int minimum_bounding_box_size; int x_plate_bounding_box_size; int y_plate_bounding_box_size; + int max_refines; int object_group_size; int temporal_spread; diff --git a/src/libseqarrange/src/seq_interface.cpp b/src/libseqarrange/src/seq_interface.cpp index 8460b414a0..0379fb060c 100644 --- a/src/libseqarrange/src/seq_interface.cpp +++ b/src/libseqarrange/src/seq_interface.cpp @@ -32,6 +32,8 @@ const int SEQ_SCHEDULING_TEMPORAL_SPREAD = 16; const int SEQ_BOUNDING_BOX_SIZE_OPTIMIZATION_STEP = 4; const int SEQ_MINIMUM_BOUNDING_BOX_SIZE = 16; +const int SEQ_MAX_REFINES = 2; + /*----------------------------------------------------------------*/ @@ -91,7 +93,8 @@ SolverConfiguration::SolverConfiguration() : bounding_box_size_optimization_step(SEQ_BOUNDING_BOX_SIZE_OPTIMIZATION_STEP) , minimum_bounding_box_size(SEQ_MINIMUM_BOUNDING_BOX_SIZE) , x_plate_bounding_box_size(SEQ_PRUSA_MK3S_X_SIZE) - , y_plate_bounding_box_size(SEQ_PRUSA_MK3S_Y_SIZE) + , y_plate_bounding_box_size(SEQ_PRUSA_MK3S_Y_SIZE) + , max_refines(SEQ_MAX_REFINES) , object_group_size(SEQ_OBJECT_GROUP_SIZE) , temporal_spread(SEQ_SCHEDULING_TEMPORAL_SPREAD) , decimation_precision(SEQ_DECIMATION_PRECISION_LOW) @@ -104,6 +107,7 @@ SolverConfiguration::SolverConfiguration() SolverConfiguration::SolverConfiguration(const PrinterGeometry &printer_geometry) : bounding_box_size_optimization_step(SEQ_BOUNDING_BOX_SIZE_OPTIMIZATION_STEP) , minimum_bounding_box_size(SEQ_MINIMUM_BOUNDING_BOX_SIZE) + , max_refines(SEQ_MAX_REFINES) , object_group_size(SEQ_OBJECT_GROUP_SIZE) , temporal_spread(SEQ_SCHEDULING_TEMPORAL_SPREAD) , decimation_precision(SEQ_DECIMATION_PRECISION_LOW) @@ -314,9 +318,6 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver } #endif - std::vector polygons; - std::vector > unreachable_polygons; - std::map original_index_map; std::vector lepox_to_next; @@ -363,14 +364,8 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver } std::vector remaining_polygons; - std::vector polygon_index_map; std::vector decided_polygons; - for (unsigned int index = 0; index < polygons.size(); ++index) - { - polygon_index_map.push_back(index); - } - std::vector poly_positions_X; std::vector poly_positions_Y; std::vector times_T; @@ -404,7 +399,6 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver poly_positions_Y, times_T, solvable_objects, - polygon_index_map, decided_polygons, remaining_polygons, progress_objects_done, @@ -487,18 +481,14 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver { next_solvable_objects.push_back(solvable_objects[remaining_polygons[i]]); } - polygon_index_map.clear(); solvable_objects = next_solvable_objects; - std::vector next_polygon_index_map; std::map next_original_index_map; - for (unsigned int index = 0; index < polygons.size(); ++index) + for (unsigned int index = 0; index < solvable_objects.size(); ++index) { - next_polygon_index_map.push_back(index); next_original_index_map[index] = original_index_map[remaining_polygons[index]]; } - polygon_index_map = next_polygon_index_map; original_index_map = next_original_index_map; scheduled_plates.push_back(scheduled_plate); @@ -545,12 +535,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_ PrinterType printer_type = SEQ_PRINTER_TYPE_PRUSA_MK3S; - std::vector polygons; - std::vector > unreachable_polygons; - std::vector lepox_to_next; - std::vector solvable_objects; - std::map original_index_map; #ifdef DEBUG @@ -763,13 +748,14 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_ } std::vector remaining_polygons; - std::vector polygon_index_map; std::vector decided_polygons; - for (unsigned int index = 0; index < polygons.size(); ++index) + /* + for (unsigned int index = 0; index < solvable_objects.size(); ++index) { polygon_index_map.push_back(index); } + */ std::vector poly_positions_X; std::vector poly_positions_Y; @@ -804,7 +790,6 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_ poly_positions_Y, times_T, solvable_objects, - polygon_index_map, decided_polygons, remaining_polygons, progress_objects_done, @@ -886,18 +871,13 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_ { next_solvable_objects.push_back(solvable_objects[i]); } - polygon_index_map.clear(); solvable_objects = next_solvable_objects; - - std::vector next_polygon_index_map; std::map next_original_index_map; - for (unsigned int index = 0; index < polygons.size(); ++index) + for (unsigned int index = 0; index < solvable_objects.size(); ++index) { - next_polygon_index_map.push_back(index); next_original_index_map[index] = original_index_map[remaining_polygons[index]]; } - polygon_index_map = next_polygon_index_map; original_index_map = next_original_index_map; scheduled_plates.push_back(scheduled_plate); @@ -1087,13 +1067,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration } std::vector remaining_polygons; - std::vector polygon_index_map; std::vector decided_polygons; - - for (unsigned int index = 0; index < solvable_objects.size(); ++index) - { - polygon_index_map.push_back(index); - } std::vector poly_positions_X; std::vector poly_positions_Y; @@ -1128,7 +1102,6 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration poly_positions_Y, times_T, solvable_objects, - polygon_index_map, decided_polygons, remaining_polygons, progress_objects_done, @@ -1211,18 +1184,13 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration { next_solvable_objects.push_back(solvable_objects[i]); } - polygon_index_map.clear(); solvable_objects = next_solvable_objects; - - std::vector next_polygon_index_map; std::map next_original_index_map; for (unsigned int index = 0; index < solvable_objects.size(); ++index) { - next_polygon_index_map.push_back(index); next_original_index_map[index] = original_index_map[remaining_polygons[index]]; } - polygon_index_map = next_polygon_index_map; original_index_map = next_original_index_map; scheduled_plates.push_back(scheduled_plate); diff --git a/src/libseqarrange/src/seq_preprocess.cpp b/src/libseqarrange/src/seq_preprocess.cpp index 25f78eb30d..60e4449c9f 100644 --- a/src/libseqarrange/src/seq_preprocess.cpp +++ b/src/libseqarrange/src/seq_preprocess.cpp @@ -889,6 +889,35 @@ bool check_PolygonSize(const SolverConfiguration &solver_configuration, coord_t } +void glue_LowObjects(std::vector &solvable_objects) +{ + int low = 0; + + for (unsigned int i = 0; i < solvable_objects.size(); ++i) + { + double polygon_area = calc_PolygonArea(solvable_objects[i].polygon); + double unreachable_area = calc_PolygonUnreachableZoneArea(solvable_objects[i].polygon, solvable_objects[i].unreachable_polygons); + + if (2 * polygon_area > unreachable_area) + { + printf("Low: %d\n", solvable_objects[i].id); + if (++low >= 2) + { + assert(i > 0); + printf("---> gluing: %d -> %d\n", solvable_objects[i-1].id, solvable_objects[i].id); + solvable_objects[i-1].lepox_to_next = true; + low = 1; + } + } + else + { + printf("noLow: %d\n", solvable_objects[i].id); + low = 0; + } + } +} + + /*----------------------------------------------------------------*/ double calc_PolygonArea(const Slic3r::Polygon &polygon) diff --git a/src/libseqarrange/src/seq_preprocess.hpp b/src/libseqarrange/src/seq_preprocess.hpp index 2436bc40a1..e4791d9047 100644 --- a/src/libseqarrange/src/seq_preprocess.hpp +++ b/src/libseqarrange/src/seq_preprocess.hpp @@ -199,6 +199,8 @@ bool check_PolygonSize(const SolverConfiguration &solver_configuration, coord_t void simplify_ConvexUnreachablePolygons(const std::vector > &unreachable_convex_polygons, std::vector &simplified_unreachable_polygons); +void glue_LowObjects(std::vector &solvable_ojects); + /*----------------------------------------------------------------*/ diff --git a/src/libseqarrange/src/seq_sequential.cpp b/src/libseqarrange/src/seq_sequential.cpp index 557f6cbb54..815f520d18 100644 --- a/src/libseqarrange/src/seq_sequential.cpp +++ b/src/libseqarrange/src/seq_sequential.cpp @@ -365,7 +365,6 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver } if (lepox_to_next[undecided[i]]) { - printf("Lepox constraint present: %d\n", undecided[i]); if (undecided.size() > i + 1) { int next_i = undecided[i + 1]; @@ -7915,7 +7914,6 @@ bool optimize_SequentialWeakPolygonNonoverlappingCentered(z3::solver const std::vector > &unreachable_polygons) { z3::set_param("timeout", solver_configuration.optimization_timeout.c_str()); - //z3::set_param("parallel.enable", "true"); int last_solvable_bounding_box_size = -1; @@ -8280,8 +8278,7 @@ bool optimize_SequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver const std::vector > &unreachable_polygons) { z3::set_param("timeout", solver_configuration.optimization_timeout.c_str()); - //z3::set_param("parallel.enable", "true"); - + coord_t last_solvable_bounding_box_size = -1; std::vector local_dec_values_X = dec_values_X; @@ -8620,7 +8617,6 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver std::function progress_callback) { z3::set_param("timeout", solver_configuration.optimization_timeout.c_str()); - //z3::set_param("parallel.enable", "true"); coord_t last_solvable_bounding_box_size = -1; @@ -8640,7 +8636,7 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver while ((half_x_max - half_x_min) > 1 && (half_y_max - half_y_min) > 1) { #ifdef DEBUG - { + { printf("Halves: %d, %d, %d, %d\n", half_x_min, half_x_max, half_y_min, half_y_max); } #endif @@ -8752,6 +8748,8 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver local_dec_values_Y, local_dec_values_T); + int total_refines = 0; + while (true) { #ifdef PROFILE @@ -8777,79 +8775,83 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver refine_cumul += (refine_finish - refine_start) / (double)CLOCKS_PER_SEC; } #endif - + if (refined) { + ++total_refines; + bool refined_sat = false; - #ifdef DEBUG + if (total_refines < solver_configuration.max_refines) { - printf("Solving 12 ...\n"); - } - #endif + #ifdef DEBUG + { + printf("------> ... Solving 12 ... <------\n"); + } + #endif - if (checkArea_SequentialWeakPolygonNonoverlapping(box_min_x, - box_min_y, - box_max_x, - box_max_y, - fixed, - undecided, - polygons, - unreachable_polygons)) - { - #ifdef PROFILE - { - recheck_start = clock(); - } - #endif - - switch (Solver.check(complete_assumptions)) - { - case z3::sat: + if (checkArea_SequentialWeakPolygonNonoverlapping(box_min_x, + box_min_y, + box_max_x, + box_max_y, + fixed, + undecided, + polygons, + unreachable_polygons)) { #ifdef PROFILE { - recheck_finish = clock(); - recheck_SAT_cumul += (recheck_finish - recheck_start) / (double)CLOCKS_PER_SEC; + recheck_start = clock(); } #endif - refined_sat = true; - break; - } - case z3::unsat: - { - #ifdef PROFILE - { - recheck_finish = clock(); - recheck_UNSAT_cumul += (recheck_finish - recheck_start) / (double)CLOCKS_PER_SEC; - } - #endif - refined_sat = false; - break; - } - case z3::unknown: - { - #ifdef PROFILE + switch (Solver.check(complete_assumptions)) { - recheck_finish = clock(); - recheck_INDET_cumul += (recheck_finish - recheck_start) / (double)CLOCKS_PER_SEC; + case z3::sat: + { + #ifdef PROFILE + { + recheck_finish = clock(); + recheck_SAT_cumul += (recheck_finish - recheck_start) / (double)CLOCKS_PER_SEC; + } + #endif + + refined_sat = true; + break; } - #endif + case z3::unsat: + { + #ifdef PROFILE + { + recheck_finish = clock(); + recheck_UNSAT_cumul += (recheck_finish - recheck_start) / (double)CLOCKS_PER_SEC; + } + #endif + refined_sat = false; + break; + } + case z3::unknown: + { + #ifdef PROFILE + { + recheck_finish = clock(); + recheck_INDET_cumul += (recheck_finish - recheck_start) / (double)CLOCKS_PER_SEC; + } + #endif + refined_sat = false; + break; + } + default: + { + break; + } + } + } + else + { refined_sat = false; - break; - } - default: - { - break; - } } } - else - { - refined_sat = false; - } - #ifdef DEBUG { printf("Solving 12 ... finished: %d\n", refined_sat); @@ -8860,6 +8862,7 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver printf("Printing solver status:\n"); cout << Solver << "\n"; */ + progress_callback(progress_range.progress_min + (progress_range.progress_max - progress_range.progress_min) * progress / progress_total_estimation); if (refined_sat) { @@ -8933,14 +8936,7 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver } #endif - if (last_solvable_bounding_box_size > 0) - { - size_solvable = false; - } - else - { - size_solvable = false; - } + size_solvable = false; } coord_t half_x_med = (half_x_max + half_x_min) / 2; @@ -8954,14 +8950,14 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver } #endif half_x_min = half_x_med; - half_y_min = half_y_med; + half_y_min = half_y_med; } else { #ifdef DEBUG { printf("Unsolvable\n"); - } + } #endif half_x_max = half_x_med; half_y_max = half_y_med; @@ -8994,7 +8990,7 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver #endif return true; - } + } return false; } @@ -10291,7 +10287,6 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So std::vector &dec_values_Y, std::vector &dec_values_T, const std::vector &solvable_objects, - const std::vector &undecided_polygons, std::vector &decided_polygons, std::vector &remaining_polygons, int progress_objects_done, @@ -10429,12 +10424,12 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So printf(" %d\n", undecided[j]); } printf("Decided\n"); - for (unsigned int j = 0; j < decided_solvable_objects.size(); ++j) + for (unsigned int j = 0; j < decided_polygons.size(); ++j) { printf(" %d\n", decided_polygons[j]); } printf("Locals\n"); - for (unsigned int j = 0; j < solvable_objects.size(); ++j) + for (unsigned int j = 0; j < decided_polygons.size(); ++j) { printf("X: %ld,%ld Y: %ld,%ld T: %ld,%ld\n", local_values_X[j].numerator, @@ -10524,7 +10519,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So printf("Remaining polygon: %d\n", curr_polygon + object_group_size - 1); } #endif - remaining_local.push_back(undecided_polygons[curr_polygon + object_group_size - 1]); + remaining_local.push_back(undecided.back()); } missing.push_back(undecided.back()); undecided.pop_back(); @@ -10545,7 +10540,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So if (!optimized) { if (curr_polygon <= 0) - { + { return false; } else @@ -10556,7 +10551,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So for (; curr_polygon < solvable_objects.size(); ++curr_polygon) { - remaining_polygons.push_back(undecided_polygons[curr_polygon]); + remaining_polygons.push_back(curr_polygon); } } return true; diff --git a/src/libseqarrange/src/seq_sequential.hpp b/src/libseqarrange/src/seq_sequential.hpp index b7dfae9c86..3386f6d2f1 100644 --- a/src/libseqarrange/src/seq_sequential.hpp +++ b/src/libseqarrange/src/seq_sequential.hpp @@ -1603,7 +1603,6 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So std::vector &dec_values_Y, std::vector &dec_values_T, const std::vector &solvable_objects, - const std::vector &undecided_polygons, std::vector &decided_polygons, std::vector &remaining_polygons, int progress_objects_done,