mirror of https://codeberg.org/topola/topola.git
Rename `NavmesherBoard` to `Autorouter`, move it to own file
This commit is contained in:
parent
7f4d3eb420
commit
07427a3831
|
|
@ -23,9 +23,10 @@ impl Display {
|
||||||
self.display_layout(ctx, ui, /*menu_bar,*/ viewport, workspace);
|
self.display_layout(ctx, ui, /*menu_bar,*/ viewport, workspace);
|
||||||
self.display_bboxes(ctx, ui, viewport, workspace);
|
self.display_bboxes(ctx, ui, viewport, workspace);
|
||||||
self.display_navmeshes(ctx, ui, viewport, workspace);
|
self.display_navmeshes(ctx, ui, viewport, workspace);
|
||||||
|
//self.display_ratsnest(ctx, ui, viewport, workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn display_layout(
|
fn display_layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &egui::Context,
|
ctx: &egui::Context,
|
||||||
ui: &egui::Ui,
|
ui: &egui::Ui,
|
||||||
|
|
@ -35,7 +36,7 @@ impl Display {
|
||||||
) {
|
) {
|
||||||
ui.painter().line(
|
ui.painter().line(
|
||||||
workspace
|
workspace
|
||||||
.navmesher_board
|
.autorouter
|
||||||
.board()
|
.board()
|
||||||
.layout()
|
.layout()
|
||||||
.boundary()
|
.boundary()
|
||||||
|
|
@ -48,13 +49,7 @@ impl Display {
|
||||||
egui::Stroke::new(5.0 / viewport.scale_factor(), egui::Color32::WHITE),
|
egui::Stroke::new(5.0 / viewport.scale_factor(), egui::Color32::WHITE),
|
||||||
);
|
);
|
||||||
|
|
||||||
for (joint_index, joint) in workspace
|
for (joint_index, joint) in workspace.autorouter.board().layout().joints().collection() {
|
||||||
.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,
|
||||||
|
|
@ -63,21 +58,18 @@ impl Display {
|
||||||
joint,
|
joint,
|
||||||
workspace.appearance_panel.layer_color(
|
workspace.appearance_panel.layer_color(
|
||||||
ctx,
|
ctx,
|
||||||
workspace.navmesher_board.board().layer_name(joint.layer),
|
workspace.autorouter.board().layer_name(joint.layer),
|
||||||
workspace
|
workspace.autorouter.board().pin_selection_contains_joint(
|
||||||
.navmesher_board
|
&workspace.pin_selection,
|
||||||
.board()
|
JointId::new(joint_index),
|
||||||
.pin_selection_contains_joint(
|
),
|
||||||
&workspace.pin_selection,
|
|
||||||
JointId::new(joint_index),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (segment_index, segment) in workspace
|
for (segment_index, segment) in workspace
|
||||||
.navmesher_board
|
.autorouter
|
||||||
.board()
|
.board()
|
||||||
.layout()
|
.layout()
|
||||||
.segments()
|
.segments()
|
||||||
|
|
@ -90,20 +82,17 @@ impl Display {
|
||||||
viewport,
|
viewport,
|
||||||
segment,
|
segment,
|
||||||
workspace
|
workspace
|
||||||
.navmesher_board
|
.autorouter
|
||||||
.board()
|
.board()
|
||||||
.layout()
|
.layout()
|
||||||
.segment_endpoints(SegmentId::new(segment_index)),
|
.segment_endpoints(SegmentId::new(segment_index)),
|
||||||
workspace.appearance_panel.layer_color(
|
workspace.appearance_panel.layer_color(
|
||||||
ctx,
|
ctx,
|
||||||
workspace.navmesher_board.board().layer_name(segment.layer),
|
workspace.autorouter.board().layer_name(segment.layer),
|
||||||
workspace
|
workspace.autorouter.board().pin_selection_contains_segment(
|
||||||
.navmesher_board
|
&workspace.pin_selection,
|
||||||
.board()
|
SegmentId::new(segment_index),
|
||||||
.pin_selection_contains_segment(
|
),
|
||||||
&workspace.pin_selection,
|
|
||||||
SegmentId::new(segment_index),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +101,7 @@ impl Display {
|
||||||
// TODO: Vias.
|
// TODO: Vias.
|
||||||
|
|
||||||
for (polygon_index, polygon) in workspace
|
for (polygon_index, polygon) in workspace
|
||||||
.navmesher_board
|
.autorouter
|
||||||
.board()
|
.board()
|
||||||
.layout()
|
.layout()
|
||||||
.polygons()
|
.polygons()
|
||||||
|
|
@ -126,14 +115,11 @@ impl Display {
|
||||||
polygon,
|
polygon,
|
||||||
workspace.appearance_panel.layer_color(
|
workspace.appearance_panel.layer_color(
|
||||||
ctx,
|
ctx,
|
||||||
workspace.navmesher_board.board().layer_name(polygon.layer),
|
workspace.autorouter.board().layer_name(polygon.layer),
|
||||||
workspace
|
workspace.autorouter.board().pin_selection_contains_polygon(
|
||||||
.navmesher_board
|
&workspace.pin_selection,
|
||||||
.board()
|
PolygonId::new(polygon_index),
|
||||||
.pin_selection_contains_polygon(
|
),
|
||||||
&workspace.pin_selection,
|
|
||||||
PolygonId::new(polygon_index),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -201,13 +187,7 @@ impl Display {
|
||||||
viewport: &Viewport,
|
viewport: &Viewport,
|
||||||
workspace: &Workspace,
|
workspace: &Workspace,
|
||||||
) {
|
) {
|
||||||
for (_, joint) in workspace
|
for (_, joint) in workspace.autorouter.board().layout().joints().collection() {
|
||||||
.navmesher_board
|
|
||||||
.board()
|
|
||||||
.layout()
|
|
||||||
.joints()
|
|
||||||
.collection()
|
|
||||||
{
|
|
||||||
if workspace.appearance_panel.visible[joint.layer] {
|
if workspace.appearance_panel.visible[joint.layer] {
|
||||||
ui.painter().rect_stroke(
|
ui.painter().rect_stroke(
|
||||||
egui::Rect {
|
egui::Rect {
|
||||||
|
|
@ -228,7 +208,7 @@ impl Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, segment) in workspace
|
for (i, segment) in workspace
|
||||||
.navmesher_board
|
.autorouter
|
||||||
.board()
|
.board()
|
||||||
.layout()
|
.layout()
|
||||||
.segments()
|
.segments()
|
||||||
|
|
@ -236,7 +216,7 @@ impl Display {
|
||||||
{
|
{
|
||||||
if workspace.appearance_panel.visible[segment.layer] {
|
if workspace.appearance_panel.visible[segment.layer] {
|
||||||
let endpoints = workspace
|
let endpoints = workspace
|
||||||
.navmesher_board
|
.autorouter
|
||||||
.board()
|
.board()
|
||||||
.layout()
|
.layout()
|
||||||
.segment_endpoints(SegmentId::new(i));
|
.segment_endpoints(SegmentId::new(i));
|
||||||
|
|
@ -256,7 +236,7 @@ impl Display {
|
||||||
// TODO: vias.
|
// TODO: vias.
|
||||||
|
|
||||||
for (i, polygon) in workspace
|
for (i, polygon) in workspace
|
||||||
.navmesher_board
|
.autorouter
|
||||||
.board()
|
.board()
|
||||||
.layout()
|
.layout()
|
||||||
.polygons()
|
.polygons()
|
||||||
|
|
@ -285,10 +265,10 @@ impl Display {
|
||||||
viewport: &Viewport,
|
viewport: &Viewport,
|
||||||
workspace: &Workspace,
|
workspace: &Workspace,
|
||||||
) {
|
) {
|
||||||
for layer in 0..*workspace.navmesher_board.board().layout().layer_count() {
|
for layer in 0..*workspace.autorouter.board().layout().layer_count() {
|
||||||
if workspace.appearance_panel.visible[layer] {
|
if workspace.appearance_panel.visible[layer] {
|
||||||
for navmesh in
|
for navmesh in
|
||||||
workspace.navmesher_board.navmesher().layer_navmeshers()[layer].navmeshes()
|
workspace.autorouter.navmesher().layer_navmeshers()[layer].navmeshes()
|
||||||
{
|
{
|
||||||
for edge_geom in navmesh
|
for edge_geom in navmesh
|
||||||
.triangulation()
|
.triangulation()
|
||||||
|
|
@ -335,4 +315,13 @@ impl Display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn display_ratsnest(
|
||||||
|
ctx: &egui::Context,
|
||||||
|
ui: &egui::Ui,
|
||||||
|
viewport: &Viewport,
|
||||||
|
workspace: &Workspace,
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ impl Viewport {
|
||||||
|
|
||||||
if response.clicked() {
|
if response.clicked() {
|
||||||
if let Some(pin_selector) =
|
if let Some(pin_selector) =
|
||||||
workspace.navmesher_board.board().point_pin_selector(
|
workspace.autorouter.board().point_pin_selector(
|
||||||
0,
|
0,
|
||||||
Vector2::new(
|
Vector2::new(
|
||||||
pointer_scene_pos.x as i64,
|
pointer_scene_pos.x as i64,
|
||||||
|
|
@ -113,14 +113,14 @@ impl Viewport {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn boundary_bounding_box(workspace: &Workspace) -> egui::Rect {
|
fn boundary_bounding_box(workspace: &Workspace) -> egui::Rect {
|
||||||
let first = workspace.navmesher_board.board().layout().boundary()[0];
|
let first = workspace.autorouter.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.navmesher_board.board().layout().boundary()[1..].iter() {
|
for point in workspace.autorouter.board().layout().boundary()[1..].iter() {
|
||||||
if point[0] < min_x {
|
if point[0] < min_x {
|
||||||
min_x = point[0];
|
min_x = point[0];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,12 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
use topola::{Board, NavmesherBoard, PinSelection};
|
use topola::{Autorouter, Board, PinSelection};
|
||||||
|
|
||||||
use crate::{appearance_panel::AppearancePanel, translator::Translator};
|
use crate::{appearance_panel::AppearancePanel, translator::Translator};
|
||||||
|
|
||||||
pub struct Workspace {
|
pub struct Workspace {
|
||||||
pub navmesher_board: NavmesherBoard,
|
pub autorouter: Autorouter,
|
||||||
pub appearance_panel: AppearancePanel,
|
pub appearance_panel: AppearancePanel,
|
||||||
pub pin_selection: PinSelection,
|
pub pin_selection: PinSelection,
|
||||||
}
|
}
|
||||||
|
|
@ -17,14 +17,13 @@ impl Workspace {
|
||||||
let appearance_panel = AppearancePanel::new(&board);
|
let appearance_panel = AppearancePanel::new(&board);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
navmesher_board: NavmesherBoard::with_board(board),
|
autorouter: Autorouter::with_board(board),
|
||||||
appearance_panel,
|
appearance_panel,
|
||||||
pin_selection: PinSelection::new(),
|
pin_selection: PinSelection::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_appearance_panel(&mut self, ctx: &egui::Context) {
|
pub fn update_appearance_panel(&mut self, ctx: &egui::Context) {
|
||||||
self.appearance_panel
|
self.appearance_panel.update(ctx, &self.autorouter.board());
|
||||||
.update(ctx, &self.navmesher_board.board());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
|
use derive_getters::Getters;
|
||||||
|
use undoredo::Recorder;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
Board, Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Vector2, Via, ViaId,
|
||||||
|
navmesher::{MultiObstacleId, Navmesher},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Getters)]
|
||||||
|
pub struct Autorouter {
|
||||||
|
navmesher: Navmesher,
|
||||||
|
board: Board,
|
||||||
|
|
||||||
|
joint_multiobstacles: Recorder<Vec<MultiObstacleId>>,
|
||||||
|
segment_multiobstacles: Recorder<Vec<MultiObstacleId>>,
|
||||||
|
polygon_multiobstacles: Recorder<Vec<MultiObstacleId>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Autorouter {
|
||||||
|
pub fn with_board(board: Board) -> Self {
|
||||||
|
let mut this = Self {
|
||||||
|
navmesher: Navmesher::new(
|
||||||
|
board
|
||||||
|
.layout()
|
||||||
|
.boundary()
|
||||||
|
.iter()
|
||||||
|
.map(|p| Vector2::new(p[0], p[1])),
|
||||||
|
*board.layout().layer_count(),
|
||||||
|
),
|
||||||
|
board,
|
||||||
|
|
||||||
|
joint_multiobstacles: Recorder::new(Vec::new()),
|
||||||
|
segment_multiobstacles: Recorder::new(Vec::new()),
|
||||||
|
polygon_multiobstacles: Recorder::new(Vec::new()),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i, joint) in this.board.layout().joints().collection() {
|
||||||
|
this.joint_multiobstacles.insert(
|
||||||
|
i,
|
||||||
|
this.navmesher
|
||||||
|
.insert_multiobstacle(joint.layer, Self::joint_bounding_octagon(*joint)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, segment) in this.board.layout().segments().collection() {
|
||||||
|
this.segment_multiobstacles.insert(
|
||||||
|
i,
|
||||||
|
this.navmesher.insert_multiobstacle(
|
||||||
|
segment.layer,
|
||||||
|
this.segment_bounding_rectangle(SegmentId::new(i), *segment),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, polygon) in this.board.layout().polygons().collection() {
|
||||||
|
this.polygon_multiobstacles.insert(
|
||||||
|
i,
|
||||||
|
this.navmesher
|
||||||
|
.insert_multiobstacle(polygon.layer, polygon.vertices.clone()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_joint(&mut self, joint: Joint) -> JointId {
|
||||||
|
let joint_id = self.board.add_joint(joint);
|
||||||
|
self.joint_multiobstacles.insert(
|
||||||
|
joint_id.index(),
|
||||||
|
self.navmesher
|
||||||
|
.insert_multiobstacle(joint.layer, Self::joint_bounding_octagon(joint)),
|
||||||
|
);
|
||||||
|
|
||||||
|
joint_id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn joint_bounding_octagon(joint: Joint) -> [Vector2<i64>; 8] {
|
||||||
|
let cx = joint.position.x;
|
||||||
|
let cy = joint.position.y;
|
||||||
|
let r = joint.radius as i64;
|
||||||
|
|
||||||
|
[
|
||||||
|
Vector2::new(cx + r, cy + r / 2),
|
||||||
|
Vector2::new(cx + r / 2, cy + r),
|
||||||
|
Vector2::new(cx - r / 2, cy + r),
|
||||||
|
Vector2::new(cx - r, cy + r / 2),
|
||||||
|
Vector2::new(cx - r, cy - r / 2),
|
||||||
|
Vector2::new(cx - r / 2, cy - r),
|
||||||
|
Vector2::new(cx + r / 2, cy - r),
|
||||||
|
Vector2::new(cx + r, cy - r / 2),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_segment(&mut self, segment: Segment) -> SegmentId {
|
||||||
|
let segment_id = self.board.add_segment(segment);
|
||||||
|
self.segment_multiobstacles.insert(
|
||||||
|
segment_id.index(),
|
||||||
|
self.navmesher.insert_multiobstacle(
|
||||||
|
segment.layer,
|
||||||
|
self.segment_bounding_rectangle(segment_id, segment),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
segment_id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn segment_bounding_rectangle(
|
||||||
|
&self,
|
||||||
|
segment_id: SegmentId,
|
||||||
|
segment: Segment,
|
||||||
|
) -> [Vector2<i64>; 4] {
|
||||||
|
let endpoints = self.board.layout().segment_endpoints(segment_id);
|
||||||
|
crate::math::inflated_segment(
|
||||||
|
endpoints[0].x,
|
||||||
|
endpoints[0].y,
|
||||||
|
endpoints[1].x,
|
||||||
|
endpoints[1].y,
|
||||||
|
segment.half_width,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_via(&mut self, via: Via) -> ViaId {
|
||||||
|
// TODO: Insert into navmesh.
|
||||||
|
self.board.add_via(via)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||||
|
let polygon_id = self.board.add_polygon(polygon.clone());
|
||||||
|
self.polygon_multiobstacles.insert(
|
||||||
|
polygon_id.index(),
|
||||||
|
self.navmesher
|
||||||
|
.insert_multiobstacle(polygon.layer, polygon.vertices),
|
||||||
|
);
|
||||||
|
|
||||||
|
polygon_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
|
mod autorouter;
|
||||||
mod board;
|
mod board;
|
||||||
mod layout;
|
mod layout;
|
||||||
mod math;
|
mod math;
|
||||||
|
|
@ -11,10 +12,10 @@ mod ratsnest;
|
||||||
mod selection;
|
mod selection;
|
||||||
mod specctra;
|
mod specctra;
|
||||||
|
|
||||||
|
pub use crate::autorouter::Autorouter;
|
||||||
pub use crate::board::Board;
|
pub use crate::board::Board;
|
||||||
pub use crate::layout::Layout;
|
pub use crate::layout::Layout;
|
||||||
pub use crate::math::Vector2;
|
pub use crate::math::Vector2;
|
||||||
pub use crate::navmesher::NavmesherBoard;
|
|
||||||
pub use crate::primitives::{
|
pub use crate::primitives::{
|
||||||
Joint, JointId, Polygon, PolygonId, PrimitiveId, Segment, SegmentId, Via, ViaId,
|
Joint, JointId, Polygon, PolygonId, PrimitiveId, Segment, SegmentId, Via, ViaId,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,8 @@ use dearcut::{RecordingTriangulator, VertexId};
|
||||||
use derive_getters::Getters;
|
use derive_getters::Getters;
|
||||||
use derive_more::Constructor;
|
use derive_more::Constructor;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use undoredo::Recorder;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::Vector2;
|
||||||
Board, Vector2, math,
|
|
||||||
primitives::{Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Via, ViaId},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
||||||
|
|
@ -173,133 +169,3 @@ impl Navmesher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Getters)]
|
|
||||||
pub struct NavmesherBoard {
|
|
||||||
navmesher: Navmesher,
|
|
||||||
board: Board,
|
|
||||||
|
|
||||||
joint_multiobstacles: Recorder<Vec<MultiObstacleId>>,
|
|
||||||
segment_multiobstacles: Recorder<Vec<MultiObstacleId>>,
|
|
||||||
polygon_multiobstacles: Recorder<Vec<MultiObstacleId>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NavmesherBoard {
|
|
||||||
pub fn with_board(board: Board) -> Self {
|
|
||||||
let mut this = Self {
|
|
||||||
navmesher: Navmesher::new(
|
|
||||||
board
|
|
||||||
.layout()
|
|
||||||
.boundary()
|
|
||||||
.iter()
|
|
||||||
.map(|p| Vector2::new(p[0], p[1])),
|
|
||||||
*board.layout().layer_count(),
|
|
||||||
),
|
|
||||||
board,
|
|
||||||
|
|
||||||
joint_multiobstacles: Recorder::new(Vec::new()),
|
|
||||||
segment_multiobstacles: Recorder::new(Vec::new()),
|
|
||||||
polygon_multiobstacles: Recorder::new(Vec::new()),
|
|
||||||
};
|
|
||||||
|
|
||||||
for (i, joint) in this.board.layout().joints().collection() {
|
|
||||||
this.joint_multiobstacles.insert(
|
|
||||||
i,
|
|
||||||
this.navmesher
|
|
||||||
.insert_multiobstacle(joint.layer, Self::joint_bounding_octagon(*joint)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i, segment) in this.board.layout().segments().collection() {
|
|
||||||
this.segment_multiobstacles.insert(
|
|
||||||
i,
|
|
||||||
this.navmesher.insert_multiobstacle(
|
|
||||||
segment.layer,
|
|
||||||
this.segment_bounding_rectangle(SegmentId::new(i), *segment),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i, polygon) in this.board.layout().polygons().collection() {
|
|
||||||
this.polygon_multiobstacles.insert(
|
|
||||||
i,
|
|
||||||
this.navmesher
|
|
||||||
.insert_multiobstacle(polygon.layer, polygon.vertices.clone()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_joint(&mut self, joint: Joint) -> JointId {
|
|
||||||
let joint_id = self.board.add_joint(joint);
|
|
||||||
self.joint_multiobstacles.insert(
|
|
||||||
joint_id.index(),
|
|
||||||
self.navmesher
|
|
||||||
.insert_multiobstacle(joint.layer, Self::joint_bounding_octagon(joint)),
|
|
||||||
);
|
|
||||||
|
|
||||||
joint_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn joint_bounding_octagon(joint: Joint) -> [Vector2<i64>; 8] {
|
|
||||||
let cx = joint.position.x;
|
|
||||||
let cy = joint.position.y;
|
|
||||||
let r = joint.radius as i64;
|
|
||||||
|
|
||||||
[
|
|
||||||
Vector2::new(cx + r, cy + r / 2),
|
|
||||||
Vector2::new(cx + r / 2, cy + r),
|
|
||||||
Vector2::new(cx - r / 2, cy + r),
|
|
||||||
Vector2::new(cx - r, cy + r / 2),
|
|
||||||
Vector2::new(cx - r, cy - r / 2),
|
|
||||||
Vector2::new(cx - r / 2, cy - r),
|
|
||||||
Vector2::new(cx + r / 2, cy - r),
|
|
||||||
Vector2::new(cx + r, cy - r / 2),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_segment(&mut self, segment: Segment) -> SegmentId {
|
|
||||||
let segment_id = self.board.add_segment(segment);
|
|
||||||
self.segment_multiobstacles.insert(
|
|
||||||
segment_id.index(),
|
|
||||||
self.navmesher.insert_multiobstacle(
|
|
||||||
segment.layer,
|
|
||||||
self.segment_bounding_rectangle(segment_id, segment),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
segment_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn segment_bounding_rectangle(
|
|
||||||
&self,
|
|
||||||
segment_id: SegmentId,
|
|
||||||
segment: Segment,
|
|
||||||
) -> [Vector2<i64>; 4] {
|
|
||||||
let endpoints = self.board.layout().segment_endpoints(segment_id);
|
|
||||||
math::inflated_segment(
|
|
||||||
endpoints[0].x,
|
|
||||||
endpoints[0].y,
|
|
||||||
endpoints[1].x,
|
|
||||||
endpoints[1].y,
|
|
||||||
segment.half_width,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_via(&mut self, via: Via) -> ViaId {
|
|
||||||
// TODO: Insert into navmesh.
|
|
||||||
self.board.add_via(via)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
|
||||||
let polygon_id = self.board.add_polygon(polygon.clone());
|
|
||||||
self.polygon_multiobstacles.insert(
|
|
||||||
polygon_id.index(),
|
|
||||||
self.navmesher
|
|
||||||
.insert_multiobstacle(polygon.layer, polygon.vertices),
|
|
||||||
);
|
|
||||||
|
|
||||||
polygon_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue