Wrap `Board` in `NavmesherBoard`

This commit is contained in:
Mikolaj Wielgus 2026-03-11 10:26:23 +01:00
parent a8e14753d9
commit 09e1e35151
5 changed files with 66 additions and 16 deletions

View File

@ -33,7 +33,8 @@ impl Displayer {
) { ) {
ui.painter().line( ui.painter().line(
workspace workspace
.board .navmesher_board
.board()
.layout() .layout()
.boundary() .boundary()
.iter() .iter()
@ -45,7 +46,13 @@ impl Displayer {
egui::Stroke::new(5.0 / viewport.scale_factor(), egui::Color32::WHITE), egui::Stroke::new(5.0 / viewport.scale_factor(), egui::Color32::WHITE),
); );
for (_, joint) in workspace.board.layout().joints().collection() { for (_, joint) in workspace
.navmesher_board
.board()
.layout()
.joints()
.collection()
{
if workspace.appearance_panel.visible[joint.layer] { if workspace.appearance_panel.visible[joint.layer] {
self.paint_joint( self.paint_joint(
ctx, ctx,
@ -56,13 +63,19 @@ impl Displayer {
.appearance_panel .appearance_panel
.colors(ctx) .colors(ctx)
.layers .layers
.color(workspace.board.layer_name(joint.layer)) .color(workspace.navmesher_board.board().layer_name(joint.layer))
.normal, .normal,
); );
} }
} }
for (i, segment) in workspace.board.layout().segments().collection() { for (i, segment) in workspace
.navmesher_board
.board()
.layout()
.segments()
.collection()
{
if workspace.appearance_panel.visible[segment.layer] { if workspace.appearance_panel.visible[segment.layer] {
self.paint_segment( self.paint_segment(
ctx, ctx,
@ -70,20 +83,27 @@ impl Displayer {
viewport, viewport,
segment, segment,
workspace workspace
.board .navmesher_board
.board()
.layout() .layout()
.segment_endpoints(SegmentId::new(i)), .segment_endpoints(SegmentId::new(i)),
workspace workspace
.appearance_panel .appearance_panel
.colors(ctx) .colors(ctx)
.layers .layers
.color(workspace.board.layer_name(segment.layer)) .color(workspace.navmesher_board.board().layer_name(segment.layer))
.normal, .normal,
); );
} }
} }
for (_, polygon) in workspace.board.layout().polygons().collection() { for (_, polygon) in workspace
.navmesher_board
.board()
.layout()
.polygons()
.collection()
{
if workspace.appearance_panel.visible[polygon.layer] { if workspace.appearance_panel.visible[polygon.layer] {
self.paint_polygon( self.paint_polygon(
ctx, ctx,
@ -94,7 +114,7 @@ impl Displayer {
.appearance_panel .appearance_panel
.colors(ctx) .colors(ctx)
.layers .layers
.color(workspace.board.layer_name(polygon.layer)) .color(workspace.navmesher_board.board().layer_name(polygon.layer))
.normal, .normal,
); );
} }

View File

@ -52,14 +52,14 @@ impl Viewport {
} }
fn boundary_bounding_box(workspace: &Workspace) -> egui::Rect { fn boundary_bounding_box(workspace: &Workspace) -> egui::Rect {
let first = workspace.board.layout().boundary()[0]; let first = workspace.navmesher_board.board().layout().boundary()[0];
let mut min_x = first[0]; let mut min_x = first[0];
let mut max_x = first[0]; let mut max_x = first[0];
let mut min_y = first[1]; let mut min_y = first[1];
let mut max_y = first[1]; let mut max_y = first[1];
for point in workspace.board.layout().boundary()[1..].iter() { for point in workspace.navmesher_board.board().layout().boundary()[1..].iter() {
if point[0] < min_x { if point[0] < min_x {
min_x = point[0]; min_x = point[0];
} }

View File

@ -2,12 +2,12 @@
// //
// SPDX-License-Identifier: MIT OR Apache-2.0 // SPDX-License-Identifier: MIT OR Apache-2.0
use topola::Board; use topola::{Board, NavmesherBoard};
use crate::{appearance_panel::AppearancePanel, translator::Translator}; use crate::{appearance_panel::AppearancePanel, translator::Translator};
pub struct Workspace { pub struct Workspace {
pub board: Board, pub navmesher_board: NavmesherBoard,
pub appearance_panel: AppearancePanel, pub appearance_panel: AppearancePanel,
} }
@ -16,12 +16,13 @@ impl Workspace {
let appearance_panel = AppearancePanel::new(&board); let appearance_panel = AppearancePanel::new(&board);
Self { Self {
board, navmesher_board: NavmesherBoard::with_board(board),
appearance_panel, appearance_panel,
} }
} }
pub fn update_appearance_panel(&mut self, ctx: &egui::Context) { pub fn update_appearance_panel(&mut self, ctx: &egui::Context) {
self.appearance_panel.update(ctx, &self.board); self.appearance_panel
.update(ctx, &self.navmesher_board.board());
} }
} }

View File

@ -12,3 +12,4 @@ pub use crate::board::Board;
pub use crate::layout::{ pub use crate::layout::{
Joint, JointId, Layout, Polygon, PolygonId, Segment, SegmentId, Via, ViaId, Joint, JointId, Layout, Polygon, PolygonId, Segment, SegmentId, Via, ViaId,
}; };
pub use crate::navmesher::NavmesherBoard;

View File

@ -17,6 +17,13 @@ pub struct LayerNavmesher {
} }
impl LayerNavmesher { impl LayerNavmesher {
pub fn new() -> Self {
Self {
navmeshes: Vec::new(),
inflation_factors: Vec::new(),
}
}
pub fn insert_polygon(&mut self, polygon: impl IntoIterator<Item = [i64; 2]>) { pub fn insert_polygon(&mut self, polygon: impl IntoIterator<Item = [i64; 2]>) {
let polygon: Vec<[i64; 2]> = polygon.into_iter().collect(); let polygon: Vec<[i64; 2]> = polygon.into_iter().collect();
@ -67,6 +74,14 @@ pub struct Navmesher {
} }
impl Navmesher { impl Navmesher {
pub fn new(layer_count: usize) -> Self {
Self {
layers: std::iter::repeat_with(LayerNavmesher::new)
.take(layer_count)
.collect(),
}
}
pub fn insert_polygon(&mut self, layer: usize, polygon: impl IntoIterator<Item = [i64; 2]>) { pub fn insert_polygon(&mut self, layer: usize, polygon: impl IntoIterator<Item = [i64; 2]>) {
self.layers[layer].insert_polygon(polygon); self.layers[layer].insert_polygon(polygon);
} }
@ -79,12 +94,25 @@ pub struct NavmesherBoard {
} }
impl NavmesherBoard { impl NavmesherBoard {
pub fn with_board(board: Board) -> Self {
let mut navmesher = Navmesher::new(*board.layout().layer_count());
for (_, joint) in board.layout().joints().collection() {
Self::insert_joint_in_navmesher(&mut navmesher, *joint);
}
Self { navmesher, board }
}
pub fn insert_joint(&mut self, joint: Joint) -> JointId { pub fn insert_joint(&mut self, joint: Joint) -> JointId {
self.navmesher Self::insert_joint_in_navmesher(&mut self.navmesher, joint);
.insert_polygon(joint.layer, Self::joint_circumscribed_octagon(joint));
self.board.add_joint(joint) self.board.add_joint(joint)
} }
fn insert_joint_in_navmesher(navmesher: &mut Navmesher, joint: Joint) {
navmesher.insert_polygon(joint.layer, Self::joint_circumscribed_octagon(joint));
}
fn joint_circumscribed_octagon(joint: Joint) -> [[i64; 2]; 8] { fn joint_circumscribed_octagon(joint: Joint) -> [[i64; 2]; 8] {
let cx = joint.position[0]; let cx = joint.position[0];
let cy = joint.position[1]; let cy = joint.position[1];