Perfrom seam placing on geometry only for SeamAligned, otherwise use extrusions

This commit is contained in:
Martin Šach 2024-07-18 12:46:35 +02:00 committed by Lukas Matena
parent 214a35d968
commit ef2a64032a
5 changed files with 45 additions and 9 deletions

View File

@ -218,7 +218,7 @@ BoundedPolygons project_to_geometry(const Geometry::Extrusions &external_perimet
Polygons expanded_extrusion{expand(external_perimeter.polygon, external_perimeter.width / 2.0)}; Polygons expanded_extrusion{expand(external_perimeter.polygon, external_perimeter.width / 2.0)};
if (!expanded_extrusion.empty()) { if (!expanded_extrusion.empty()) {
return BoundedPolygon{ return BoundedPolygon{
expanded_extrusion.front(), expanded_extrusion.front().bounding_box(), external_perimeter.polygon.is_clockwise() expanded_extrusion.front(), expanded_extrusion.front().bounding_box(), external_perimeter.polygon.is_clockwise(), 0.0
}; };
} }
} }
@ -227,7 +227,7 @@ BoundedPolygons project_to_geometry(const Geometry::Extrusions &external_perimet
const Polygon &adjacent_boundary{ const Polygon &adjacent_boundary{
!is_hole ? external_perimeter.island_boundary.contour : !is_hole ? external_perimeter.island_boundary.contour :
external_perimeter.island_boundary.holes[choosen_index - 1]}; external_perimeter.island_boundary.holes[choosen_index - 1]};
return BoundedPolygon{adjacent_boundary, external_perimeter.island_boundary_bounding_boxes[choosen_index], is_hole}; return BoundedPolygon{adjacent_boundary, external_perimeter.island_boundary_bounding_boxes[choosen_index], is_hole, 0.0};
} }
); );
return result; return result;
@ -243,6 +243,27 @@ std::vector<BoundedPolygons> project_to_geometry(const std::vector<Geometry::Ext
return result; return result;
} }
std::vector<BoundedPolygons> convert_to_geometry(const std::vector<Geometry::Extrusions> &extrusions) {
std::vector<BoundedPolygons> result;
result.reserve(extrusions.size());
for (const Geometry::Extrusions &layer : extrusions) {
result.emplace_back();
using std::transform, std::back_inserter;
transform(
layer.begin(), layer.end(), back_inserter(result.back()),
[&](const Geometry::Extrusion &extrusion) {
return BoundedPolygon{
extrusion.polygon, extrusion.bounding_box, extrusion.polygon.is_clockwise(), extrusion.width / 2.0
};
}
);
}
return result;
}
std::vector<Vec2d> oversample_edge(const Vec2d &from, const Vec2d &to, const double max_distance) { std::vector<Vec2d> oversample_edge(const Vec2d &from, const Vec2d &to, const double max_distance) {
const double total_distance{(from - to).norm()}; const double total_distance{(from - to).norm()};
const auto points_count{static_cast<std::size_t>(std::ceil(total_distance / max_distance)) + 1}; const auto points_count{static_cast<std::size_t>(std::ceil(total_distance / max_distance)) + 1};

View File

@ -61,12 +61,14 @@ struct BoundedPolygon {
Polygon polygon; Polygon polygon;
BoundingBox bounding_box; BoundingBox bounding_box;
bool is_hole{false}; bool is_hole{false};
double offset_inside{};
}; };
using BoundedPolygons = std::vector<BoundedPolygon>; using BoundedPolygons = std::vector<BoundedPolygon>;
BoundedPolygons project_to_geometry(const Geometry::Extrusions &external_perimeters, const double max_bb_distance); BoundedPolygons project_to_geometry(const Geometry::Extrusions &external_perimeters, const double max_bb_distance);
std::vector<BoundedPolygons> project_to_geometry(const std::vector<Geometry::Extrusions> &extrusions, const double max_bb_distance); std::vector<BoundedPolygons> project_to_geometry(const std::vector<Geometry::Extrusions> &extrusions, const double max_bb_distance);
std::vector<BoundedPolygons> convert_to_geometry(const std::vector<Geometry::Extrusions> &extrusions);
Vec2d get_polygon_normal( Vec2d get_polygon_normal(
const std::vector<Vec2d> &points, const std::size_t index, const double min_arm_length const std::vector<Vec2d> &points, const std::size_t index, const double min_arm_length

View File

@ -326,7 +326,8 @@ Perimeter Perimeter::create(
const Polygon &polygon, const Polygon &polygon,
const ModelInfo::Painting &painting, const ModelInfo::Painting &painting,
const LayerInfo &layer_info, const LayerInfo &layer_info,
const PerimeterParams &params const PerimeterParams &params,
const double offset_inside
) { ) {
if (polygon.size() < 3) { if (polygon.size() < 3) {
return Perimeter::create_degenerate( return Perimeter::create_degenerate(
@ -353,10 +354,17 @@ Perimeter Perimeter::create(
Impl::oversample_painted(points, is_painted, layer_info.slice_z, params.oversampling_max_distance)}; Impl::oversample_painted(points, is_painted, layer_info.slice_z, params.oversampling_max_distance)};
std::vector<PointType> point_types{ std::vector<PointType> point_types{
Impl::get_point_types(perimeter_points, painting, layer_info.slice_z, params.painting_radius)}; Impl::get_point_types(perimeter_points, painting, layer_info.slice_z, offset_inside > 0 ? offset_inside * 2 : params.painting_radius)};
std::tie(perimeter_points, point_types) = // Geometry converted from extrusions has non zero offset_inside.
Impl::remove_redundant_points(perimeter_points, point_types, params.simplification_epsilon); // Do not remomve redundant points for extrusions, becouse the redundant
// points can be on overhangs.
if (offset_inside < std::numeric_limits<double>::epsilon()) {
// The following is optimization with significant impact. If in doubt, run
// the "Seam benchmarks" test case in fff_print_tests.
std::tie(perimeter_points, point_types) =
Impl::remove_redundant_points(perimeter_points, point_types, params.simplification_epsilon);
}
const std::vector<double> embeddings{ const std::vector<double> embeddings{
Geometry::get_embedding_distances(perimeter_points, layer_info.distancer)}; Geometry::get_embedding_distances(perimeter_points, layer_info.distancer)};
@ -411,7 +419,7 @@ LayerPerimeters create_perimeters(
const Geometry::BoundedPolygon &bounded_polygon{layer[polygon_index]}; const Geometry::BoundedPolygon &bounded_polygon{layer[polygon_index]};
const LayerInfo &layer_info{layer_infos[layer_index]}; const LayerInfo &layer_info{layer_infos[layer_index]};
result[layer_index][polygon_index] = BoundedPerimeter{ result[layer_index][polygon_index] = BoundedPerimeter{
Perimeter::create(bounded_polygon.polygon, painting, layer_info, params), Perimeter::create(bounded_polygon.polygon, painting, layer_info, params, bounded_polygon.offset_inside),
bounded_polygon.bounding_box}; bounded_polygon.bounding_box};
} }
); );

View File

@ -151,7 +151,8 @@ struct Perimeter
const Polygon &polygon, const Polygon &polygon,
const ModelInfo::Painting &painting, const ModelInfo::Painting &painting,
const LayerInfo &layer_info, const LayerInfo &layer_info,
const PerimeterParams &params const PerimeterParams &params,
const double offset_inside
); );
static Perimeter create_degenerate( static Perimeter create_degenerate(

View File

@ -38,7 +38,11 @@ ObjectLayerPerimeters get_perimeters(
const Perimeters::LayerInfos layer_infos{Perimeters::get_layer_infos( const Perimeters::LayerInfos layer_infos{Perimeters::get_layer_infos(
print_object->layers(), params.perimeter.elephant_foot_compensation print_object->layers(), params.perimeter.elephant_foot_compensation
)}; )};
const std::vector<Geometry::BoundedPolygons> projected{Geometry::project_to_geometry(extrusions, params.max_distance)}; const std::vector<Geometry::BoundedPolygons> projected{
print_object->config().seam_position == spAligned ?
Geometry::project_to_geometry(extrusions, params.max_distance) :
Geometry::convert_to_geometry(extrusions)
};
Perimeters::LayerPerimeters perimeters{Perimeters::create_perimeters(projected, layer_infos, painting, params.perimeter)}; Perimeters::LayerPerimeters perimeters{Perimeters::create_perimeters(projected, layer_infos, painting, params.perimeter)};
throw_if_canceled(); throw_if_canceled();