Revisited scheduling of object instances via object gluing, added object gluing across multple beds.

This commit is contained in:
surynek 2025-02-12 13:36:42 +01:00 committed by Lukas Matena
parent 78c6ed2c6b
commit 1259d59098
4 changed files with 301 additions and 38 deletions

View File

@ -332,6 +332,19 @@ std::vector<ScheduledPlate> schedule_ObjectsForSequentialPrint(const SolverConfi
} }
bool is_scheduled(int i, const std::vector<int> &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, void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_configuration,
const PrinterGeometry &printer_geometry, const PrinterGeometry &printer_geometry,
const std::vector<ObjectToPrint> &objects_to_print, const std::vector<ObjectToPrint> &objects_to_print,
@ -350,8 +363,6 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver
#endif #endif
std::map<int, int> original_index_map; std::map<int, int> original_index_map;
std::vector<bool> lepox_to_next;
std::vector<SolvableObject> solvable_objects; std::vector<SolvableObject> solvable_objects;
#ifdef DEBUG #ifdef DEBUG
@ -410,6 +421,8 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver
int progress_object_phases_done = 0; int progress_object_phases_done = 0;
int progress_object_phases_total = SEQ_MAKE_EXTRA_PROGRESS((objects_to_print.size() * SEQ_PROGRESS_PHASES_PER_OBJECT)); int progress_object_phases_total = SEQ_MAKE_EXTRA_PROGRESS((objects_to_print.size() * SEQ_PROGRESS_PHASES_PER_OBJECT));
bool trans_bed_lepox = false;
do do
{ {
ScheduledPlate scheduled_plate; ScheduledPlate scheduled_plate;
@ -430,6 +443,7 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver
poly_positions_Y, poly_positions_Y,
times_T, times_T,
solvable_objects, solvable_objects,
trans_bed_lepox,
decided_polygons, decided_polygons,
remaining_polygons, remaining_polygons,
progress_object_phases_done, progress_object_phases_done,
@ -464,6 +478,27 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver
} }
#endif #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<double, int> scheduled_polygons; std::map<double, int> scheduled_polygons;
for (unsigned int i = 0; i < decided_polygons.size(); ++i) for (unsigned int i = 0; i < decided_polygons.size(); ++i)
{ {
@ -802,6 +837,8 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_
int progress_object_phases_done = 0; int progress_object_phases_done = 0;
int progress_object_phases_total = SEQ_MAKE_EXTRA_PROGRESS((objects_to_print.size() * SEQ_PROGRESS_PHASES_PER_OBJECT)); int progress_object_phases_total = SEQ_MAKE_EXTRA_PROGRESS((objects_to_print.size() * SEQ_PROGRESS_PHASES_PER_OBJECT));
bool trans_bed_lepox = false;
do do
{ {
ScheduledPlate scheduled_plate; ScheduledPlate scheduled_plate;
@ -822,6 +859,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_
poly_positions_Y, poly_positions_Y,
times_T, times_T,
solvable_objects, solvable_objects,
trans_bed_lepox,
decided_polygons, decided_polygons,
remaining_polygons, remaining_polygons,
progress_object_phases_done, progress_object_phases_done,
@ -856,6 +894,27 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_
} }
#endif #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<double, int> scheduled_polygons; std::map<double, int> scheduled_polygons;
for (unsigned int i = 0; i < decided_polygons.size(); ++i) 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_done = 0;
int progress_object_phases_total = SEQ_MAKE_EXTRA_PROGRESS((objects_to_print.size() * SEQ_PROGRESS_PHASES_PER_OBJECT)); int progress_object_phases_total = SEQ_MAKE_EXTRA_PROGRESS((objects_to_print.size() * SEQ_PROGRESS_PHASES_PER_OBJECT));
bool trans_bed_lepox = false;
do do
{ {
ScheduledPlate scheduled_plate; ScheduledPlate scheduled_plate;
@ -1135,6 +1196,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration
poly_positions_Y, poly_positions_Y,
times_T, times_T,
solvable_objects, solvable_objects,
trans_bed_lepox,
decided_polygons, decided_polygons,
remaining_polygons, remaining_polygons,
progress_object_phases_done, progress_object_phases_done,
@ -1170,6 +1232,27 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration
} }
#endif #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<double, int> scheduled_polygons; std::map<double, int> scheduled_polygons;
for (unsigned int i = 0; i < decided_polygons.size(); ++i) for (unsigned int i = 0; i < decided_polygons.size(); ++i)
{ {

View File

@ -377,6 +377,44 @@ void introduce_ConsequentialTemporalOrderingAgainstFixed(z3::solver
} }
bool is_undecided(int i, const std::vector<int> &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<int> &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<int> &fixed, const std::vector<bool> &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<int> &fixed, const std::vector<bool> &lepox_to_next)
{
return (i > 0 && lepox_to_next[i - 1] && is_fixed(i - 1, fixed));
}
void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver &Solver, void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver &Solver,
z3::context &Context, z3::context &Context,
const z3::expr_vector &dec_vars_T, const z3::expr_vector &dec_vars_T,
@ -385,44 +423,143 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver
const std::vector<int> &undecided, const std::vector<int> &undecided,
int temporal_spread, int temporal_spread,
const std::vector<Slic3r::Polygon> &SEQ_UNUSED(polygons), const std::vector<Slic3r::Polygon> &SEQ_UNUSED(polygons),
const std::vector<bool> &lepox_to_next) const std::vector<bool> &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]) printf("-> ");
{ }
for (unsigned int j = 1; j < undecided.size(); ++j) printf(" ");
{ }
Solver.add(dec_vars_T[undecided[0]] + temporal_spread < dec_vars_T[undecided[j]]); printf("\n");
}
if (!fixed.empty()) printf("Fixed:\n");
{ for (unsigned int i = 0; i < fixed.size(); ++i)
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("%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 (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]); 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 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]]); 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);
}
} }
} }
} }
@ -10902,6 +11039,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
const std::vector<Slic3r::Polygon> &polygons, const std::vector<Slic3r::Polygon> &polygons,
const std::vector<Slic3r::Polygon> &unreachable_polygons, const std::vector<Slic3r::Polygon> &unreachable_polygons,
const std::vector<bool> &lepox_to_next, const std::vector<bool> &lepox_to_next,
bool trans_bed_lepox,
const std::vector<int> &undecided_polygons, const std::vector<int> &undecided_polygons,
std::vector<int> &decided_polygons, std::vector<int> &decided_polygons,
std::vector<int> &remaining_polygons, std::vector<int> &remaining_polygons,
@ -10924,6 +11062,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
polygons, polygons,
_unreachable_polygons, _unreachable_polygons,
lepox_to_next, lepox_to_next,
trans_bed_lepox,
undecided_polygons, undecided_polygons,
decided_polygons, decided_polygons,
remaining_polygons, remaining_polygons,
@ -10940,6 +11079,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
const std::vector<Slic3r::Polygon> &polygons, const std::vector<Slic3r::Polygon> &polygons,
const std::vector<std::vector<Slic3r::Polygon> > &unreachable_polygons, const std::vector<std::vector<Slic3r::Polygon> > &unreachable_polygons,
const std::vector<bool> &lepox_to_next, const std::vector<bool> &lepox_to_next,
bool trans_bed_lepox,
const std::vector<int> &undecided_polygons, const std::vector<int> &undecided_polygons,
std::vector<int> &decided_polygons, std::vector<int> &decided_polygons,
std::vector<int> &remaining_polygons, std::vector<int> &remaining_polygons,
@ -11039,7 +11179,8 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
undecided, undecided,
solver_configuration.temporal_spread, solver_configuration.temporal_spread,
polygons, polygons,
lepox_to_next); lepox_to_next,
trans_bed_lepox);
std::vector<int> missing; std::vector<int> missing;
std::vector<int> remaining_local; std::vector<int> remaining_local;
@ -11195,16 +11336,17 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
} }
bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const SolverConfiguration &solver_configuration, bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const SolverConfiguration &solver_configuration,
std::vector<Rational> &dec_values_X, std::vector<Rational> &dec_values_X,
std::vector<Rational> &dec_values_Y, std::vector<Rational> &dec_values_Y,
std::vector<Rational> &dec_values_T, std::vector<Rational> &dec_values_T,
const std::vector<SolvableObject> &solvable_objects, const std::vector<SolvableObject> &solvable_objects,
std::vector<int> &decided_polygons, bool trans_bed_lepox,
std::vector<int> &remaining_polygons, std::vector<int> &decided_polygons,
int &progress_object_phases_done, std::vector<int> &remaining_polygons,
int progress_total_object_phases, int &progress_object_phases_done,
std::function<void(int)> progress_callback) int progress_total_object_phases,
std::function<void(int)> progress_callback)
{ {
std::vector<int> undecided; std::vector<int> undecided;
@ -11333,7 +11475,8 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
undecided, undecided,
solver_configuration.temporal_spread, solver_configuration.temporal_spread,
polygons, polygons,
lepox_to_next); lepox_to_next,
trans_bed_lepox);
std::vector<int> missing; std::vector<int> missing;
std::vector<int> remaining_local; std::vector<int> remaining_local;

