-
-
Notifications
You must be signed in to change notification settings - Fork 909
Combing polygon type #2231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jellespijker
wants to merge
3
commits into
main
Choose a base branch
from
combing-polygon-type
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Combing polygon type #2231
Changes from 2 commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,7 @@ | |
| #include "Slice.h" | ||
| #include "pathPlanning/CombPaths.h" | ||
| #include "pathPlanning/LinePolygonsCrossings.h" | ||
| #include "settings/EnumSettings.h" // Added for CombingPolygonType | ||
| #include "sliceDataStorage.h" | ||
| #include "utils/PolygonsPointIndex.h" | ||
| #include "utils/SVG.h" | ||
|
|
@@ -101,29 +102,121 @@ bool Comb::calc( | |
| { | ||
| return true; | ||
| } | ||
|
|
||
| const CombingPolygonType combing_polygon_type = train.settings_.get<CombingPolygonType>("combing_polygon_type"); | ||
|
|
||
| // Pointers to the boundaries and related structures to be used. | ||
| // Default to the ones initialized in the constructor. | ||
| Shape* current_boundary_optimal = &boundary_inside_optimal_; | ||
| Shape* current_boundary_minimum = &boundary_inside_minimum_; | ||
| PartsView* current_parts_view_optimal = const_cast<PartsView*>(&parts_view_inside_optimal_); | ||
| PartsView* current_parts_view_minimum = const_cast<PartsView*>(&parts_view_inside_minimum_); | ||
jellespijker marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| LocToLineGrid* current_loc_to_line_optimal = inside_loc_to_line_optimal_.get(); | ||
| LocToLineGrid* current_loc_to_line_minimum = inside_loc_to_line_minimum_.get(); | ||
|
|
||
| // Local instances for when we use alternative polygons | ||
| Shape local_boundary_optimal; | ||
| Shape local_boundary_minimum; | ||
| std::unique_ptr<PartsView> local_parts_view_optimal; | ||
| std::unique_ptr<PartsView> local_parts_view_minimum; | ||
| std::unique_ptr<LocToLineGrid> local_loc_to_line_optimal; | ||
| std::unique_ptr<LocToLineGrid> local_loc_to_line_minimum; | ||
|
|
||
| bool use_original_boundaries = true; | ||
|
|
||
| // Determine if alternative boundaries are needed based on the setting | ||
| switch (combing_polygon_type) | ||
|
||
| { | ||
| case CombingPolygonType::OUTER_WALL: | ||
| // Default behavior, use original boundaries | ||
| use_original_boundaries = true; | ||
| break; | ||
| case CombingPolygonType::OUTLINE: | ||
| { | ||
| // Use the general layer outlines for combing. | ||
| // travel_avoid_supports is set to false as we are defining the combing boundary itself, not an avoidance area. | ||
| Polygons outline_polys = storage_.getLayerOutlines(layer_nr_, false, false); | ||
| if (! outline_polys.empty()) | ||
| { | ||
| local_boundary_optimal = outline_polys; // Shape can be constructed from Polygons | ||
| local_boundary_minimum = outline_polys; // Use the same for minimum | ||
| use_original_boundaries = false; | ||
| } | ||
| else | ||
| { | ||
| // No outline polygons, fall back to original boundaries (OuterWall) | ||
| use_original_boundaries = true; | ||
| } | ||
| break; | ||
| } | ||
| case CombingPolygonType::SECOND_WALL: | ||
| { | ||
| const Walls& walls = storage_.getWalls(layer_nr_, train.extruder_nr_); | ||
| if (! walls.second_wall_polys.empty()) | ||
| { | ||
| local_boundary_optimal = walls.second_wall_polys; // Shape can be constructed from PolygonsPart | ||
| local_boundary_minimum = walls.second_wall_polys; // Use second wall for both | ||
| use_original_boundaries = false; | ||
| } | ||
| else | ||
| { | ||
| // No second wall, fall back to original boundaries (OuterWall) | ||
| use_original_boundaries = true; | ||
| } | ||
| break; | ||
| } | ||
| case CombingPolygonType::PLUGIN: | ||
| // Plugin handling, assume default for now or specific logic if defined | ||
| use_original_boundaries = true; | ||
| break; | ||
| default: | ||
| // Unknown value, fall back to default behavior | ||
| use_original_boundaries = true; | ||
| break; | ||
| } | ||
|
|
||
| // If alternative boundaries are chosen and valid, set them up | ||
| if (! use_original_boundaries) | ||
| { | ||
| // Initialize local PartsView and LocToLineGrid for the selected polygons | ||
| // Note: Splitting into PartsView might reorder polygons in local_boundary_optimal/minimum | ||
| local_parts_view_optimal = std::make_unique<PartsView>(local_boundary_optimal.splitIntoPartsView()); | ||
| local_parts_view_minimum = std::make_unique<PartsView>(local_boundary_minimum.splitIntoPartsView()); | ||
| local_loc_to_line_optimal = PolygonUtils::createLocToLineGrid(local_boundary_optimal, offset_from_outlines_); | ||
| local_loc_to_line_minimum = PolygonUtils::createLocToLineGrid(local_boundary_minimum, offset_from_outlines_); | ||
|
|
||
| current_boundary_optimal = &local_boundary_optimal; | ||
| current_boundary_minimum = &local_boundary_minimum; | ||
| current_parts_view_optimal = local_parts_view_optimal.get(); | ||
| current_parts_view_minimum = local_parts_view_minimum.get(); | ||
| current_loc_to_line_optimal = local_loc_to_line_optimal.get(); | ||
| current_loc_to_line_minimum = local_loc_to_line_minimum.get(); | ||
| } | ||
|
|
||
|
|
||
| const Point2LL travel_end_point_before_combing = end_point; | ||
| // Move start and end point inside the optimal comb boundary | ||
| size_t start_inside_poly = NO_INDEX; | ||
| const bool start_inside = moveInside(boundary_inside_optimal_, _start_inside, inside_loc_to_line_optimal_.get(), start_point, start_inside_poly); | ||
| const bool start_inside = moveInside(*current_boundary_optimal, _start_inside, current_loc_to_line_optimal, start_point, start_inside_poly); | ||
|
|
||
| size_t end_inside_poly = NO_INDEX; | ||
| const bool end_inside = moveInside(boundary_inside_optimal_, _end_inside, inside_loc_to_line_optimal_.get(), end_point, end_inside_poly); | ||
| const bool end_inside = moveInside(*current_boundary_optimal, _end_inside, current_loc_to_line_optimal, end_point, end_inside_poly); | ||
|
|
||
| size_t start_part_boundary_poly_idx = NO_INDEX; // Added initial value to stop MSVC throwing an exception in debug mode | ||
| size_t start_part_boundary_poly_idx = NO_INDEX; | ||
| size_t end_part_boundary_poly_idx = NO_INDEX; | ||
| size_t start_part_idx = (start_inside_poly == NO_INDEX) ? NO_INDEX : parts_view_inside_optimal_.getPartContaining(start_inside_poly, &start_part_boundary_poly_idx); | ||
| size_t end_part_idx = (end_inside_poly == NO_INDEX) ? NO_INDEX : parts_view_inside_optimal_.getPartContaining(end_inside_poly, &end_part_boundary_poly_idx); | ||
| size_t start_part_idx = (start_inside_poly == NO_INDEX) ? NO_INDEX : current_parts_view_optimal->getPartContaining(start_inside_poly, &start_part_boundary_poly_idx); | ||
| size_t end_part_idx = (end_inside_poly == NO_INDEX) ? NO_INDEX : current_parts_view_optimal->getPartContaining(end_inside_poly, &end_part_boundary_poly_idx); | ||
|
|
||
| const bool fail_on_unavoidable_obstacles = perform_z_hops && perform_z_hops_only_when_collides; | ||
|
|
||
| // normal combing within part using optimal comb boundary | ||
| if (start_inside && end_inside && start_part_idx == end_part_idx) | ||
| { | ||
| SingleShape part = parts_view_inside_optimal_.assemblePart(start_part_idx); | ||
| SingleShape part = current_parts_view_optimal->assemblePart(start_part_idx); | ||
| comb_paths.emplace_back(); | ||
| const bool combing_succeeded = LinePolygonsCrossings::comb( | ||
| part, | ||
| *inside_loc_to_line_optimal_, | ||
| *current_loc_to_line_optimal, | ||
| start_point, | ||
| end_point, | ||
| comb_paths.back(), | ||
|
|
@@ -138,36 +231,36 @@ bool Comb::calc( | |
|
|
||
| // Move start and end point inside the minimum comb boundary | ||
| size_t start_inside_poly_min = NO_INDEX; | ||
| const bool start_inside_min = moveInside(boundary_inside_minimum_, _start_inside, inside_loc_to_line_minimum_.get(), start_point, start_inside_poly_min); | ||
| const bool start_inside_min = moveInside(*current_boundary_minimum, _start_inside, current_loc_to_line_minimum, start_point, start_inside_poly_min); | ||
|
|
||
| size_t end_inside_poly_min = NO_INDEX; | ||
| const bool end_inside_min = moveInside(boundary_inside_minimum_, _end_inside, inside_loc_to_line_minimum_.get(), end_point, end_inside_poly_min); | ||
| const bool end_inside_min = moveInside(*current_boundary_minimum, _end_inside, current_loc_to_line_minimum, end_point, end_inside_poly_min); | ||
|
|
||
| size_t start_part_boundary_poly_idx_min{}; | ||
| size_t end_part_boundary_poly_idx_min{}; | ||
| size_t start_part_idx_min | ||
| = (start_inside_poly_min == NO_INDEX) ? NO_INDEX : parts_view_inside_minimum_.getPartContaining(start_inside_poly_min, &start_part_boundary_poly_idx_min); | ||
| size_t end_part_idx_min = (end_inside_poly_min == NO_INDEX) ? NO_INDEX : parts_view_inside_minimum_.getPartContaining(end_inside_poly_min, &end_part_boundary_poly_idx_min); | ||
| = (start_inside_poly_min == NO_INDEX) ? NO_INDEX : current_parts_view_minimum->getPartContaining(start_inside_poly_min, &start_part_boundary_poly_idx_min); | ||
| size_t end_part_idx_min = (end_inside_poly_min == NO_INDEX) ? NO_INDEX : current_parts_view_minimum->getPartContaining(end_inside_poly_min, &end_part_boundary_poly_idx_min); | ||
|
|
||
| CombPath result_path; | ||
| bool comb_result; | ||
|
|
||
| // normal combing within part using minimum comb boundary | ||
| if (start_inside_min && end_inside_min && start_part_idx_min == end_part_idx_min) | ||
| { | ||
| SingleShape part = parts_view_inside_minimum_.assemblePart(start_part_idx_min); | ||
| SingleShape part = current_parts_view_minimum->assemblePart(start_part_idx_min); | ||
| comb_paths.emplace_back(); | ||
|
|
||
| comb_result = LinePolygonsCrossings::comb( | ||
| part, | ||
| *inside_loc_to_line_minimum_, | ||
| *current_loc_to_line_minimum, | ||
| start_point, | ||
| end_point, | ||
| result_path, | ||
| -offset_dist_to_get_from_on_the_polygon_to_outside_, | ||
| max_comb_distance_ignored, | ||
| fail_on_unavoidable_obstacles); | ||
| Comb::moveCombPathInside(boundary_inside_minimum_, boundary_inside_optimal_, result_path, comb_paths.back()); // add altered result_path to combPaths.back() | ||
| Comb::moveCombPathInside(*current_boundary_minimum, *current_boundary_optimal, result_path, comb_paths.back()); // add altered result_path to combPaths.back() | ||
| // If the endpoint of the travel path changes with combing, then it means that we are moving to an outer wall | ||
| // and we should unretract before the last travel move when travelling to that outer wall | ||
| unretract_before_last_travel_move = comb_result && end_point != travel_end_point_before_combing; | ||
|
|
@@ -188,12 +281,12 @@ bool Comb::calc( | |
|
|
||
| // Find the crossings using the minimum comb boundary, since it's guaranteed to be as close as we can get to the destination. | ||
| // Getting as close as possible prevents exiting the polygon in the wrong direction (e.g. into a hole instead of to the outside). | ||
| Crossing start_crossing(start_point, start_inside_min, start_part_idx_min, start_part_boundary_poly_idx_min, boundary_inside_minimum_, *inside_loc_to_line_minimum_); | ||
| Crossing end_crossing(end_point, end_inside_min, end_part_idx_min, end_part_boundary_poly_idx_min, boundary_inside_minimum_, *inside_loc_to_line_minimum_); | ||
| Crossing start_crossing(start_point, start_inside_min, start_part_idx_min, start_part_boundary_poly_idx_min, *current_boundary_minimum, *current_loc_to_line_minimum); | ||
| Crossing end_crossing(end_point, end_inside_min, end_part_idx_min, end_part_boundary_poly_idx_min, *current_boundary_minimum, *current_loc_to_line_minimum); | ||
|
|
||
| { // find crossing over the in-between area between inside and outside | ||
| start_crossing.findCrossingInOrMid(parts_view_inside_minimum_, end_point); | ||
| end_crossing.findCrossingInOrMid(parts_view_inside_minimum_, start_crossing.in_or_mid_); | ||
| start_crossing.findCrossingInOrMid(*current_parts_view_minimum, end_point); | ||
| end_crossing.findCrossingInOrMid(*current_parts_view_minimum, start_crossing.in_or_mid_); | ||
| } | ||
|
|
||
| bool skip_avoid_other_parts_path = false; | ||
|
|
@@ -228,10 +321,10 @@ bool Comb::calc( | |
| comb_paths.emplace_back(); | ||
| // If we're inside the optimal bound, first try the optimal combing path. If it fails, use the minimum path instead. | ||
| constexpr bool fail_for_optimum_bound = true; | ||
| bool combing_succeeded = start_inside | ||
| bool combing_succeeded = start_inside // Check if originally inside the optimal constructor-defined boundary | ||
| && LinePolygonsCrossings::comb( | ||
| boundary_inside_optimal_, | ||
| *inside_loc_to_line_optimal_, | ||
| *current_boundary_optimal, | ||
| *current_loc_to_line_optimal, | ||
| start_point, | ||
| start_crossing.in_or_mid_, | ||
| comb_paths.back(), | ||
|
|
@@ -240,9 +333,10 @@ bool Comb::calc( | |
| fail_for_optimum_bound); | ||
| if (! combing_succeeded) | ||
| { | ||
| // If combing with optimal failed or was skipped, try/fallback to minimum | ||
| combing_succeeded = LinePolygonsCrossings::comb( | ||
| start_crossing.dest_part_, | ||
| *inside_loc_to_line_minimum_, | ||
| start_crossing.dest_part_, // dest_part_ is from the Crossing, based on current_boundary_minimum | ||
| *current_loc_to_line_minimum, | ||
| start_point, | ||
| start_crossing.in_or_mid_, | ||
| comb_paths.back(), | ||
|
|
@@ -316,13 +410,14 @@ bool Comb::calc( | |
| { | ||
| if (start_inside == end_inside && start_part_idx == end_part_idx) | ||
| { | ||
| if (start_inside) | ||
| if (start_inside) // Check if originally inside the optimal constructor-defined boundary | ||
| { // both start and end are inside | ||
| comb_paths.back().cross_boundary = PolygonUtils::polygonCollidesWithLineSegment(start_point, end_point, *inside_loc_to_line_optimal_); | ||
| comb_paths.back().cross_boundary = PolygonUtils::polygonCollidesWithLineSegment(start_point, end_point, *current_loc_to_line_optimal); | ||
| } | ||
| else | ||
| { // both start and end are outside | ||
| comb_paths.back().cross_boundary = PolygonUtils::polygonCollidesWithLineSegment(start_point, end_point, getModelBoundaryLocToLine(train)); | ||
| comb_paths.back().cross_boundary | ||
| = PolygonUtils::polygonCollidesWithLineSegment(start_point, end_point, getModelBoundaryLocToLine(train)); // Uses original model boundary logic | ||
| } | ||
| } | ||
| else | ||
|
|
@@ -331,17 +426,17 @@ bool Comb::calc( | |
| } | ||
| } | ||
|
|
||
| if (end_inside) | ||
| if (end_inside_min) // check end_inside_min as this refers to the current boundary (original or local) | ||
| { | ||
| // boundary to end | ||
| assert(end_crossing.dest_part_.size() > 0 && "The part we end up inside when combing should have been computed already!"); | ||
| comb_paths.emplace_back(); | ||
| // If we're inside the optimal bound, first try the optimal combing path. If it fails, use the minimum path instead. | ||
| constexpr bool fail_for_optimum_bound = true; | ||
| bool combing_succeeded = end_inside | ||
| bool combing_succeeded = end_inside // Check if originally inside the optimal constructor-defined boundary | ||
| && LinePolygonsCrossings::comb( | ||
| boundary_inside_optimal_, | ||
| *inside_loc_to_line_optimal_, | ||
| *current_boundary_optimal, | ||
| *current_loc_to_line_optimal, | ||
| end_crossing.in_or_mid_, | ||
| end_point, | ||
| comb_paths.back(), | ||
|
|
@@ -350,9 +445,10 @@ bool Comb::calc( | |
| fail_for_optimum_bound); | ||
| if (! combing_succeeded) | ||
| { | ||
| // If combing with optimal failed or was skipped, try/fallback to minimum | ||
| combing_succeeded = LinePolygonsCrossings::comb( | ||
| end_crossing.dest_part_, | ||
| *inside_loc_to_line_minimum_, | ||
| end_crossing.dest_part_, // dest_part_ is from the Crossing, based on current_boundary_minimum | ||
| *current_loc_to_line_minimum, | ||
| end_crossing.in_or_mid_, | ||
| end_point, | ||
| comb_paths.back(), | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.