-
-
Notifications
You must be signed in to change notification settings - Fork 233
Add support for forbidden zones #731
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # Code for handling forbidden zones of movements | ||
| # | ||
| # Copyright (C) 2025 Daniel Berlin <dberlin@dberlin.org> | ||
| # | ||
| # This file may be distributed under the terms of the GNU GPLv3 license. | ||
|
|
||
| from shapely import from_wkt, STRtree, LineString | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be lazy-loaded if
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto |
||
| import logging | ||
|
|
||
| class ForbiddenZones: | ||
| # On init we just read in the shapes and prepare the STRtree | ||
| def __init__(self, config): | ||
| self.forbidden_zone_tree = None | ||
| if config.has_section("forbidden_zones"): | ||
| section = config.getsection("forbidden_zones") | ||
| forbidden_shapes_wkt = section.getlists("shapes", seps=("\n")) | ||
| logging.info(f"Forbidden zone shapes (WKT):{forbidden_shapes_wkt}") | ||
| forbidden_shapes_wkt = [shape.strip() for shape in forbidden_shapes_wkt if len(shape.strip()) != 0] | ||
| forbidden_shapes = [from_wkt(shape) for shape in forbidden_shapes_wkt] | ||
| logging.info(f"Forbidden zone shapes (parsed):{forbidden_shapes}") | ||
| self.forbidden_zone_tree = STRtree(forbidden_shapes) | ||
|
|
||
| # Check whether a proposed line move intersects any forbidden zone shapes | ||
| # Touching the shape counts (So a point that is on the border of a shape is not allowed) | ||
| def check_move(self, move): | ||
| if self.forbidden_zone_tree: | ||
| # Transform the move into a shapely LineString, get candidates from the STRtree | ||
| # and check each candidate for intersection | ||
| x_y_line = LineString([move.start_pos[:2], move.end_pos[:2]]) | ||
| candidates = self.forbidden_zone_tree.query(x_y_line, predicate='intersects') | ||
| if len(candidates) > 0: | ||
| for geom_index in candidates: | ||
| geom = self.forbidden_zone_tree.geometries.take(geom_index) | ||
| if x_y_line.intersects(geom): | ||
| raise move.move_error(f"Move line {x_y_line} intersects forbidden zone shape {geom}") | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should move in to the toolhead so all kinematics benefit. Toolhead calls
check_move, so the forbidden_zones check_move can go right before that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, i'm on it.