mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 18:25:55 +08:00
#11484 - Fixed crash when applying Split to Objects command (SPE-1983)
This commit is contained in:
parent
a9410edc2c
commit
9c3a3f8a87
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user