mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-01 00:42:07 +08:00
Merge branch 'master' of https://github.com/Prusa-Development/PrusaSlicerPrivate into et_transformations
This commit is contained in:
commit
e0d2338787
@ -31,6 +31,9 @@ public:
|
|||||||
virtual void reverse() = 0;
|
virtual void reverse() = 0;
|
||||||
virtual const Point& first_point() const = 0;
|
virtual const Point& first_point() const = 0;
|
||||||
virtual const Point& last_point() const = 0;
|
virtual const Point& last_point() const = 0;
|
||||||
|
// Returns an approximately middle point of a path, loop or an extrusion collection.
|
||||||
|
// Used to get a sample point of an extrusion or extrusion collection, which is possibly deep inside its island.
|
||||||
|
virtual const Point& middle_point() const = 0;
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
virtual void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const = 0;
|
virtual void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const = 0;
|
||||||
@ -81,6 +84,7 @@ public:
|
|||||||
void reverse() override { this->polyline.reverse(); }
|
void reverse() override { this->polyline.reverse(); }
|
||||||
const Point& first_point() const override { return this->polyline.points.front(); }
|
const Point& first_point() const override { return this->polyline.points.front(); }
|
||||||
const Point& last_point() const override { return this->polyline.points.back(); }
|
const Point& last_point() const override { return this->polyline.points.back(); }
|
||||||
|
const Point& middle_point() const override { return this->polyline.points[this->polyline.size() / 2]; }
|
||||||
size_t size() const { return this->polyline.size(); }
|
size_t size() const { return this->polyline.size(); }
|
||||||
bool empty() const { return this->polyline.empty(); }
|
bool empty() const { return this->polyline.empty(); }
|
||||||
bool is_closed() const { return ! this->empty() && this->polyline.points.front() == this->polyline.points.back(); }
|
bool is_closed() const { return ! this->empty() && this->polyline.points.front() == this->polyline.points.back(); }
|
||||||
@ -153,6 +157,7 @@ public:
|
|||||||
void reverse() override;
|
void reverse() override;
|
||||||
const Point& first_point() const override { return this->paths.front().polyline.points.front(); }
|
const Point& first_point() const override { return this->paths.front().polyline.points.front(); }
|
||||||
const Point& last_point() const override { return this->paths.back().polyline.points.back(); }
|
const Point& last_point() const override { return this->paths.back().polyline.points.back(); }
|
||||||
|
const Point& middle_point() const override { auto &path = this->paths[this->paths.size() / 2]; return path.polyline.points[path.polyline.size() / 2]; }
|
||||||
size_t size() const { return this->paths.size(); }
|
size_t size() const { return this->paths.size(); }
|
||||||
bool empty() const { return this->paths.empty(); }
|
bool empty() const { return this->paths.empty(); }
|
||||||
double length() const override;
|
double length() const override;
|
||||||
@ -204,6 +209,7 @@ public:
|
|||||||
void reverse() override;
|
void reverse() override;
|
||||||
const Point& first_point() const override { return this->paths.front().polyline.points.front(); }
|
const Point& first_point() const override { return this->paths.front().polyline.points.front(); }
|
||||||
const Point& last_point() const override { assert(this->first_point() == this->paths.back().polyline.points.back()); return this->first_point(); }
|
const Point& last_point() const override { assert(this->first_point() == this->paths.back().polyline.points.back()); return this->first_point(); }
|
||||||
|
const Point& middle_point() const override { auto& path = this->paths[this->paths.size() / 2]; return path.polyline.points[path.polyline.size() / 2]; }
|
||||||
Polygon polygon() const;
|
Polygon polygon() const;
|
||||||
double length() const override;
|
double length() const override;
|
||||||
bool split_at_vertex(const Point &point, const double scaled_epsilon = scaled<double>(0.001));
|
bool split_at_vertex(const Point &point, const double scaled_epsilon = scaled<double>(0.001));
|
||||||
|
@ -102,6 +102,7 @@ public:
|
|||||||
void reverse() override;
|
void reverse() override;
|
||||||
const Point& first_point() const override { return this->entities.front()->first_point(); }
|
const Point& first_point() const override { return this->entities.front()->first_point(); }
|
||||||
const Point& last_point() const override { return this->entities.back()->last_point(); }
|
const Point& last_point() const override { return this->entities.back()->last_point(); }
|
||||||
|
const Point& middle_point() const override { return this->entities[this->entities.size() / 2]->middle_point(); }
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override;
|
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override;
|
||||||
|
@ -578,7 +578,7 @@ void Layer::sort_perimeters_into_islands(
|
|||||||
// Take a sample deep inside its island if available. Infills are usually quite far from the island boundary.
|
// Take a sample deep inside its island if available. Infills are usually quite far from the island boundary.
|
||||||
for (uint32_t iexpoly : fill_expolygons_ranges[islice])
|
for (uint32_t iexpoly : fill_expolygons_ranges[islice])
|
||||||
if (const ExPolygon &expoly = fill_expolygons[iexpoly]; ! expoly.empty()) {
|
if (const ExPolygon &expoly = fill_expolygons[iexpoly]; ! expoly.empty()) {
|
||||||
sample = expoly.contour.points.front();
|
sample = expoly.contour.points[expoly.contour.points.size() / 2];
|
||||||
sample_set = true;
|
sample_set = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -589,12 +589,12 @@ void Layer::sort_perimeters_into_islands(
|
|||||||
if (ee.is_collection()) {
|
if (ee.is_collection()) {
|
||||||
for (const ExtrusionEntity *ee2 : dynamic_cast<const ExtrusionEntityCollection&>(ee).entities)
|
for (const ExtrusionEntity *ee2 : dynamic_cast<const ExtrusionEntityCollection&>(ee).entities)
|
||||||
if (! ee2->role().is_external()) {
|
if (! ee2->role().is_external()) {
|
||||||
sample = ee2->first_point();
|
sample = ee2->middle_point();
|
||||||
sample_set = true;
|
sample_set = true;
|
||||||
goto loop_end;
|
goto loop_end;
|
||||||
}
|
}
|
||||||
} else if (! ee.role().is_external()) {
|
} else if (! ee.role().is_external()) {
|
||||||
sample = ee.first_point();
|
sample = ee.middle_point();
|
||||||
sample_set = true;
|
sample_set = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -603,12 +603,12 @@ void Layer::sort_perimeters_into_islands(
|
|||||||
if (! sample_set) {
|
if (! sample_set) {
|
||||||
if (! extrusions.second.empty()) {
|
if (! extrusions.second.empty()) {
|
||||||
// If there is no inner perimeter, take a sample of some gap fill extrusion.
|
// If there is no inner perimeter, take a sample of some gap fill extrusion.
|
||||||
sample = this_layer_region.thin_fills().entities[*extrusions.second.begin()]->first_point();
|
sample = this_layer_region.thin_fills().entities[*extrusions.second.begin()]->middle_point();
|
||||||
sample_set = true;
|
sample_set = true;
|
||||||
}
|
}
|
||||||
if (! sample_set && ! extrusions.first.empty()) {
|
if (! sample_set && ! extrusions.first.empty()) {
|
||||||
// As a last resort, take a sample of some external perimeter.
|
// As a last resort, take a sample of some external perimeter.
|
||||||
sample = this_layer_region.perimeters().entities[*extrusions.first.begin()]->first_point();
|
sample = this_layer_region.perimeters().entities[*extrusions.first.begin()]->middle_point();
|
||||||
sample_set = true;
|
sample_set = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -835,6 +835,15 @@ void Layer::sort_perimeters_into_islands(
|
|||||||
d2min = d2;
|
d2min = d2;
|
||||||
lslice_idx_min = lslice_idx;
|
lslice_idx_min = lslice_idx;
|
||||||
}
|
}
|
||||||
|
if (lslice_idx_min == -1) {
|
||||||
|
// This should not happen, but Arachne seems to produce a perimeter point far outside its source contour.
|
||||||
|
// As a last resort, find the closest source contours to the sample point.
|
||||||
|
for (int lslice_idx = int(lslices_ex.size()) - 1; lslice_idx >= 0; -- lslice_idx)
|
||||||
|
if (double d2 = (lslices[lslice_idx].point_projection(it_source_slice->second) - it_source_slice->second).cast<double>().squaredNorm(); d2 < d2min) {
|
||||||
|
d2min = d2;
|
||||||
|
lslice_idx_min = lslice_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
assert(lslice_idx_min != -1);
|
assert(lslice_idx_min != -1);
|
||||||
insert_into_island(lslice_idx_min, it_source_slice->first);
|
insert_into_island(lslice_idx_min, it_source_slice->first);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user