mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 18:55:54 +08:00
Implementation of object gluing into the sequential solver and more fine grained progress callback.
This commit is contained in:
parent
967a0710d3
commit
e627aeb685
@ -320,6 +320,8 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver
|
|||||||
std::map<int, int> original_index_map;
|
std::map<int, int> original_index_map;
|
||||||
std::vector<bool> lepox_to_next;
|
std::vector<bool> lepox_to_next;
|
||||||
|
|
||||||
|
std::vector<SolvableObject> solvable_objects;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
printf(" Preparing objects ...\n");
|
printf(" Preparing objects ...\n");
|
||||||
@ -334,12 +336,9 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver
|
|||||||
std::vector<std::vector<Slic3r::Polygon> > extruder_convex_level_polygons;
|
std::vector<std::vector<Slic3r::Polygon> > extruder_convex_level_polygons;
|
||||||
std::vector<std::vector<Slic3r::Polygon> > extruder_box_level_polygons;
|
std::vector<std::vector<Slic3r::Polygon> > extruder_box_level_polygons;
|
||||||
|
|
||||||
std::vector<Slic3r::Polygon> scale_down_unreachable_polygons;
|
SolvableObject solvable_object;
|
||||||
|
|
||||||
original_index_map[i] = objects_to_print[i].id;
|
original_index_map[i] = objects_to_print[i].id;
|
||||||
|
|
||||||
Polygon scale_down_object_polygon;
|
|
||||||
|
|
||||||
prepare_ExtruderPolygons(solver_configuration,
|
prepare_ExtruderPolygons(solver_configuration,
|
||||||
printer_geometry,
|
printer_geometry,
|
||||||
objects_to_print[i],
|
objects_to_print[i],
|
||||||
@ -354,13 +353,13 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver
|
|||||||
box_level_polygons,
|
box_level_polygons,
|
||||||
extruder_convex_level_polygons,
|
extruder_convex_level_polygons,
|
||||||
extruder_box_level_polygons,
|
extruder_box_level_polygons,
|
||||||
scale_down_object_polygon,
|
solvable_object.polygon,
|
||||||
scale_down_unreachable_polygons);
|
solvable_object.unreachable_polygons);
|
||||||
|
|
||||||
unreachable_polygons.push_back(scale_down_unreachable_polygons);
|
solvable_object.id = objects_to_print[i].id;
|
||||||
polygons.push_back(scale_down_object_polygon);
|
solvable_object.lepox_to_next = objects_to_print[i].glued_to_next;
|
||||||
|
|
||||||
lepox_to_next.push_back(objects_to_print[i].glued_to_next);
|
solvable_objects.push_back(solvable_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> remaining_polygons;
|
std::vector<int> remaining_polygons;
|
||||||
@ -404,9 +403,7 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver
|
|||||||
poly_positions_X,
|
poly_positions_X,
|
||||||
poly_positions_Y,
|
poly_positions_Y,
|
||||||
times_T,
|
times_T,
|
||||||
polygons,
|
solvable_objects,
|
||||||
unreachable_polygons,
|
|
||||||
lepox_to_next,
|
|
||||||
polygon_index_map,
|
polygon_index_map,
|
||||||
decided_polygons,
|
decided_polygons,
|
||||||
remaining_polygons,
|
remaining_polygons,
|
||||||
@ -484,27 +481,14 @@ void schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::vector<Polygon> next_polygons;
|
std::vector<SolvableObject> next_solvable_objects;
|
||||||
std::vector<vector<Polygon> > next_unreachable_polygons;
|
|
||||||
std::vector<bool> next_lepox_to_next;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < remaining_polygons.size(); ++i)
|
for (unsigned int i = 0; i < remaining_polygons.size(); ++i)
|
||||||
{
|
{
|
||||||
next_polygons.push_back(polygons[remaining_polygons[i]]);
|
next_solvable_objects.push_back(solvable_objects[remaining_polygons[i]]);
|
||||||
next_unreachable_polygons.push_back(unreachable_polygons[remaining_polygons[i]]);
|
|
||||||
next_lepox_to_next.push_back(lepox_to_next[remaining_polygons[i]]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: remove */
|
|
||||||
polygons.clear();
|
|
||||||
unreachable_polygons.clear();
|
|
||||||
lepox_to_next.clear();
|
|
||||||
|
|
||||||
polygon_index_map.clear();
|
polygon_index_map.clear();
|
||||||
|
solvable_objects = next_solvable_objects;
|
||||||
polygons = next_polygons;
|
|
||||||
unreachable_polygons = next_unreachable_polygons;
|
|
||||||
lepox_to_next = next_lepox_to_next;
|
|
||||||
|
|
||||||
std::vector<int> next_polygon_index_map;
|
std::vector<int> next_polygon_index_map;
|
||||||
std::map<int, int> next_original_index_map;
|
std::map<int, int> next_original_index_map;
|
||||||
@ -565,6 +549,8 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_
|
|||||||
std::vector<std::vector<Slic3r::Polygon> > unreachable_polygons;
|
std::vector<std::vector<Slic3r::Polygon> > unreachable_polygons;
|
||||||
std::vector<bool> lepox_to_next;
|
std::vector<bool> lepox_to_next;
|
||||||
|
|
||||||
|
std::vector<SolvableObject> solvable_objects;
|
||||||
|
|
||||||
std::map<int, int> original_index_map;
|
std::map<int, int> original_index_map;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -718,10 +704,9 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SolvableObject solvable_object;
|
||||||
|
|
||||||
Polygon scale_down_polygon;
|
scaleDown_PolygonForSequentialSolver(nozzle_polygon, solvable_object.polygon);
|
||||||
scaleDown_PolygonForSequentialSolver(nozzle_polygon, scale_down_polygon);
|
|
||||||
polygons.push_back(scale_down_polygon);
|
|
||||||
|
|
||||||
std::vector<Slic3r::Polygon> convex_level_polygons;
|
std::vector<Slic3r::Polygon> convex_level_polygons;
|
||||||
convex_level_polygons.push_back(nozzle_polygon);
|
convex_level_polygons.push_back(nozzle_polygon);
|
||||||
@ -737,31 +722,31 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_
|
|||||||
case SEQ_PRINTER_TYPE_PRUSA_MK3S:
|
case SEQ_PRINTER_TYPE_PRUSA_MK3S:
|
||||||
{
|
{
|
||||||
prepare_UnreachableZonePolygons(solver_configuration,
|
prepare_UnreachableZonePolygons(solver_configuration,
|
||||||
convex_level_polygons,
|
convex_level_polygons,
|
||||||
box_level_polygons,
|
box_level_polygons,
|
||||||
SEQ_UNREACHABLE_POLYGON_CONVEX_LEVELS_MK3S,
|
SEQ_UNREACHABLE_POLYGON_CONVEX_LEVELS_MK3S,
|
||||||
SEQ_UNREACHABLE_POLYGON_BOX_LEVELS_MK3S,
|
SEQ_UNREACHABLE_POLYGON_BOX_LEVELS_MK3S,
|
||||||
scale_down_unreachable_polygons);
|
solvable_object.unreachable_polygons);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SEQ_PRINTER_TYPE_PRUSA_MK4:
|
case SEQ_PRINTER_TYPE_PRUSA_MK4:
|
||||||
{
|
{
|
||||||
prepare_UnreachableZonePolygons(solver_configuration,
|
prepare_UnreachableZonePolygons(solver_configuration,
|
||||||
convex_level_polygons,
|
convex_level_polygons,
|
||||||
box_level_polygons,
|
box_level_polygons,
|
||||||
SEQ_UNREACHABLE_POLYGON_CONVEX_LEVELS_MK4,
|
SEQ_UNREACHABLE_POLYGON_CONVEX_LEVELS_MK4,
|
||||||
SEQ_UNREACHABLE_POLYGON_BOX_LEVELS_MK4,
|
SEQ_UNREACHABLE_POLYGON_BOX_LEVELS_MK4,
|
||||||
scale_down_unreachable_polygons);
|
solvable_object.unreachable_polygons);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SEQ_PRINTER_TYPE_PRUSA_XL:
|
case SEQ_PRINTER_TYPE_PRUSA_XL:
|
||||||
{
|
{
|
||||||
prepare_UnreachableZonePolygons(solver_configuration,
|
prepare_UnreachableZonePolygons(solver_configuration,
|
||||||
convex_level_polygons,
|
convex_level_polygons,
|
||||||
box_level_polygons,
|
box_level_polygons,
|
||||||
SEQ_UNREACHABLE_POLYGON_CONVEX_LEVELS_XL,
|
SEQ_UNREACHABLE_POLYGON_CONVEX_LEVELS_XL,
|
||||||
SEQ_UNREACHABLE_POLYGON_BOX_LEVELS_XL,
|
SEQ_UNREACHABLE_POLYGON_BOX_LEVELS_XL,
|
||||||
scale_down_unreachable_polygons);
|
solvable_object.unreachable_polygons);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -771,22 +756,24 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unreachable_polygons.push_back(scale_down_unreachable_polygons);
|
solvable_object.id = objects_to_print[i].id;
|
||||||
lepox_to_next.push_back(objects_to_print[i].glued_to_next);
|
solvable_object.lepox_to_next = objects_to_print[i].glued_to_next;
|
||||||
|
|
||||||
|
solvable_objects.push_back(solvable_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<int> remaining_polygons;
|
std::vector<int> remaining_polygons;
|
||||||
vector<int> polygon_index_map;
|
std::vector<int> polygon_index_map;
|
||||||
vector<int> decided_polygons;
|
std::vector<int> decided_polygons;
|
||||||
|
|
||||||
for (unsigned int index = 0; index < polygons.size(); ++index)
|
for (unsigned int index = 0; index < polygons.size(); ++index)
|
||||||
{
|
{
|
||||||
polygon_index_map.push_back(index);
|
polygon_index_map.push_back(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Rational> poly_positions_X;
|
std::vector<Rational> poly_positions_X;
|
||||||
vector<Rational> poly_positions_Y;
|
std::vector<Rational> poly_positions_Y;
|
||||||
vector<Rational> times_T;
|
std::vector<Rational> times_T;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
@ -816,9 +803,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_
|
|||||||
poly_positions_X,
|
poly_positions_X,
|
||||||
poly_positions_Y,
|
poly_positions_Y,
|
||||||
times_T,
|
times_T,
|
||||||
polygons,
|
solvable_objects,
|
||||||
unreachable_polygons,
|
|
||||||
lepox_to_next,
|
|
||||||
polygon_index_map,
|
polygon_index_map,
|
||||||
decided_polygons,
|
decided_polygons,
|
||||||
remaining_polygons,
|
remaining_polygons,
|
||||||
@ -895,27 +880,14 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration &solver_
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::vector<Polygon> next_polygons;
|
std::vector<SolvableObject> next_solvable_objects;
|
||||||
std::vector<vector<Polygon> > next_unreachable_polygons;
|
|
||||||
std::vector<bool> next_lepox_to_next;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < remaining_polygons.size(); ++i)
|
for (unsigned int i = 0; i < remaining_polygons.size(); ++i)
|
||||||
{
|
{
|
||||||
next_polygons.push_back(polygons[remaining_polygons[i]]);
|
next_solvable_objects.push_back(solvable_objects[i]);
|
||||||
next_unreachable_polygons.push_back(unreachable_polygons[remaining_polygons[i]]);
|
|
||||||
next_lepox_to_next.push_back(lepox_to_next[remaining_polygons[i]]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: remove */
|
|
||||||
polygons.clear();
|
|
||||||
unreachable_polygons.clear();
|
|
||||||
lepox_to_next.clear();
|
|
||||||
|
|
||||||
polygon_index_map.clear();
|
polygon_index_map.clear();
|
||||||
|
solvable_objects = next_solvable_objects;
|
||||||
polygons = next_polygons;
|
|
||||||
unreachable_polygons = next_unreachable_polygons;
|
|
||||||
lepox_to_next = next_lepox_to_next;
|
|
||||||
|
|
||||||
std::vector<int> next_polygon_index_map;
|
std::vector<int> next_polygon_index_map;
|
||||||
std::map<int, int> next_original_index_map;
|
std::map<int, int> next_original_index_map;
|
||||||
@ -1007,11 +979,8 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::vector<Slic3r::Polygon> polygons;
|
std::vector<SolvableObject> solvable_objects;
|
||||||
std::vector<std::vector<Slic3r::Polygon> > unreachable_polygons;
|
|
||||||
|
|
||||||
std::map<int, int> original_index_map;
|
std::map<int, int> original_index_map;
|
||||||
std::vector<bool> lepox_to_next;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
@ -1090,10 +1059,9 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration
|
|||||||
}
|
}
|
||||||
++ht;
|
++ht;
|
||||||
}
|
}
|
||||||
|
SolvableObject solvable_object;
|
||||||
|
|
||||||
Polygon scale_down_polygon;
|
scaleDown_PolygonForSequentialSolver(nozzle_polygon, solvable_object.polygon);
|
||||||
scaleDown_PolygonForSequentialSolver(nozzle_polygon, scale_down_polygon);
|
|
||||||
polygons.push_back(scale_down_polygon);
|
|
||||||
|
|
||||||
std::vector<Slic3r::Polygon> convex_level_polygons;
|
std::vector<Slic3r::Polygon> convex_level_polygons;
|
||||||
convex_level_polygons.push_back(nozzle_polygon);
|
convex_level_polygons.push_back(nozzle_polygon);
|
||||||
@ -1110,17 +1078,19 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration
|
|||||||
box_level_polygons,
|
box_level_polygons,
|
||||||
convex_unreachable_zones,
|
convex_unreachable_zones,
|
||||||
box_unreachable_zones,
|
box_unreachable_zones,
|
||||||
scale_down_unreachable_polygons);
|
solvable_object.unreachable_polygons);
|
||||||
|
|
||||||
unreachable_polygons.push_back(scale_down_unreachable_polygons);
|
solvable_object.id = objects_to_print[i].id;
|
||||||
lepox_to_next.push_back(objects_to_print[i].glued_to_next);
|
solvable_object.lepox_to_next = objects_to_print[i].glued_to_next;
|
||||||
|
|
||||||
|
solvable_objects.push_back(solvable_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> remaining_polygons;
|
std::vector<int> remaining_polygons;
|
||||||
std::vector<int> polygon_index_map;
|
std::vector<int> polygon_index_map;
|
||||||
std::vector<int> decided_polygons;
|
std::vector<int> 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);
|
polygon_index_map.push_back(index);
|
||||||
}
|
}
|
||||||
@ -1157,9 +1127,7 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration
|
|||||||
poly_positions_X,
|
poly_positions_X,
|
||||||
poly_positions_Y,
|
poly_positions_Y,
|
||||||
times_T,
|
times_T,
|
||||||
polygons,
|
solvable_objects,
|
||||||
unreachable_polygons,
|
|
||||||
lepox_to_next,
|
|
||||||
polygon_index_map,
|
polygon_index_map,
|
||||||
decided_polygons,
|
decided_polygons,
|
||||||
remaining_polygons,
|
remaining_polygons,
|
||||||
@ -1237,32 +1205,19 @@ int schedule_ObjectsForSequentialPrint(const SolverConfiguration
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::vector<Polygon> next_polygons;
|
std::vector<SolvableObject> next_solvable_objects;
|
||||||
std::vector<vector<Polygon> > next_unreachable_polygons;
|
|
||||||
std::vector<bool> next_lepox_to_next;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < remaining_polygons.size(); ++i)
|
for (unsigned int i = 0; i < remaining_polygons.size(); ++i)
|
||||||
{
|
{
|
||||||
next_polygons.push_back(polygons[remaining_polygons[i]]);
|
next_solvable_objects.push_back(solvable_objects[i]);
|
||||||
next_unreachable_polygons.push_back(unreachable_polygons[remaining_polygons[i]]);
|
|
||||||
next_lepox_to_next.push_back(lepox_to_next[remaining_polygons[i]]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: remove */
|
|
||||||
polygons.clear();
|
|
||||||
unreachable_polygons.clear();
|
|
||||||
lepox_to_next.clear();
|
|
||||||
|
|
||||||
polygon_index_map.clear();
|
polygon_index_map.clear();
|
||||||
|
solvable_objects = next_solvable_objects;
|
||||||
polygons = next_polygons;
|
|
||||||
unreachable_polygons = next_unreachable_polygons;
|
|
||||||
lepox_to_next = next_lepox_to_next;
|
|
||||||
|
|
||||||
std::vector<int> next_polygon_index_map;
|
std::vector<int> next_polygon_index_map;
|
||||||
std::map<int, int> next_original_index_map;
|
std::map<int, int> 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_polygon_index_map.push_back(index);
|
||||||
next_original_index_map[index] = original_index_map[remaining_polygons[index]];
|
next_original_index_map[index] = original_index_map[remaining_polygons[index]];
|
||||||
|
@ -343,15 +343,41 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver
|
|||||||
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)
|
||||||
{
|
{
|
||||||
std::set<int> fixed_(fixed.begin(), fixed.end());
|
|
||||||
std::set<int> undecided_(undecided.begin(), undecided.end());
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < undecided.size(); ++i)
|
for (unsigned int i = 0; i < undecided.size(); ++i)
|
||||||
{
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
if ((undecided[0] - 1) >= 0)
|
||||||
|
{
|
||||||
|
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]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (lepox_to_next[undecided[i]])
|
if (lepox_to_next[undecided[i]])
|
||||||
{
|
{
|
||||||
/* TODO: we know what to do */
|
printf("Lepox constraint present: %d\n", undecided[i]);
|
||||||
//Solver.add(dec_vars_T[previous_polygons[undecided[i]]] + temporal_spread < dec_vars_T[undecided[i]] && dec_vars_T[previous_polygons[undecided[i]]] + temporal_spread + temporal_spread / 2 > dec_vars_T[undecided[i]]);
|
if (undecided.size() > i + 1)
|
||||||
|
{
|
||||||
|
int next_i = undecided[i + 1];
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (unsigned int j = 0; j < undecided.size() - 1; ++j)
|
||||||
|
{
|
||||||
|
Solver.add(dec_vars_T[undecided[j]] + temporal_spread < dec_vars_T[undecided[i]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8589,7 +8615,9 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver
|
|||||||
const string_map &dec_var_names_map,
|
const string_map &dec_var_names_map,
|
||||||
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 z3::expr_vector &presence_constraints)
|
const z3::expr_vector &presence_constraints,
|
||||||
|
const ProgressRange &progress_range,
|
||||||
|
std::function<void(int)> progress_callback)
|
||||||
{
|
{
|
||||||
z3::set_param("timeout", solver_configuration.optimization_timeout.c_str());
|
z3::set_param("timeout", solver_configuration.optimization_timeout.c_str());
|
||||||
//z3::set_param("parallel.enable", "true");
|
//z3::set_param("parallel.enable", "true");
|
||||||
@ -8606,6 +8634,9 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver
|
|||||||
coord_t half_y_min = 0;
|
coord_t half_y_min = 0;
|
||||||
coord_t half_y_max = box_half_y_max;
|
coord_t half_y_max = box_half_y_max;
|
||||||
|
|
||||||
|
int progress_total_estimation = MAX(1,std::log2(half_x_max - half_x_min));
|
||||||
|
int progress = 0;
|
||||||
|
|
||||||
while ((half_x_max - half_x_min) > 1 && (half_y_max - half_y_min) > 1)
|
while ((half_x_max - half_x_min) > 1 && (half_y_max - half_y_min) > 1)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -8940,7 +8971,11 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver
|
|||||||
printf("Halves augmented: X:[%d,%d] Y:[%d,%d]\n", half_x_min, half_x_max, half_y_min, half_y_max);
|
printf("Halves augmented: X:[%d,%d] Y:[%d,%d]\n", half_x_min, half_x_max, half_y_min, half_y_max);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
++progress;
|
||||||
|
progress_callback(progress_range.progress_min + (progress_range.progress_max - progress_range.progress_min) * progress / progress_total_estimation);
|
||||||
}
|
}
|
||||||
|
progress_callback(progress_range.progress_max);
|
||||||
|
|
||||||
if (last_solvable_bounding_box_size > 0)
|
if (last_solvable_bounding_box_size > 0)
|
||||||
{
|
{
|
||||||
@ -9987,8 +10022,8 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
|||||||
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,
|
||||||
int objects_done,
|
int progress_objects_done,
|
||||||
int total_objects,
|
int progress_total_objects,
|
||||||
std::function<void(int)> progress_callback)
|
std::function<void(int)> progress_callback)
|
||||||
{
|
{
|
||||||
std::vector<int> undecided;
|
std::vector<int> undecided;
|
||||||
@ -10067,6 +10102,26 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
|||||||
decided_polygons,
|
decided_polygons,
|
||||||
undecided,
|
undecided,
|
||||||
dec_var_names_map);
|
dec_var_names_map);
|
||||||
|
|
||||||
|
introduce_ConsequentialTemporalOrderingAgainstFixed(z_solver,
|
||||||
|
z_context,
|
||||||
|
local_dec_vars_T,
|
||||||
|
local_values_T,
|
||||||
|
decided_polygons,
|
||||||
|
undecided,
|
||||||
|
solver_configuration.temporal_spread,
|
||||||
|
polygons);
|
||||||
|
|
||||||
|
introduce_ConsequentialTemporalLepoxAgainstFixed(z_solver,
|
||||||
|
z_context,
|
||||||
|
local_dec_vars_T,
|
||||||
|
local_values_T,
|
||||||
|
decided_polygons,
|
||||||
|
undecided,
|
||||||
|
solver_configuration.temporal_spread,
|
||||||
|
polygons,
|
||||||
|
lepox_to_next);
|
||||||
|
|
||||||
#ifdef PROFILE
|
#ifdef PROFILE
|
||||||
{
|
{
|
||||||
build_finish = clock();
|
build_finish = clock();
|
||||||
@ -10074,7 +10129,8 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vector<int> missing;
|
std::vector<int> missing;
|
||||||
|
std::vector<int> remaining_local;
|
||||||
|
|
||||||
while(object_group_size > 0)
|
while(object_group_size > 0)
|
||||||
{
|
{
|
||||||
@ -10107,25 +10163,6 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
introduce_ConsequentialTemporalOrderingAgainstFixed(z_solver,
|
|
||||||
z_context,
|
|
||||||
local_dec_vars_T,
|
|
||||||
local_values_T,
|
|
||||||
decided_polygons,
|
|
||||||
undecided,
|
|
||||||
solver_configuration.temporal_spread,
|
|
||||||
polygons);
|
|
||||||
|
|
||||||
introduce_ConsequentialTemporalLepoxAgainstFixed(z_solver,
|
|
||||||
z_context,
|
|
||||||
local_dec_vars_T,
|
|
||||||
local_values_T,
|
|
||||||
decided_polygons,
|
|
||||||
undecided,
|
|
||||||
solver_configuration.temporal_spread,
|
|
||||||
polygons,
|
|
||||||
lepox_to_next);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
printf("%ld,%ld\n", local_values_X.size(), local_values_Y.size());
|
printf("%ld,%ld\n", local_values_X.size(), local_values_Y.size());
|
||||||
@ -10141,7 +10178,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + objects_done)) / total_objects);
|
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + progress_objects_done)) / progress_total_objects);
|
||||||
|
|
||||||
optimized = optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z_solver,
|
optimized = optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z_solver,
|
||||||
z_context,
|
z_context,
|
||||||
@ -10159,7 +10196,10 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
|||||||
dec_var_names_map,
|
dec_var_names_map,
|
||||||
polygons,
|
polygons,
|
||||||
unreachable_polygons,
|
unreachable_polygons,
|
||||||
presence_assumptions);
|
presence_assumptions,
|
||||||
|
ProgressRange((SEQ_PROGRESS_RANGE * (decided_polygons.size() + progress_objects_done)) / progress_total_objects,
|
||||||
|
(SEQ_PROGRESS_RANGE * (decided_polygons.size() + (progress_objects_done + 1))) / progress_total_objects),
|
||||||
|
progress_callback);
|
||||||
|
|
||||||
if (optimized)
|
if (optimized)
|
||||||
{
|
{
|
||||||
@ -10180,18 +10220,17 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
|||||||
}
|
}
|
||||||
augment_TemporalSpread(solver_configuration, dec_values_T, decided_polygons);
|
augment_TemporalSpread(solver_configuration, dec_values_T, decided_polygons);
|
||||||
|
|
||||||
if (polygons.size() - curr_polygon > (unsigned int)solver_configuration.object_group_size)
|
if (polygons.size() - curr_polygon > (unsigned int)object_group_size)
|
||||||
{
|
{
|
||||||
curr_polygon += solver_configuration.object_group_size;
|
curr_polygon += object_group_size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
curr_polygon += polygons.size() - curr_polygon;
|
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + progress_objects_done)) / progress_total_objects);
|
||||||
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + objects_done)) / total_objects);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + objects_done)) / total_objects);
|
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + progress_objects_done)) / progress_total_objects);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -10201,16 +10240,18 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
|||||||
printf("Remaining polygon: %d\n", curr_polygon + object_group_size - 1);
|
printf("Remaining polygon: %d\n", curr_polygon + object_group_size - 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
remaining_polygons.push_back(undecided_polygons[curr_polygon + object_group_size - 1]);
|
remaining_local.push_back(undecided_polygons[curr_polygon + object_group_size - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
missing.push_back(undecided.back());
|
missing.push_back(undecided.back());
|
||||||
undecided.pop_back();
|
undecided.pop_back();
|
||||||
|
|
||||||
--object_group_size;
|
--object_group_size;
|
||||||
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + objects_done)) / total_objects);
|
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + progress_objects_done)) / progress_total_objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::reverse(remaining_local.begin(), remaining_local.end());
|
||||||
|
remaining_polygons.insert(remaining_polygons.end(), remaining_local.begin(), remaining_local.end());
|
||||||
|
|
||||||
#ifdef PROFILE
|
#ifdef PROFILE
|
||||||
{
|
{
|
||||||
printf("Build: %.3f\n", build_cumul);
|
printf("Build: %.3f\n", build_cumul);
|
||||||
@ -10233,15 +10274,298 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
|||||||
{
|
{
|
||||||
remaining_polygons.push_back(undecided_polygons[curr_polygon]);
|
remaining_polygons.push_back(undecided_polygons[curr_polygon]);
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(remaining_polygons.empty());
|
||||||
|
}
|
||||||
|
assert(remaining_polygons.empty());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const SolverConfiguration &solver_configuration,
|
||||||
|
std::vector<Rational> &dec_values_X,
|
||||||
|
std::vector<Rational> &dec_values_Y,
|
||||||
|
std::vector<Rational> &dec_values_T,
|
||||||
|
const std::vector<SolvableObject> &solvable_objects,
|
||||||
|
const std::vector<int> &undecided_polygons,
|
||||||
|
std::vector<int> &decided_polygons,
|
||||||
|
std::vector<int> &remaining_polygons,
|
||||||
|
int progress_objects_done,
|
||||||
|
int progress_total_objects,
|
||||||
|
std::function<void(int)> progress_callback)
|
||||||
|
{
|
||||||
|
std::vector<int> undecided;
|
||||||
|
|
||||||
|
decided_polygons.clear();
|
||||||
|
remaining_polygons.clear();
|
||||||
|
|
||||||
|
dec_values_X.resize(solvable_objects.size());
|
||||||
|
dec_values_Y.resize(solvable_objects.size());
|
||||||
|
dec_values_T.resize(solvable_objects.size());
|
||||||
|
|
||||||
|
int box_half_x_max = solver_configuration.x_plate_bounding_box_size / 2;
|
||||||
|
int box_half_y_max = solver_configuration.y_plate_bounding_box_size / 2;
|
||||||
|
|
||||||
|
std::vector<Slic3r::Polygon> polygons;
|
||||||
|
std::vector<std::vector<Slic3r::Polygon> > unreachable_polygons;
|
||||||
|
std::vector<bool> lepox_to_next;
|
||||||
|
|
||||||
|
for (const auto& solvable_object: solvable_objects)
|
||||||
|
{
|
||||||
|
polygons.push_back(solvable_object.polygon);
|
||||||
|
unreachable_polygons.push_back(solvable_object.unreachable_polygons);
|
||||||
|
lepox_to_next.push_back(solvable_object.lepox_to_next);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int curr_polygon = 0; curr_polygon < solvable_objects.size(); /* nothing */)
|
||||||
|
{
|
||||||
|
bool optimized = false;
|
||||||
|
z3::set_param("timeout", solver_configuration.optimization_timeout.c_str());
|
||||||
|
|
||||||
|
z3::context z_context;
|
||||||
|
z3::solver z_solver(z_context);
|
||||||
|
|
||||||
|
z3::expr_vector local_dec_vars_X(z_context);
|
||||||
|
z3::expr_vector local_dec_vars_Y(z_context);
|
||||||
|
z3::expr_vector local_dec_vars_T(z_context);
|
||||||
|
|
||||||
|
vector<Rational> local_values_X;
|
||||||
|
vector<Rational> local_values_Y;
|
||||||
|
vector<Rational> local_values_T;
|
||||||
|
|
||||||
|
local_values_X.resize(solvable_objects.size());
|
||||||
|
local_values_Y.resize(solvable_objects.size());
|
||||||
|
local_values_T.resize(solvable_objects.size());
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < decided_polygons.size(); ++i)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
printf("Decided: %d %.3f, %.3f, %.3f\n",
|
||||||
|
decided_polygons[i],
|
||||||
|
dec_values_X[decided_polygons[i]].as_double(),
|
||||||
|
dec_values_Y[decided_polygons[i]].as_double(),
|
||||||
|
dec_values_T[decided_polygons[i]].as_double());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
local_values_X[decided_polygons[i]] = dec_values_X[decided_polygons[i]];
|
||||||
|
local_values_Y[decided_polygons[i]] = dec_values_Y[decided_polygons[i]];
|
||||||
|
local_values_T[decided_polygons[i]] = dec_values_T[decided_polygons[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
string_map dec_var_names_map;
|
||||||
|
int object_group_size = MIN((unsigned int)solver_configuration.object_group_size, solvable_objects.size() - curr_polygon);
|
||||||
|
|
||||||
|
undecided.clear();
|
||||||
|
for (int i = 0; i < object_group_size; ++i)
|
||||||
|
{
|
||||||
|
undecided.push_back(curr_polygon + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef PROFILE
|
||||||
|
{
|
||||||
|
build_start = clock();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
build_ConsequentialWeakPolygonNonoverlapping(z_solver,
|
||||||
|
z_context,
|
||||||
|
polygons,
|
||||||
|
unreachable_polygons,
|
||||||
|
local_dec_vars_X,
|
||||||
|
local_dec_vars_Y,
|
||||||
|
local_dec_vars_T,
|
||||||
|
local_values_X,
|
||||||
|
local_values_Y,
|
||||||
|
local_values_T,
|
||||||
|
decided_polygons,
|
||||||
|
undecided,
|
||||||
|
dec_var_names_map);
|
||||||
|
|
||||||
|
introduce_ConsequentialTemporalOrderingAgainstFixed(z_solver,
|
||||||
|
z_context,
|
||||||
|
local_dec_vars_T,
|
||||||
|
local_values_T,
|
||||||
|
decided_polygons,
|
||||||
|
undecided,
|
||||||
|
solver_configuration.temporal_spread,
|
||||||
|
polygons);
|
||||||
|
|
||||||
|
introduce_ConsequentialTemporalLepoxAgainstFixed(z_solver,
|
||||||
|
z_context,
|
||||||
|
local_dec_vars_T,
|
||||||
|
local_values_T,
|
||||||
|
decided_polygons,
|
||||||
|
undecided,
|
||||||
|
solver_configuration.temporal_spread,
|
||||||
|
polygons,
|
||||||
|
lepox_to_next);
|
||||||
|
|
||||||
|
#ifdef PROFILE
|
||||||
|
{
|
||||||
|
build_finish = clock();
|
||||||
|
build_cumul += (build_finish - build_start) / (double)CLOCKS_PER_SEC;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<int> missing;
|
||||||
|
std::vector<int> remaining_local;
|
||||||
|
|
||||||
|
while(object_group_size > 0)
|
||||||
|
{
|
||||||
|
z3::expr_vector presence_assumptions(z_context);
|
||||||
|
assume_ConsequentialObjectPresence(z_context, local_dec_vars_T, undecided, missing, presence_assumptions);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
printf("Undecided\n");
|
||||||
|
for (unsigned int j = 0; j < undecided.size(); ++j)
|
||||||
|
{
|
||||||
|
printf(" %d\n", undecided[j]);
|
||||||
|
}
|
||||||
|
printf("Decided\n");
|
||||||
|
for (unsigned int j = 0; j < decided_solvable_objects.size(); ++j)
|
||||||
|
{
|
||||||
|
printf(" %d\n", decided_polygons[j]);
|
||||||
|
}
|
||||||
|
printf("Locals\n");
|
||||||
|
for (unsigned int j = 0; j < solvable_objects.size(); ++j)
|
||||||
|
{
|
||||||
|
printf("X: %ld,%ld Y: %ld,%ld T: %ld,%ld\n",
|
||||||
|
local_values_X[j].numerator,
|
||||||
|
local_values_X[j].denominator,
|
||||||
|
local_values_Y[j].numerator,
|
||||||
|
local_values_Y[j].denominator,
|
||||||
|
local_values_T[j].numerator,
|
||||||
|
local_values_T[j].denominator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
printf("%ld,%ld\n", local_values_X.size(), local_values_Y.size());
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < solvable_objects.size(); ++i)
|
||||||
|
{
|
||||||
|
printf("poly: %ld\n", polygons[i].points.size());
|
||||||
|
for (unsigned int j = 0; j < polygons[i].points.size(); ++j)
|
||||||
|
{
|
||||||
|
printf(" %d,%d\n", polygons[i].points[j].x(), polygons[i].points[j].y());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + progress_objects_done)) / progress_total_objects);
|
||||||
|
|
||||||
|
optimized = optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z_solver,
|
||||||
|
z_context,
|
||||||
|
solver_configuration,
|
||||||
|
box_half_x_max,
|
||||||
|
box_half_y_max,
|
||||||
|
local_dec_vars_X,
|
||||||
|
local_dec_vars_Y,
|
||||||
|
local_dec_vars_T,
|
||||||
|
local_values_X,
|
||||||
|
local_values_Y,
|
||||||
|
local_values_T,
|
||||||
|
decided_polygons,
|
||||||
|
undecided,
|
||||||
|
dec_var_names_map,
|
||||||
|
polygons,
|
||||||
|
unreachable_polygons,
|
||||||
|
presence_assumptions,
|
||||||
|
ProgressRange((SEQ_PROGRESS_RANGE * (decided_polygons.size() + progress_objects_done)) / progress_total_objects,
|
||||||
|
(SEQ_PROGRESS_RANGE * (decided_polygons.size() + (progress_objects_done + 1))) / progress_total_objects),
|
||||||
|
progress_callback);
|
||||||
|
|
||||||
|
if (optimized)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
printf("Printing solver status:\n");
|
||||||
|
cout << z_solver << "\n";
|
||||||
|
|
||||||
|
printf("Printing smt status:\n");
|
||||||
|
cout << z_solver.to_smt2() << "\n";
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < undecided.size(); ++i)
|
||||||
|
{
|
||||||
|
dec_values_X[undecided[i]] = local_values_X[undecided[i]];
|
||||||
|
dec_values_Y[undecided[i]] = local_values_Y[undecided[i]];
|
||||||
|
dec_values_T[undecided[i]] = local_values_T[undecided[i]];
|
||||||
|
decided_polygons.push_back(undecided[i]);
|
||||||
|
}
|
||||||
|
augment_TemporalSpread(solver_configuration, dec_values_T, decided_polygons);
|
||||||
|
|
||||||
|
if (solvable_objects.size() - curr_polygon > (unsigned int)object_group_size)
|
||||||
|
{
|
||||||
|
curr_polygon += object_group_size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + progress_objects_done)) / progress_total_objects);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + progress_objects_done)) / progress_total_objects);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
printf("Remaining polygon: %d\n", curr_polygon + object_group_size - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
remaining_local.push_back(undecided_polygons[curr_polygon + object_group_size - 1]);
|
||||||
|
}
|
||||||
|
missing.push_back(undecided.back());
|
||||||
|
undecided.pop_back();
|
||||||
|
|
||||||
|
--object_group_size;
|
||||||
|
progress_callback((SEQ_PROGRESS_RANGE * (decided_polygons.size() + progress_objects_done)) / progress_total_objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::reverse(remaining_local.begin(), remaining_local.end());
|
||||||
|
remaining_polygons.insert(remaining_polygons.end(), remaining_local.begin(), remaining_local.end());
|
||||||
|
|
||||||
|
#ifdef PROFILE
|
||||||
|
{
|
||||||
|
printf("Build: %.3f\n", build_cumul);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!optimized)
|
||||||
|
{
|
||||||
|
if (curr_polygon <= 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (solvable_objects.size() - curr_polygon > (unsigned int)solver_configuration.object_group_size)
|
||||||
|
{
|
||||||
|
curr_polygon += solver_configuration.object_group_size;
|
||||||
|
|
||||||
|
for (; curr_polygon < solvable_objects.size(); ++curr_polygon)
|
||||||
|
{
|
||||||
|
remaining_polygons.push_back(undecided_polygons[curr_polygon]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert(remaining_polygons.empty());
|
||||||
}
|
}
|
||||||
|
assert(remaining_polygons.empty());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,18 @@ typedef std::basic_string<char> string;
|
|||||||
typedef std::unordered_map<string, int> string_map;
|
typedef std::unordered_map<string, int> string_map;
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
struct SolvableObject
|
||||||
|
{
|
||||||
|
int id = 0;
|
||||||
|
|
||||||
|
Slic3r::Polygon polygon;
|
||||||
|
std::vector<Slic3r::Polygon> unreachable_polygons;
|
||||||
|
bool lepox_to_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
struct Rational
|
struct Rational
|
||||||
@ -179,6 +191,20 @@ struct Rational
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
struct ProgressRange
|
||||||
|
{
|
||||||
|
ProgressRange(int min, int max)
|
||||||
|
: progress_min(min)
|
||||||
|
, progress_max(max)
|
||||||
|
{ /* nothing */ }
|
||||||
|
|
||||||
|
int progress_min;
|
||||||
|
int progress_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
bool lines_intersect_(coord_t ax, coord_t ay, coord_t ux, coord_t uy, coord_t bx, coord_t by, coord_t vx, coord_t vy);
|
bool lines_intersect_(coord_t ax, coord_t ay, coord_t ux, coord_t uy, coord_t bx, coord_t by, coord_t vx, coord_t vy);
|
||||||
@ -1447,6 +1473,7 @@ bool optimize_SequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver
|
|||||||
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);
|
||||||
|
|
||||||
|
|
||||||
bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver &Solver,
|
bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver &Solver,
|
||||||
z3::context &Context,
|
z3::context &Context,
|
||||||
const SolverConfiguration &solver_configuration,
|
const SolverConfiguration &solver_configuration,
|
||||||
@ -1462,7 +1489,9 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver
|
|||||||
const std::vector<int> &undecided,
|
const std::vector<int> &undecided,
|
||||||
const string_map &dec_var_names_map,
|
const string_map &dec_var_names_map,
|
||||||
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 ProgressRange &progress_range,
|
||||||
|
std::function<void(int)> progress_callback);
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
@ -1565,8 +1594,20 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
|||||||
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,
|
||||||
int objects_done,
|
int progress_objects_done,
|
||||||
int total_objects,
|
int progress_total_objects,
|
||||||
|
std::function<void(int)> progress_callback = [](int progress){});
|
||||||
|
|
||||||
|
bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const SolverConfiguration &solver_configuration,
|
||||||
|
std::vector<Rational> &dec_values_X,
|
||||||
|
std::vector<Rational> &dec_values_Y,
|
||||||
|
std::vector<Rational> &dec_values_T,
|
||||||
|
const std::vector<SolvableObject> &solvable_objects,
|
||||||
|
const std::vector<int> &undecided_polygons,
|
||||||
|
std::vector<int> &decided_polygons,
|
||||||
|
std::vector<int> &remaining_polygons,
|
||||||
|
int progress_objects_done,
|
||||||
|
int progress_total_objects,
|
||||||
std::function<void(int)> progress_callback = [](int progress){});
|
std::function<void(int)> progress_callback = [](int progress){});
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
@ -752,11 +752,6 @@ int solve_SequentialPrint(const CommandParameters &command_parameters)
|
|||||||
next_lepox_to_next.push_back(lepox_to_next[remaining_polygons[i]]);
|
next_lepox_to_next.push_back(lepox_to_next[remaining_polygons[i]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: remove */
|
|
||||||
polygons.clear();
|
|
||||||
unreachable_polygons.clear();
|
|
||||||
lepox_to_next.clear();
|
|
||||||
|
|
||||||
polygon_index_map.clear();
|
polygon_index_map.clear();
|
||||||
|
|
||||||
polygons = next_polygons;
|
polygons = next_polygons;
|
||||||
|
@ -401,6 +401,87 @@ int test_interface_5(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int test_interface_6(void)
|
||||||
|
{
|
||||||
|
clock_t start, finish;
|
||||||
|
|
||||||
|
printf("Testing interface 6 ...\n");
|
||||||
|
|
||||||
|
start = clock();
|
||||||
|
|
||||||
|
SolverConfiguration solver_configuration;
|
||||||
|
solver_configuration.decimation_precision = SEQ_DECIMATION_PRECISION_LOW;
|
||||||
|
solver_configuration.object_group_size = 4;
|
||||||
|
|
||||||
|
printf("Loading objects ...\n");
|
||||||
|
std::vector<ObjectToPrint> objects_to_print = load_exported_data("arrange_data_export.txt");
|
||||||
|
printf("Loading objects ... finished\n");
|
||||||
|
|
||||||
|
for (auto& object_to_print: objects_to_print)
|
||||||
|
{
|
||||||
|
object_to_print.glued_to_next = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrinterGeometry printer_geometry;
|
||||||
|
|
||||||
|
printf("Loading printer geometry ...\n");
|
||||||
|
int result = load_printer_geometry("../printers/printer_geometry.mk4.compatibility.txt", printer_geometry);
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
printf("Cannot load printer geometry (code: %d).\n", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
solver_configuration.setup(printer_geometry);
|
||||||
|
printf("Loading printer geometry ... finished\n");
|
||||||
|
|
||||||
|
std::vector<ScheduledPlate> scheduled_plates;
|
||||||
|
printf("Scheduling objects for sequential print ...\n");
|
||||||
|
|
||||||
|
scheduled_plates = schedule_ObjectsForSequentialPrint(solver_configuration,
|
||||||
|
printer_geometry,
|
||||||
|
objects_to_print,
|
||||||
|
[](int progress) { printf("Progress: %d\n", progress); });
|
||||||
|
|
||||||
|
printf("Object scheduling for sequential print SUCCESSFUL !\n");
|
||||||
|
|
||||||
|
printf("Number of plates: %ld\n", scheduled_plates.size());
|
||||||
|
|
||||||
|
for (unsigned int plate = 0; plate < scheduled_plates.size(); ++plate)
|
||||||
|
{
|
||||||
|
printf(" Number of objects on plate: %ld\n", scheduled_plates[plate].scheduled_objects.size());
|
||||||
|
|
||||||
|
for (const auto& scheduled_object: scheduled_plates[plate].scheduled_objects)
|
||||||
|
{
|
||||||
|
cout << " ID: " << scheduled_object.id << " X: " << scheduled_object.x << " Y: " << scheduled_object.y << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finish = clock();
|
||||||
|
printf("Solving time: %.3f\n", (finish - start) / (double)CLOCKS_PER_SEC);
|
||||||
|
|
||||||
|
start = clock();
|
||||||
|
|
||||||
|
printf("Checking sequential printability ...\n");
|
||||||
|
|
||||||
|
bool printable = check_ScheduledObjectsForSequentialPrintability(solver_configuration,
|
||||||
|
printer_geometry,
|
||||||
|
objects_to_print,
|
||||||
|
scheduled_plates);
|
||||||
|
|
||||||
|
printf(" Scheduled/arranged objects are sequentially printable: %s\n", (printable ? "YES" : "NO"));
|
||||||
|
|
||||||
|
printf("Checking sequential printability ... finished\n");
|
||||||
|
|
||||||
|
finish = clock();
|
||||||
|
printf("Checking time: %.3f\n", (finish - start) / (double)CLOCKS_PER_SEC);
|
||||||
|
|
||||||
|
printf("Testing interface 6 ... finished\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
int main(int SEQ_UNUSED(argc), char **SEQ_UNUSED(argv))
|
int main(int SEQ_UNUSED(argc), char **SEQ_UNUSED(argv))
|
||||||
@ -410,6 +491,7 @@ int main(int SEQ_UNUSED(argc), char **SEQ_UNUSED(argv))
|
|||||||
// test_interface_3();
|
// test_interface_3();
|
||||||
// test_interface_4();
|
// test_interface_4();
|
||||||
test_interface_5();
|
test_interface_5();
|
||||||
|
// test_interface_6();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ int test_interface_4(void);
|
|||||||
/* Interface test 5 */
|
/* Interface test 5 */
|
||||||
int test_interface_5(void);
|
int test_interface_5(void);
|
||||||
|
|
||||||
|
/* Interface test 6 */
|
||||||
|
int test_interface_6(void);
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ static std::vector<Sequential::ObjectToPrint> get_objects_to_print(const Model&
|
|||||||
std::vector<Sequential::ObjectToPrint> objects;
|
std::vector<Sequential::ObjectToPrint> objects;
|
||||||
for (const ModelObject* mo : model.objects) {
|
for (const ModelObject* mo : model.objects) {
|
||||||
const ModelInstance* mi = mo->instances.front();
|
const ModelInstance* mi = mo->instances.front();
|
||||||
objects.emplace_back(Sequential::ObjectToPrint{int(mo->id().id), scaled(mo->instance_bounding_box(0).size().z()), {}});
|
objects.emplace_back(Sequential::ObjectToPrint{int(mo->id().id), false, scaled(mo->instance_bounding_box(0).size().z()), {}});
|
||||||
for (double height : heights) {
|
for (double height : heights) {
|
||||||
auto tr = Transform3d::Identity();
|
auto tr = Transform3d::Identity();
|
||||||
Vec3d offset = mi->get_offset();
|
Vec3d offset = mi->get_offset();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user