#11484 - Fixed crash when applying Split to Objects command (SPE-1983)

This commit is contained in:
enricoturri1966 2023-10-23 12:02:22 +02:00 committed by YuSanka
parent a9410edc2c
commit 9c3a3f8a87

View File

@ -417,54 +417,58 @@ bool Print::sequential_print_horizontal_clearance_valid(const Print& print, Poly
polygons->clear();
std::vector<size_t> intersecting_idxs;
std::map<ObjectID, Polygon> map_model_object_to_convex_hull;
for (const PrintObject *print_object : print.objects()) {
assert(! print_object->model_object()->instances.empty());
assert(! print_object->instances().empty());
ObjectID model_object_id = print_object->model_object()->id();
auto it_convex_hull = map_model_object_to_convex_hull.find(model_object_id);
std::map<ObjectID, Polygon> map_model_object_to_convex_hull;
for (const PrintObject *print_object : print.objects()) {
assert(! print_object->model_object()->instances.empty());
assert(! print_object->instances().empty());
ObjectID model_object_id = print_object->model_object()->id();
auto it_convex_hull = map_model_object_to_convex_hull.find(model_object_id);
// Get convex hull of all printable volumes assigned to this print object.
ModelInstance *model_instance0 = print_object->model_object()->instances.front();
if (it_convex_hull == map_model_object_to_convex_hull.end()) {
// Calculate the convex hull of a printable object.
// Grow convex hull with the clearance margin.
// FIXME: Arrangement has different parameters for offsetting (jtMiter, limit 2)
// which causes that the warning will be showed after arrangement with the
// appropriate object distance. Even if I set this to jtMiter the warning still shows up.
Geometry::Transformation trafo = model_instance0->get_transformation();
trafo.set_offset({ 0.0, 0.0, model_instance0->get_offset().z() });
it_convex_hull = map_model_object_to_convex_hull.emplace_hint(it_convex_hull, model_object_id,
offset(print_object->model_object()->convex_hull_2d(trafo.get_matrix()),
// Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects
// exactly by satisfying the extruder_clearance_radius, this test will not trigger collision.
float(scale_(0.5 * print.config().extruder_clearance_radius.value - BuildVolume::BedEpsilon)),
jtRound, scale_(0.1)).front());
}
// Make a copy, so it may be rotated for instances.
Polygon convex_hull0 = it_convex_hull->second;
const double z_diff = Geometry::rotation_diff_z(model_instance0->get_matrix(), print_object->instances().front().model_instance->get_matrix());
if (std::abs(z_diff) > EPSILON)
convex_hull0.rotate(z_diff);
// Now we check that no instance of convex_hull intersects any of the previously checked object instances.
for (const PrintInstance &instance : print_object->instances()) {
Polygon convex_hull = convex_hull0;
// instance.shift is a position of a centered object, while model object may not be centered.
// Convert the shift from the PrintObject's coordinates into ModelObject's coordinates by removing the centering offset.
convex_hull.translate(instance.shift - print_object->center_offset());
// if output needed, collect indices (inside convex_hulls_other) of intersecting hulls
for (size_t i = 0; i < convex_hulls_other.size(); ++i) {
if (! intersection(convex_hulls_other[i], convex_hull).empty()) {
if (polygons == nullptr)
return false;
else {
intersecting_idxs.emplace_back(i);
intersecting_idxs.emplace_back(convex_hulls_other.size());
if (it_convex_hull == map_model_object_to_convex_hull.end()) {
// Calculate the convex hull of a printable object.
// Grow convex hull with the clearance margin.
// FIXME: Arrangement has different parameters for offsetting (jtMiter, limit 2)
// which causes that the warning will be showed after arrangement with the
// appropriate object distance. Even if I set this to jtMiter the warning still shows up.
Geometry::Transformation trafo = model_instance0->get_transformation();
trafo.set_offset({ 0.0, 0.0, model_instance0->get_offset().z() });
Polygon ch2d = print_object->model_object()->convex_hull_2d(trafo.get_matrix());
Polygons offs_ch2d = offset(ch2d,
// Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects
// exactly by satisfying the extruder_clearance_radius, this test will not trigger collision.
float(scale_(0.5 * print.config().extruder_clearance_radius.value - BuildVolume::BedEpsilon)), jtRound, scale_(0.1));
// for invalid geometries the vector returned by offset() may be empty
if (!offs_ch2d.empty())
it_convex_hull = map_model_object_to_convex_hull.emplace_hint(it_convex_hull, model_object_id, offs_ch2d.front());
}
if (it_convex_hull != map_model_object_to_convex_hull.end()) {
// Make a copy, so it may be rotated for instances.
Polygon convex_hull0 = it_convex_hull->second;
const double z_diff = Geometry::rotation_diff_z(model_instance0->get_matrix(), print_object->instances().front().model_instance->get_matrix());
if (std::abs(z_diff) > EPSILON)
convex_hull0.rotate(z_diff);
// Now we check that no instance of convex_hull intersects any of the previously checked object instances.
for (const PrintInstance& instance : print_object->instances()) {
Polygon convex_hull = convex_hull0;
// instance.shift is a position of a centered object, while model object may not be centered.
// Convert the shift from the PrintObject's coordinates into ModelObject's coordinates by removing the centering offset.
convex_hull.translate(instance.shift - print_object->center_offset());
// if output needed, collect indices (inside convex_hulls_other) of intersecting hulls
for (size_t i = 0; i < convex_hulls_other.size(); ++i) {
if (!intersection(convex_hulls_other[i], convex_hull).empty()) {
if (polygons == nullptr)
return false;
else {
intersecting_idxs.emplace_back(i);
intersecting_idxs.emplace_back(convex_hulls_other.size());
}
}
}
convex_hulls_other.emplace_back(std::move(convex_hull));
}
convex_hulls_other.emplace_back(std::move(convex_hull));
}
}
}
}
if (!intersecting_idxs.empty()) {
// use collected indices (inside convex_hulls_other) to update output