View File

@ -344,7 +344,8 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver
const std::vector<int> &undecided, const std::vector<int> &undecided,
int temporal_spread, int temporal_spread,
const std::vector<Slic3r::Polygon> &SEQ_UNUSED(polygons), const std::vector<Slic3r::Polygon> &SEQ_UNUSED(polygons),
const std::vector<bool> &lepox_to_next); const std::vector<bool> &lepox_to_next,
bool trans_bed_lepox);
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
@ -1642,6 +1643,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
const std::vector<Slic3r::Polygon> &polygons, const std::vector<Slic3r::Polygon> &polygons,
const std::vector<Slic3r::Polygon> &unreachable_polygons, const std::vector<Slic3r::Polygon> &unreachable_polygons,
const std::vector<bool> &lepox_to_next, const std::vector<bool> &lepox_to_next,
bool trans_bed_lepox,
const std::vector<int> &undecided_polygons, const std::vector<int> &undecided_polygons,
std::vector<int> &decided_polygons, std::vector<int> &decided_polygons,
std::vector<int> &remaining_polygons, std::vector<int> &remaining_polygons,
@ -1656,6 +1658,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
const std::vector<Slic3r::Polygon> &polygons, const std::vector<Slic3r::Polygon> &polygons,
const std::vector<std::vector<Slic3r::Polygon> > &unreachable_polygons, const std::vector<std::vector<Slic3r::Polygon> > &unreachable_polygons,
const std::vector<bool> &lepox_to_next, const std::vector<bool> &lepox_to_next,
bool trans_bed_lepox,
const std::vector<int> &undecided_polygons, const std::vector<int> &undecided_polygons,
std::vector<int> &decided_polygons, std::vector<int> &decided_polygons,
std::vector<int> &remaining_polygons, std::vector<int> &remaining_polygons,
@ -1668,6 +1671,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
std::vector<Rational> &dec_values_Y, std::vector<Rational> &dec_values_Y,
std::vector<Rational> &dec_values_T, std::vector<Rational> &dec_values_T,
const std::vector<SolvableObject> &solvable_objects, const std::vector<SolvableObject> &solvable_objects,
bool trans_bed_lepox,
std::vector<int> &decided_polygons, std::vector<int> &decided_polygons,
std::vector<int> &remaining_polygons, std::vector<int> &remaining_polygons,
int &progress_object_phases_done, int &progress_object_phases_done,

View File

@ -185,6 +185,19 @@ string convert_Index2Suffix(int index)
} }
bool is_scheduled(int i, const std::vector<int> &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) int solve_SequentialPrint(const CommandParameters &command_parameters)
{ {
clock_t start, finish; clock_t start, finish;
@ -385,6 +398,8 @@ int solve_SequentialPrint(const CommandParameters &command_parameters)
int progress_objects_done = 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 do
{ {
decided_polygons.clear(); decided_polygons.clear();
@ -402,6 +417,7 @@ int solve_SequentialPrint(const CommandParameters &command_parameters)
polygons, polygons,
unreachable_polygons, unreachable_polygons,
lepox_to_next, lepox_to_next,
trans_bed_lepox,
polygon_index_map, polygon_index_map,
decided_polygons, decided_polygons,
remaining_polygons, remaining_polygons,
@ -443,6 +459,23 @@ int solve_SequentialPrint(const CommandParameters &command_parameters)
printf(" ID:%d\n", original_index_map[remaining_polygons[i]]); 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<double, int> scheduled_polygons; std::map<double, int> scheduled_polygons;
for (unsigned int i = 0; i < decided_polygons.size(); ++i) for (unsigned int i = 0; i < decided_polygons.size(); ++i)
{ {