mirror of https://codeberg.org/topola/topola.git
layout: move pin information to a new parent object, `Board`
This commit is contained in:
parent
b22e3dce1a
commit
de17adb01c
|
|
@ -14,6 +14,7 @@ use thiserror::Error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
autorouter::{
|
autorouter::{
|
||||||
|
board::Board,
|
||||||
ratsnest::{Ratsnest, RatsnestVertexIndex},
|
ratsnest::{Ratsnest, RatsnestVertexIndex},
|
||||||
selection::Selection,
|
selection::Selection,
|
||||||
},
|
},
|
||||||
|
|
@ -22,7 +23,7 @@ use crate::{
|
||||||
graph::{GetLayer, GetMaybeNet},
|
graph::{GetLayer, GetMaybeNet},
|
||||||
rules::RulesTrait,
|
rules::RulesTrait,
|
||||||
},
|
},
|
||||||
layout::{Layout, NodeIndex},
|
layout::Layout,
|
||||||
router::{
|
router::{
|
||||||
navmesh::{Navmesh, NavmeshError},
|
navmesh::{Navmesh, NavmeshError},
|
||||||
Router, RouterError, RouterObserverTrait,
|
Router, RouterError, RouterObserverTrait,
|
||||||
|
|
@ -63,7 +64,7 @@ impl Autoroute {
|
||||||
};
|
};
|
||||||
|
|
||||||
let (source, target) = Self::ratline_endpoints(autorouter, cur_ratline);
|
let (source, target) = Self::ratline_endpoints(autorouter, cur_ratline);
|
||||||
let navmesh = Some(Navmesh::new(&autorouter.layout, source, target)?);
|
let navmesh = Some(Navmesh::new(autorouter.board.layout(), source, target)?);
|
||||||
|
|
||||||
let this = Self {
|
let this = Self {
|
||||||
ratlines_iter,
|
ratlines_iter,
|
||||||
|
|
@ -84,7 +85,7 @@ impl Autoroute {
|
||||||
|
|
||||||
(
|
(
|
||||||
Some(
|
Some(
|
||||||
Navmesh::new(&autorouter.layout, source, target)
|
Navmesh::new(autorouter.board.layout(), source, target)
|
||||||
.ok()
|
.ok()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
),
|
||||||
|
|
@ -95,7 +96,7 @@ impl Autoroute {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut router = Router::new_from_navmesh(
|
let mut router = Router::new_from_navmesh(
|
||||||
&mut autorouter.layout,
|
autorouter.board.layout_mut(),
|
||||||
std::mem::replace(&mut self.navmesh, new_navmesh).unwrap(),
|
std::mem::replace(&mut self.navmesh, new_navmesh).unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -130,7 +131,7 @@ impl Autoroute {
|
||||||
.vertex_index()
|
.vertex_index()
|
||||||
{
|
{
|
||||||
RatsnestVertexIndex::FixedDot(dot) => dot,
|
RatsnestVertexIndex::FixedDot(dot) => dot,
|
||||||
RatsnestVertexIndex::Zone(zone) => autorouter.layout.zone_apex(zone),
|
RatsnestVertexIndex::Zone(zone) => autorouter.board.layout_mut().zone_apex(zone),
|
||||||
};
|
};
|
||||||
|
|
||||||
let target_dot = match autorouter
|
let target_dot = match autorouter
|
||||||
|
|
@ -141,7 +142,7 @@ impl Autoroute {
|
||||||
.vertex_index()
|
.vertex_index()
|
||||||
{
|
{
|
||||||
RatsnestVertexIndex::FixedDot(dot) => dot,
|
RatsnestVertexIndex::FixedDot(dot) => dot,
|
||||||
RatsnestVertexIndex::Zone(zone) => autorouter.layout.zone_apex(zone),
|
RatsnestVertexIndex::Zone(zone) => autorouter.board.layout_mut().zone_apex(zone),
|
||||||
};
|
};
|
||||||
|
|
||||||
(source_dot, target_dot)
|
(source_dot, target_dot)
|
||||||
|
|
@ -153,14 +154,14 @@ impl Autoroute {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Autorouter<R: RulesTrait> {
|
pub struct Autorouter<R: RulesTrait> {
|
||||||
layout: Layout<R>,
|
board: Board<R>,
|
||||||
ratsnest: Ratsnest,
|
ratsnest: Ratsnest,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RulesTrait> Autorouter<R> {
|
impl<R: RulesTrait> Autorouter<R> {
|
||||||
pub fn new(layout: Layout<R>) -> Result<Self, InsertionError> {
|
pub fn new(board: Board<R>) -> Result<Self, InsertionError> {
|
||||||
let ratsnest = Ratsnest::new(&layout)?;
|
let ratsnest = Ratsnest::new(board.layout())?;
|
||||||
Ok(Self { layout, ratsnest })
|
Ok(Self { board, ratsnest })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn autoroute(
|
pub fn autoroute(
|
||||||
|
|
@ -195,7 +196,7 @@ impl<R: RulesTrait> Autorouter<R> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.band
|
.band
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.layout.remove_band(band);
|
self.board.layout_mut().remove_band(band);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -219,14 +220,14 @@ impl<R: RulesTrait> Autorouter<R> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.vertex_index();
|
.vertex_index();
|
||||||
|
|
||||||
selection.contains_node(&self.layout, source_vertex.into())
|
selection.contains_node(&self.board, source_vertex.into())
|
||||||
&& selection.contains_node(&self.layout, to_vertex.into())
|
&& selection.contains_node(&self.board, to_vertex.into())
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout(&self) -> &Layout<R> {
|
pub fn board(&self) -> &Board<R> {
|
||||||
&self.layout
|
&self.board
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ratsnest(&self) -> &Ratsnest {
|
pub fn ratsnest(&self) -> &Ratsnest {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
drawing::{
|
||||||
|
dot::{FixedDotIndex, FixedDotWeight},
|
||||||
|
graph::PrimitiveIndex,
|
||||||
|
rules::RulesTrait,
|
||||||
|
seg::{FixedSegIndex, FixedSegWeight},
|
||||||
|
Infringement,
|
||||||
|
},
|
||||||
|
geometry::GenericNode,
|
||||||
|
graph::GenericIndex,
|
||||||
|
layout::{zone::ZoneWeight, Layout},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Board<R: RulesTrait> {
|
||||||
|
layout: Layout<R>,
|
||||||
|
node_to_pin: HashMap<NodeIndex, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: RulesTrait> Board<R> {
|
||||||
|
pub fn new(layout: Layout<R>) -> Self {
|
||||||
|
Self {
|
||||||
|
layout,
|
||||||
|
node_to_pin: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_fixed_dot(
|
||||||
|
&mut self,
|
||||||
|
weight: FixedDotWeight,
|
||||||
|
maybe_pin: Option<String>,
|
||||||
|
) -> Result<FixedDotIndex, Infringement> {
|
||||||
|
let dot = self.layout.add_fixed_dot(weight)?;
|
||||||
|
|
||||||
|
if let Some(ref pin) = maybe_pin {
|
||||||
|
self.node_to_pin
|
||||||
|
.insert(GenericNode::Primitive(dot.into()), pin.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(dot)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_zone_fixed_dot(
|
||||||
|
&mut self,
|
||||||
|
weight: FixedDotWeight,
|
||||||
|
zone: GenericIndex<ZoneWeight>,
|
||||||
|
) -> Result<FixedDotIndex, Infringement> {
|
||||||
|
let dot = self.layout.add_zone_fixed_dot(weight, zone)?;
|
||||||
|
|
||||||
|
if let Some(pin) = self.node_pin(GenericNode::Compound(zone)) {
|
||||||
|
self.node_to_pin
|
||||||
|
.insert(GenericNode::Primitive(dot.into()), pin.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(dot)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_fixed_seg(
|
||||||
|
&mut self,
|
||||||
|
from: FixedDotIndex,
|
||||||
|
to: FixedDotIndex,
|
||||||
|
weight: FixedSegWeight,
|
||||||
|
maybe_pin: Option<String>,
|
||||||
|
) -> Result<FixedSegIndex, Infringement> {
|
||||||
|
let seg = self.layout.add_fixed_seg(from, to, weight)?;
|
||||||
|
|
||||||
|
if let Some(pin) = maybe_pin {
|
||||||
|
self.node_to_pin
|
||||||
|
.insert(GenericNode::Primitive(seg.into()), pin.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(seg)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_zone_fixed_seg(
|
||||||
|
&mut self,
|
||||||
|
from: FixedDotIndex,
|
||||||
|
to: FixedDotIndex,
|
||||||
|
weight: FixedSegWeight,
|
||||||
|
zone: GenericIndex<ZoneWeight>,
|
||||||
|
) -> Result<FixedSegIndex, Infringement> {
|
||||||
|
let seg = self.layout.add_zone_fixed_seg(from, to, weight, zone)?;
|
||||||
|
|
||||||
|
if let Some(pin) = self.node_pin(GenericNode::Compound(zone)) {
|
||||||
|
self.node_to_pin
|
||||||
|
.insert(GenericNode::Primitive(seg.into()), pin.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(seg)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_zone(
|
||||||
|
&mut self,
|
||||||
|
weight: ZoneWeight,
|
||||||
|
maybe_pin: Option<String>,
|
||||||
|
) -> GenericIndex<ZoneWeight> {
|
||||||
|
let zone = self.layout.add_zone(weight);
|
||||||
|
|
||||||
|
if let Some(pin) = maybe_pin {
|
||||||
|
self.node_to_pin
|
||||||
|
.insert(GenericNode::Compound(zone.into()), pin.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
zone
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn node_pin(&self, node: NodeIndex) -> Option<&String> {
|
||||||
|
self.node_to_pin.get(&node)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn layout(&self) -> &Layout<R> {
|
||||||
|
&self.layout
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn layout_mut(&mut self) -> &mut Layout<R> {
|
||||||
|
&mut self.layout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
mod autorouter;
|
mod autorouter;
|
||||||
|
pub mod board;
|
||||||
pub mod history;
|
pub mod history;
|
||||||
pub mod invoker;
|
pub mod invoker;
|
||||||
pub mod ratsnest;
|
pub mod ratsnest;
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ use core::fmt;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
autorouter::board::{Board, NodeIndex},
|
||||||
drawing::{graph::PrimitiveIndex, rules::RulesTrait},
|
drawing::{graph::PrimitiveIndex, rules::RulesTrait},
|
||||||
graph::GenericIndex,
|
graph::GenericIndex,
|
||||||
layout::{zone::ZoneWeight, Layout, NodeIndex},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
|
|
@ -19,28 +19,28 @@ impl Selection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_at_node(&mut self, layout: &Layout<impl RulesTrait>, node: NodeIndex) {
|
pub fn toggle_at_node(&mut self, board: &Board<impl RulesTrait>, node: NodeIndex) {
|
||||||
let maybe_pin = layout.node_pin(node);
|
let maybe_pin = board.node_pin(node);
|
||||||
|
|
||||||
if let Some(ref pin) = maybe_pin {
|
if let Some(ref pin) = maybe_pin {
|
||||||
if self.contains_node(layout, node) {
|
if self.contains_node(board, node) {
|
||||||
self.remove_pin(layout, pin);
|
self.remove_pin(board, pin);
|
||||||
} else {
|
} else {
|
||||||
self.add_pin(layout, pin);
|
self.add_pin(board, pin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_pin(&mut self, layout: &Layout<impl RulesTrait>, pin: &String) {
|
fn add_pin(&mut self, board: &Board<impl RulesTrait>, pin: &String) {
|
||||||
self.pins.insert(pin.clone());
|
self.pins.insert(pin.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_pin(&mut self, layout: &Layout<impl RulesTrait>, pin: &String) {
|
fn remove_pin(&mut self, board: &Board<impl RulesTrait>, pin: &String) {
|
||||||
self.pins.remove(pin);
|
self.pins.remove(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains_node(&self, layout: &Layout<impl RulesTrait>, node: NodeIndex) -> bool {
|
pub fn contains_node(&self, board: &Board<impl RulesTrait>, node: NodeIndex) -> bool {
|
||||||
if let Some(pin) = layout.node_pin(node) {
|
if let Some(pin) = board.node_pin(node) {
|
||||||
self.pins.contains(pin)
|
self.pins.contains(pin)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|
|
||||||
|
|
@ -160,19 +160,19 @@ impl eframe::App for App {
|
||||||
if cfg!(target_arch = "wasm32") {
|
if cfg!(target_arch = "wasm32") {
|
||||||
if let Ok(file_contents) = self.text_channel.1.try_recv() {
|
if let Ok(file_contents) = self.text_channel.1.try_recv() {
|
||||||
let design = DsnDesign::load_from_string(file_contents).unwrap();
|
let design = DsnDesign::load_from_string(file_contents).unwrap();
|
||||||
let layout = design.make_layout();
|
let board = design.make_board();
|
||||||
self.overlay = Some(Overlay::new(&layout).unwrap());
|
self.overlay = Some(Overlay::new(&board).unwrap());
|
||||||
self.invoker = Some(Arc::new(Mutex::new(Invoker::new(
|
self.invoker = Some(Arc::new(Mutex::new(Invoker::new(
|
||||||
Autorouter::new(layout).unwrap(),
|
Autorouter::new(board).unwrap(),
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Ok(path) = self.text_channel.1.try_recv() {
|
if let Ok(path) = self.text_channel.1.try_recv() {
|
||||||
let design = DsnDesign::load_from_file(&path).unwrap();
|
let design = DsnDesign::load_from_file(&path).unwrap();
|
||||||
let layout = design.make_layout();
|
let board = design.make_board();
|
||||||
self.overlay = Some(Overlay::new(&layout).unwrap());
|
self.overlay = Some(Overlay::new(&board).unwrap());
|
||||||
self.invoker = Some(Arc::new(Mutex::new(Invoker::new(
|
self.invoker = Some(Arc::new(Mutex::new(Invoker::new(
|
||||||
Autorouter::new(layout).unwrap(),
|
Autorouter::new(board).unwrap(),
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -359,22 +359,22 @@ impl eframe::App for App {
|
||||||
self.shared_data.lock().unwrap(),
|
self.shared_data.lock().unwrap(),
|
||||||
&mut self.overlay,
|
&mut self.overlay,
|
||||||
) {
|
) {
|
||||||
let layout = &invoker.autorouter().layout();
|
let board = invoker.autorouter().board();
|
||||||
|
|
||||||
if ctx.input(|i| i.pointer.any_click()) {
|
if ctx.input(|i| i.pointer.any_click()) {
|
||||||
overlay.click(
|
overlay.click(
|
||||||
layout,
|
board,
|
||||||
point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
|
point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for primitive in layout.drawing().layer_primitive_nodes(1) {
|
for primitive in board.layout().drawing().layer_primitive_nodes(1) {
|
||||||
let shape = primitive.primitive(layout.drawing()).shape();
|
let shape = primitive.primitive(board.layout().drawing()).shape();
|
||||||
|
|
||||||
let color = if shared_data.highlighteds.contains(&primitive)
|
let color = if shared_data.highlighteds.contains(&primitive)
|
||||||
|| overlay
|
|| overlay
|
||||||
.selection()
|
.selection()
|
||||||
.contains_node(&layout, GenericNode::Primitive(primitive))
|
.contains_node(board, GenericNode::Primitive(primitive))
|
||||||
{
|
{
|
||||||
egui::Color32::from_rgb(100, 100, 255)
|
egui::Color32::from_rgb(100, 100, 255)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -383,25 +383,25 @@ impl eframe::App for App {
|
||||||
painter.paint_primitive(&shape, color);
|
painter.paint_primitive(&shape, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
for zone in layout.layer_zone_nodes(1) {
|
for zone in board.layout().layer_zone_nodes(1) {
|
||||||
let color = if overlay
|
let color = if overlay
|
||||||
.selection()
|
.selection()
|
||||||
.contains_node(&layout, GenericNode::Compound(zone))
|
.contains_node(board, GenericNode::Compound(zone))
|
||||||
{
|
{
|
||||||
egui::Color32::from_rgb(100, 100, 255)
|
egui::Color32::from_rgb(100, 100, 255)
|
||||||
} else {
|
} else {
|
||||||
egui::Color32::from_rgb(52, 52, 200)
|
egui::Color32::from_rgb(52, 52, 200)
|
||||||
};
|
};
|
||||||
painter.paint_polygon(&layout.zone(zone).shape().polygon, color)
|
painter.paint_polygon(&board.layout().zone(zone).shape().polygon, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
for primitive in layout.drawing().layer_primitive_nodes(0) {
|
for primitive in board.layout().drawing().layer_primitive_nodes(0) {
|
||||||
let shape = primitive.primitive(layout.drawing()).shape();
|
let shape = primitive.primitive(board.layout().drawing()).shape();
|
||||||
|
|
||||||
let color = if shared_data.highlighteds.contains(&primitive)
|
let color = if shared_data.highlighteds.contains(&primitive)
|
||||||
|| overlay
|
|| overlay
|
||||||
.selection()
|
.selection()
|
||||||
.contains_node(&layout, GenericNode::Primitive(primitive))
|
.contains_node(board, GenericNode::Primitive(primitive))
|
||||||
{
|
{
|
||||||
egui::Color32::from_rgb(255, 100, 100)
|
egui::Color32::from_rgb(255, 100, 100)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -410,16 +410,16 @@ impl eframe::App for App {
|
||||||
painter.paint_primitive(&shape, color);
|
painter.paint_primitive(&shape, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
for zone in layout.layer_zone_nodes(0) {
|
for zone in board.layout().layer_zone_nodes(0) {
|
||||||
let color = if overlay
|
let color = if overlay
|
||||||
.selection()
|
.selection()
|
||||||
.contains_node(&layout, GenericNode::Compound(zone))
|
.contains_node(board, GenericNode::Compound(zone))
|
||||||
{
|
{
|
||||||
egui::Color32::from_rgb(255, 100, 100)
|
egui::Color32::from_rgb(255, 100, 100)
|
||||||
} else {
|
} else {
|
||||||
egui::Color32::from_rgb(200, 52, 52)
|
egui::Color32::from_rgb(200, 52, 52)
|
||||||
};
|
};
|
||||||
painter.paint_polygon(&layout.zone(zone).shape().polygon, color)
|
painter.paint_polygon(&board.layout().zone(zone).shape().polygon, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.show_ratsnest {
|
if self.show_ratsnest {
|
||||||
|
|
@ -447,9 +447,16 @@ impl eframe::App for App {
|
||||||
|
|
||||||
if let Some(navmesh) = &shared_data.navmesh {
|
if let Some(navmesh) = &shared_data.navmesh {
|
||||||
for edge in navmesh.edge_references() {
|
for edge in navmesh.edge_references() {
|
||||||
let from =
|
let from = edge
|
||||||
edge.source().primitive(layout.drawing()).shape().center();
|
.source()
|
||||||
let to = edge.target().primitive(layout.drawing()).shape().center();
|
.primitive(board.layout().drawing())
|
||||||
|
.shape()
|
||||||
|
.center();
|
||||||
|
let to = edge
|
||||||
|
.target()
|
||||||
|
.primitive(board.layout().drawing())
|
||||||
|
.shape()
|
||||||
|
.center();
|
||||||
|
|
||||||
let stroke = 'blk: {
|
let stroke = 'blk: {
|
||||||
if let (Some(source_pos), Some(target_pos)) = (
|
if let (Some(source_pos), Some(target_pos)) = (
|
||||||
|
|
@ -486,14 +493,14 @@ impl eframe::App for App {
|
||||||
if let (Some(from), Some(to)) = (shared_data.from, shared_data.to) {
|
if let (Some(from), Some(to)) = (shared_data.from, shared_data.to) {
|
||||||
painter.paint_dot(
|
painter.paint_dot(
|
||||||
Circle {
|
Circle {
|
||||||
pos: layout.drawing().primitive(from).shape().center(),
|
pos: board.layout().drawing().primitive(from).shape().center(),
|
||||||
r: 20.0,
|
r: 20.0,
|
||||||
},
|
},
|
||||||
egui::Color32::from_rgb(255, 255, 100),
|
egui::Color32::from_rgb(255, 255, 100),
|
||||||
);
|
);
|
||||||
painter.paint_dot(
|
painter.paint_dot(
|
||||||
Circle {
|
Circle {
|
||||||
pos: layout.drawing().primitive(to).shape().center(),
|
pos: board.layout().drawing().primitive(to).shape().center(),
|
||||||
r: 20.0,
|
r: 20.0,
|
||||||
},
|
},
|
||||||
egui::Color32::from_rgb(255, 255, 100),
|
egui::Color32::from_rgb(255, 255, 100),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use rstar::AABB;
|
||||||
use spade::InsertionError;
|
use spade::InsertionError;
|
||||||
|
|
||||||
use topola::{
|
use topola::{
|
||||||
autorouter::{ratsnest::Ratsnest, selection::Selection},
|
autorouter::{board::Board, ratsnest::Ratsnest, selection::Selection},
|
||||||
drawing::{
|
drawing::{
|
||||||
graph::{GetLayer, MakePrimitive},
|
graph::{GetLayer, MakePrimitive},
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
|
|
@ -25,16 +25,17 @@ pub struct Overlay {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Overlay {
|
impl Overlay {
|
||||||
pub fn new(layout: &Layout<impl RulesTrait>) -> Result<Self, InsertionError> {
|
pub fn new(board: &Board<impl RulesTrait>) -> Result<Self, InsertionError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ratsnest: Ratsnest::new(layout)?,
|
ratsnest: Ratsnest::new(board.layout())?,
|
||||||
selection: Selection::new(),
|
selection: Selection::new(),
|
||||||
active_layer: 0,
|
active_layer: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn click(&mut self, layout: &Layout<impl RulesTrait>, at: Point) {
|
pub fn click(&mut self, board: &Board<impl RulesTrait>, at: Point) {
|
||||||
let geoms: Vec<_> = layout
|
let geoms: Vec<_> = board
|
||||||
|
.layout()
|
||||||
.drawing()
|
.drawing()
|
||||||
.rtree()
|
.rtree()
|
||||||
.locate_in_envelope_intersecting(&AABB::<[f64; 3]>::from_corners(
|
.locate_in_envelope_intersecting(&AABB::<[f64; 3]>::from_corners(
|
||||||
|
|
@ -45,17 +46,17 @@ impl Overlay {
|
||||||
|
|
||||||
if let Some(geom) = geoms.iter().find(|&&geom| match geom.data {
|
if let Some(geom) = geoms.iter().find(|&&geom| match geom.data {
|
||||||
NodeIndex::Primitive(primitive) => {
|
NodeIndex::Primitive(primitive) => {
|
||||||
primitive.primitive(layout.drawing()).layer() == self.active_layer
|
primitive.primitive(board.layout().drawing()).layer() == self.active_layer
|
||||||
}
|
}
|
||||||
NodeIndex::Compound(compound) => false,
|
NodeIndex::Compound(compound) => false,
|
||||||
}) {
|
}) {
|
||||||
if self.toggle_selection_if_contains_point(layout, geom.data, at) {
|
if self.toggle_selection_if_contains_point(board, geom.data, at) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for geom in geoms {
|
for geom in geoms {
|
||||||
if self.toggle_selection_if_contains_point(layout, geom.data, at) {
|
if self.toggle_selection_if_contains_point(board, geom.data, at) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -63,17 +64,19 @@ impl Overlay {
|
||||||
|
|
||||||
fn toggle_selection_if_contains_point(
|
fn toggle_selection_if_contains_point(
|
||||||
&mut self,
|
&mut self,
|
||||||
layout: &Layout<impl RulesTrait>,
|
board: &Board<impl RulesTrait>,
|
||||||
node: NodeIndex,
|
node: NodeIndex,
|
||||||
p: Point,
|
p: Point,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let shape: Shape = match node {
|
let shape: Shape = match node {
|
||||||
NodeIndex::Primitive(primitive) => primitive.primitive(layout.drawing()).shape().into(),
|
NodeIndex::Primitive(primitive) => {
|
||||||
NodeIndex::Compound(compound) => layout.zone(compound).shape().into(),
|
primitive.primitive(board.layout().drawing()).shape().into()
|
||||||
|
}
|
||||||
|
NodeIndex::Compound(compound) => board.layout().zone(compound).shape().into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if shape.contains_point(p) {
|
if shape.contains_point(p) {
|
||||||
self.selection.toggle_at_node(layout, node);
|
self.selection.toggle_at_node(board, node);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,7 @@ fn main() -> Result<(), anyhow::Error> {
|
||||||
)?;
|
)?;
|
||||||
//let design = DsnDesign::load_from_file("tests/data/test/test.dsn")?;
|
//let design = DsnDesign::load_from_file("tests/data/test/test.dsn")?;
|
||||||
//dbg!(&design);
|
//dbg!(&design);
|
||||||
let layout = Arc::new(Mutex::new(design.make_layout()));
|
let layout = Arc::new(Mutex::new(design.make_board()));
|
||||||
//let mut router = Router::new(layout);
|
//let mut router = Router::new(layout);
|
||||||
|
|
||||||
let mut view = View {
|
let mut view = View {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use geo::{point, Point, Rotate, Translate};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
autorouter::board::Board,
|
||||||
drawing::{dot::FixedDotWeight, seg::FixedSegWeight, Drawing},
|
drawing::{dot::FixedDotWeight, seg::FixedSegWeight, Drawing},
|
||||||
dsn::{
|
dsn::{
|
||||||
de,
|
de,
|
||||||
|
|
@ -43,9 +44,9 @@ impl DsnDesign {
|
||||||
Ok(Self { pcb })
|
Ok(Self { pcb })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_layout(&self) -> Layout<DsnRules> {
|
pub fn make_board(&self) -> Board<DsnRules> {
|
||||||
let rules = DsnRules::from_pcb(&self.pcb);
|
let rules = DsnRules::from_pcb(&self.pcb);
|
||||||
let mut layout = Layout::new(Drawing::new(rules));
|
let mut board = Board::new(Layout::new(Drawing::new(rules)));
|
||||||
|
|
||||||
// mapping of pin id -> net id prepared for adding pins
|
// mapping of pin id -> net id prepared for adding pins
|
||||||
let pin_nets = HashMap::<String, usize>::from_iter(
|
let pin_nets = HashMap::<String, usize>::from_iter(
|
||||||
|
|
@ -55,7 +56,13 @@ impl DsnDesign {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|net| {
|
.map(|net| {
|
||||||
// resolve the id so we don't work with strings
|
// resolve the id so we don't work with strings
|
||||||
let net_id = layout.drawing().rules().net_ids.get(&net.name).unwrap();
|
let net_id = board
|
||||||
|
.layout()
|
||||||
|
.drawing()
|
||||||
|
.rules()
|
||||||
|
.net_ids
|
||||||
|
.get(&net.name)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// take the list of pins
|
// take the list of pins
|
||||||
// and for each pin id output (pin id, net id)
|
// and for each pin id output (pin id, net id)
|
||||||
|
|
@ -92,13 +99,13 @@ impl DsnDesign {
|
||||||
match shape {
|
match shape {
|
||||||
Shape::Circle(circle) => {
|
Shape::Circle(circle) => {
|
||||||
let layer = Self::layer(
|
let layer = Self::layer(
|
||||||
&mut layout,
|
&mut board,
|
||||||
&self.pcb.structure.layer_vec,
|
&self.pcb.structure.layer_vec,
|
||||||
&circle.layer,
|
&circle.layer,
|
||||||
place.side == "front",
|
place.side == "front",
|
||||||
);
|
);
|
||||||
Self::add_circle(
|
Self::add_circle(
|
||||||
&mut layout,
|
&mut board,
|
||||||
(place.x as f64, place.y as f64).into(),
|
(place.x as f64, place.y as f64).into(),
|
||||||
place.rotation as f64,
|
place.rotation as f64,
|
||||||
(pin.x as f64, pin.y as f64).into(),
|
(pin.x as f64, pin.y as f64).into(),
|
||||||
|
|
@ -111,13 +118,13 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
Shape::Rect(rect) => {
|
Shape::Rect(rect) => {
|
||||||
let layer = Self::layer(
|
let layer = Self::layer(
|
||||||
&mut layout,
|
&mut board,
|
||||||
&self.pcb.structure.layer_vec,
|
&self.pcb.structure.layer_vec,
|
||||||
&rect.layer,
|
&rect.layer,
|
||||||
place.side == "front",
|
place.side == "front",
|
||||||
);
|
);
|
||||||
Self::add_rect(
|
Self::add_rect(
|
||||||
&mut layout,
|
&mut board,
|
||||||
(place.x as f64, place.y as f64).into(),
|
(place.x as f64, place.y as f64).into(),
|
||||||
place.rotation as f64,
|
place.rotation as f64,
|
||||||
(pin.x as f64, pin.y as f64).into(),
|
(pin.x as f64, pin.y as f64).into(),
|
||||||
|
|
@ -133,13 +140,13 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
Shape::Path(path) => {
|
Shape::Path(path) => {
|
||||||
let layer = Self::layer(
|
let layer = Self::layer(
|
||||||
&mut layout,
|
&mut board,
|
||||||
&self.pcb.structure.layer_vec,
|
&self.pcb.structure.layer_vec,
|
||||||
&path.layer,
|
&path.layer,
|
||||||
place.side == "front",
|
place.side == "front",
|
||||||
);
|
);
|
||||||
Self::add_path(
|
Self::add_path(
|
||||||
&mut layout,
|
&mut board,
|
||||||
(place.x as f64, place.y as f64).into(),
|
(place.x as f64, place.y as f64).into(),
|
||||||
place.rotation as f64,
|
place.rotation as f64,
|
||||||
(pin.x as f64, pin.y as f64).into(),
|
(pin.x as f64, pin.y as f64).into(),
|
||||||
|
|
@ -153,13 +160,13 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
Shape::Polygon(polygon) => {
|
Shape::Polygon(polygon) => {
|
||||||
let layer = Self::layer(
|
let layer = Self::layer(
|
||||||
&mut layout,
|
&mut board,
|
||||||
&self.pcb.structure.layer_vec,
|
&self.pcb.structure.layer_vec,
|
||||||
&polygon.layer,
|
&polygon.layer,
|
||||||
place.side == "front",
|
place.side == "front",
|
||||||
);
|
);
|
||||||
Self::add_polygon(
|
Self::add_polygon(
|
||||||
&mut layout,
|
&mut board,
|
||||||
(place.x as f64, place.y as f64).into(),
|
(place.x as f64, place.y as f64).into(),
|
||||||
place.rotation as f64,
|
place.rotation as f64,
|
||||||
(pin.x as f64, pin.y as f64).into(),
|
(pin.x as f64, pin.y as f64).into(),
|
||||||
|
|
@ -178,7 +185,13 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
for via in &self.pcb.wiring.via_vec {
|
for via in &self.pcb.wiring.via_vec {
|
||||||
let net_id = *layout.drawing().rules().net_ids.get(&via.net).unwrap();
|
let net_id = *board
|
||||||
|
.layout()
|
||||||
|
.drawing()
|
||||||
|
.rules()
|
||||||
|
.net_ids
|
||||||
|
.get(&via.net)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// find the padstack referenced by this via placement
|
// find the padstack referenced by this via placement
|
||||||
let padstack = &self
|
let padstack = &self
|
||||||
|
|
@ -193,13 +206,13 @@ impl DsnDesign {
|
||||||
match shape {
|
match shape {
|
||||||
Shape::Circle(circle) => {
|
Shape::Circle(circle) => {
|
||||||
let layer = Self::layer(
|
let layer = Self::layer(
|
||||||
&mut layout,
|
&mut board,
|
||||||
&self.pcb.structure.layer_vec,
|
&self.pcb.structure.layer_vec,
|
||||||
&circle.layer,
|
&circle.layer,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
Self::add_circle(
|
Self::add_circle(
|
||||||
&mut layout,
|
&mut board,
|
||||||
(0.0, 0.0).into(),
|
(0.0, 0.0).into(),
|
||||||
0.0,
|
0.0,
|
||||||
(0.0, 0.0).into(),
|
(0.0, 0.0).into(),
|
||||||
|
|
@ -212,13 +225,13 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
Shape::Rect(rect) => {
|
Shape::Rect(rect) => {
|
||||||
let layer = Self::layer(
|
let layer = Self::layer(
|
||||||
&mut layout,
|
&mut board,
|
||||||
&self.pcb.structure.layer_vec,
|
&self.pcb.structure.layer_vec,
|
||||||
&rect.layer,
|
&rect.layer,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
Self::add_rect(
|
Self::add_rect(
|
||||||
&mut layout,
|
&mut board,
|
||||||
(0.0, 0.0).into(),
|
(0.0, 0.0).into(),
|
||||||
0.0,
|
0.0,
|
||||||
(0.0, 0.0).into(),
|
(0.0, 0.0).into(),
|
||||||
|
|
@ -234,13 +247,13 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
Shape::Path(path) => {
|
Shape::Path(path) => {
|
||||||
let layer = Self::layer(
|
let layer = Self::layer(
|
||||||
&mut layout,
|
&mut board,
|
||||||
&self.pcb.structure.layer_vec,
|
&self.pcb.structure.layer_vec,
|
||||||
&path.layer,
|
&path.layer,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
Self::add_path(
|
Self::add_path(
|
||||||
&mut layout,
|
&mut board,
|
||||||
(0.0, 0.0).into(),
|
(0.0, 0.0).into(),
|
||||||
0.0,
|
0.0,
|
||||||
(0.0, 0.0).into(),
|
(0.0, 0.0).into(),
|
||||||
|
|
@ -254,13 +267,13 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
Shape::Polygon(polygon) => {
|
Shape::Polygon(polygon) => {
|
||||||
let layer = Self::layer(
|
let layer = Self::layer(
|
||||||
&mut layout,
|
&mut board,
|
||||||
&self.pcb.structure.layer_vec,
|
&self.pcb.structure.layer_vec,
|
||||||
&polygon.layer,
|
&polygon.layer,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
Self::add_polygon(
|
Self::add_polygon(
|
||||||
&mut layout,
|
&mut board,
|
||||||
(0.0, 0.0).into(),
|
(0.0, 0.0).into(),
|
||||||
0.0,
|
0.0,
|
||||||
(0.0, 0.0).into(),
|
(0.0, 0.0).into(),
|
||||||
|
|
@ -277,16 +290,23 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
for wire in self.pcb.wiring.wire_vec.iter() {
|
for wire in self.pcb.wiring.wire_vec.iter() {
|
||||||
let layer_id = *layout
|
let layer_id = *board
|
||||||
|
.layout()
|
||||||
.drawing()
|
.drawing()
|
||||||
.rules()
|
.rules()
|
||||||
.layer_ids
|
.layer_ids
|
||||||
.get(&wire.path.layer)
|
.get(&wire.path.layer)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let net_id = *layout.drawing().rules().net_ids.get(&wire.net).unwrap();
|
let net_id = *board
|
||||||
|
.layout()
|
||||||
|
.drawing()
|
||||||
|
.rules()
|
||||||
|
.net_ids
|
||||||
|
.get(&wire.net)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Self::add_path(
|
Self::add_path(
|
||||||
&mut layout,
|
&mut board,
|
||||||
(0.0, 0.0).into(),
|
(0.0, 0.0).into(),
|
||||||
0.0,
|
0.0,
|
||||||
(0.0, 0.0).into(),
|
(0.0, 0.0).into(),
|
||||||
|
|
@ -299,16 +319,22 @@ impl DsnDesign {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
layout
|
board
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layer(
|
fn layer(
|
||||||
layout: &Layout<DsnRules>,
|
board: &Board<DsnRules>,
|
||||||
layer_vec: &Vec<Layer>,
|
layer_vec: &Vec<Layer>,
|
||||||
layer_name: &str,
|
layer_name: &str,
|
||||||
front: bool,
|
front: bool,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
let image_layer = *layout.drawing().rules().layer_ids.get(layer_name).unwrap();
|
let image_layer = *board
|
||||||
|
.layout()
|
||||||
|
.drawing()
|
||||||
|
.rules()
|
||||||
|
.layer_ids
|
||||||
|
.get(layer_name)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
if front {
|
if front {
|
||||||
image_layer as usize
|
image_layer as usize
|
||||||
|
|
@ -318,7 +344,7 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_circle(
|
fn add_circle(
|
||||||
layout: &mut Layout<DsnRules>,
|
board: &mut Board<DsnRules>,
|
||||||
place_pos: Point,
|
place_pos: Point,
|
||||||
place_rot: f64,
|
place_rot: f64,
|
||||||
pin_pos: Point,
|
pin_pos: Point,
|
||||||
|
|
@ -333,7 +359,7 @@ impl DsnDesign {
|
||||||
r,
|
r,
|
||||||
};
|
};
|
||||||
|
|
||||||
layout
|
board
|
||||||
.add_fixed_dot(
|
.add_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle,
|
circle,
|
||||||
|
|
@ -346,7 +372,7 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_rect(
|
fn add_rect(
|
||||||
layout: &mut Layout<DsnRules>,
|
board: &mut Board<DsnRules>,
|
||||||
place_pos: Point,
|
place_pos: Point,
|
||||||
place_rot: f64,
|
place_rot: f64,
|
||||||
pin_pos: Point,
|
pin_pos: Point,
|
||||||
|
|
@ -359,7 +385,7 @@ impl DsnDesign {
|
||||||
net: usize,
|
net: usize,
|
||||||
maybe_pin: Option<String>,
|
maybe_pin: Option<String>,
|
||||||
) {
|
) {
|
||||||
let zone = layout.add_zone(
|
let zone = board.add_zone(
|
||||||
SolidZoneWeight {
|
SolidZoneWeight {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
|
|
@ -369,7 +395,7 @@ impl DsnDesign {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Corners.
|
// Corners.
|
||||||
let dot_1_1 = layout
|
let dot_1_1 = board
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -382,7 +408,7 @@ impl DsnDesign {
|
||||||
zone,
|
zone,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let dot_2_1 = layout
|
let dot_2_1 = board
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -395,7 +421,7 @@ impl DsnDesign {
|
||||||
zone,
|
zone,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let dot_2_2 = layout
|
let dot_2_2 = board
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -408,7 +434,7 @@ impl DsnDesign {
|
||||||
zone,
|
zone,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let dot_1_2 = layout
|
let dot_1_2 = board
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -422,7 +448,7 @@ impl DsnDesign {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// Sides.
|
// Sides.
|
||||||
layout
|
board
|
||||||
.add_zone_fixed_seg(
|
.add_zone_fixed_seg(
|
||||||
dot_1_1,
|
dot_1_1,
|
||||||
dot_2_1,
|
dot_2_1,
|
||||||
|
|
@ -434,7 +460,7 @@ impl DsnDesign {
|
||||||
zone,
|
zone,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
layout
|
board
|
||||||
.add_zone_fixed_seg(
|
.add_zone_fixed_seg(
|
||||||
dot_2_1,
|
dot_2_1,
|
||||||
dot_2_2,
|
dot_2_2,
|
||||||
|
|
@ -446,7 +472,7 @@ impl DsnDesign {
|
||||||
zone,
|
zone,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
layout
|
board
|
||||||
.add_zone_fixed_seg(
|
.add_zone_fixed_seg(
|
||||||
dot_2_2,
|
dot_2_2,
|
||||||
dot_1_2,
|
dot_1_2,
|
||||||
|
|
@ -458,7 +484,7 @@ impl DsnDesign {
|
||||||
zone,
|
zone,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
layout
|
board
|
||||||
.add_zone_fixed_seg(
|
.add_zone_fixed_seg(
|
||||||
dot_1_2,
|
dot_1_2,
|
||||||
dot_1_1,
|
dot_1_1,
|
||||||
|
|
@ -473,7 +499,7 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_path(
|
fn add_path(
|
||||||
layout: &mut Layout<DsnRules>,
|
board: &mut Board<DsnRules>,
|
||||||
place_pos: Point,
|
place_pos: Point,
|
||||||
place_rot: f64,
|
place_rot: f64,
|
||||||
pin_pos: Point,
|
pin_pos: Point,
|
||||||
|
|
@ -493,7 +519,7 @@ impl DsnDesign {
|
||||||
coords[0].x as f64,
|
coords[0].x as f64,
|
||||||
coords[0].y as f64,
|
coords[0].y as f64,
|
||||||
);
|
);
|
||||||
let mut prev_index = layout
|
let mut prev_index = board
|
||||||
.add_fixed_dot(
|
.add_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -522,7 +548,7 @@ impl DsnDesign {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let index = layout
|
let index = board
|
||||||
.add_fixed_dot(
|
.add_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -537,7 +563,7 @@ impl DsnDesign {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// add a seg between the current and previous coords
|
// add a seg between the current and previous coords
|
||||||
let _ = layout
|
let _ = board
|
||||||
.add_fixed_seg(
|
.add_fixed_seg(
|
||||||
prev_index,
|
prev_index,
|
||||||
index,
|
index,
|
||||||
|
|
@ -556,7 +582,7 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_polygon(
|
fn add_polygon(
|
||||||
layout: &mut Layout<DsnRules>,
|
board: &mut Board<DsnRules>,
|
||||||
place_pos: Point,
|
place_pos: Point,
|
||||||
place_rot: f64,
|
place_rot: f64,
|
||||||
pin_pos: Point,
|
pin_pos: Point,
|
||||||
|
|
@ -567,7 +593,7 @@ impl DsnDesign {
|
||||||
net: usize,
|
net: usize,
|
||||||
maybe_pin: Option<String>,
|
maybe_pin: Option<String>,
|
||||||
) {
|
) {
|
||||||
let zone = layout.add_zone(
|
let zone = board.add_zone(
|
||||||
SolidZoneWeight {
|
SolidZoneWeight {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
|
|
@ -577,7 +603,7 @@ impl DsnDesign {
|
||||||
);
|
);
|
||||||
|
|
||||||
// add the first coordinate in the wire path as a dot and save its index
|
// add the first coordinate in the wire path as a dot and save its index
|
||||||
let mut prev_index = layout
|
let mut prev_index = board
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -602,7 +628,7 @@ impl DsnDesign {
|
||||||
|
|
||||||
// iterate through path coords starting from the second
|
// iterate through path coords starting from the second
|
||||||
for coord in coords.iter().skip(1) {
|
for coord in coords.iter().skip(1) {
|
||||||
let index = layout
|
let index = board
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -626,7 +652,7 @@ impl DsnDesign {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// add a seg between the current and previous coords
|
// add a seg between the current and previous coords
|
||||||
let _ = layout
|
let _ = board
|
||||||
.add_zone_fixed_seg(
|
.add_zone_fixed_seg(
|
||||||
prev_index,
|
prev_index,
|
||||||
index,
|
index,
|
||||||
|
|
|
||||||
|
|
@ -33,15 +33,11 @@ pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Layout<R: RulesTrait> {
|
pub struct Layout<R: RulesTrait> {
|
||||||
drawing: Drawing<ZoneWeight, R>,
|
drawing: Drawing<ZoneWeight, R>,
|
||||||
node_to_pin: HashMap<NodeIndex, String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RulesTrait> Layout<R> {
|
impl<R: RulesTrait> Layout<R> {
|
||||||
pub fn new(drawing: Drawing<ZoneWeight, R>) -> Self {
|
pub fn new(drawing: Drawing<ZoneWeight, R>) -> Self {
|
||||||
Self {
|
Self { drawing }
|
||||||
drawing,
|
|
||||||
node_to_pin: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_band(&mut self, band: BandIndex) {
|
pub fn remove_band(&mut self, band: BandIndex) {
|
||||||
|
|
@ -65,19 +61,8 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
.insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw)
|
.insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_fixed_dot(
|
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, Infringement> {
|
||||||
&mut self,
|
self.drawing.add_fixed_dot(weight)
|
||||||
weight: FixedDotWeight,
|
|
||||||
maybe_pin: Option<String>,
|
|
||||||
) -> Result<FixedDotIndex, Infringement> {
|
|
||||||
let dot = self.drawing.add_fixed_dot(weight)?;
|
|
||||||
|
|
||||||
if let Some(pin) = maybe_pin {
|
|
||||||
self.node_to_pin
|
|
||||||
.insert(GenericNode::Primitive(dot.into()), pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(dot)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_zone_fixed_dot(
|
pub fn add_zone_fixed_dot(
|
||||||
|
|
@ -85,7 +70,6 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
weight: FixedDotWeight,
|
weight: FixedDotWeight,
|
||||||
zone: GenericIndex<ZoneWeight>,
|
zone: GenericIndex<ZoneWeight>,
|
||||||
) -> Result<FixedDotIndex, Infringement> {
|
) -> Result<FixedDotIndex, Infringement> {
|
||||||
let pin = self.node_pin(GenericNode::Compound(zone));
|
|
||||||
let maybe_dot = self.drawing.add_fixed_dot(weight);
|
let maybe_dot = self.drawing.add_fixed_dot(weight);
|
||||||
|
|
||||||
if let Ok(dot) = maybe_dot {
|
if let Ok(dot) = maybe_dot {
|
||||||
|
|
@ -100,16 +84,8 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
from: FixedDotIndex,
|
from: FixedDotIndex,
|
||||||
to: FixedDotIndex,
|
to: FixedDotIndex,
|
||||||
weight: FixedSegWeight,
|
weight: FixedSegWeight,
|
||||||
maybe_pin: Option<String>,
|
|
||||||
) -> Result<FixedSegIndex, Infringement> {
|
) -> Result<FixedSegIndex, Infringement> {
|
||||||
let seg = self.drawing.add_fixed_seg(from, to, weight)?;
|
self.drawing.add_fixed_seg(from, to, weight)
|
||||||
|
|
||||||
if let Some(pin) = maybe_pin {
|
|
||||||
self.node_to_pin
|
|
||||||
.insert(GenericNode::Primitive(seg.into()), pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(seg)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_zone_fixed_seg(
|
pub fn add_zone_fixed_seg(
|
||||||
|
|
@ -119,8 +95,7 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
weight: FixedSegWeight,
|
weight: FixedSegWeight,
|
||||||
zone: GenericIndex<ZoneWeight>,
|
zone: GenericIndex<ZoneWeight>,
|
||||||
) -> Result<FixedSegIndex, Infringement> {
|
) -> Result<FixedSegIndex, Infringement> {
|
||||||
let pin = self.node_pin(GenericNode::Compound(zone));
|
let maybe_seg = self.add_fixed_seg(from, to, weight);
|
||||||
let maybe_seg = self.add_fixed_seg(from, to, weight, pin.cloned());
|
|
||||||
|
|
||||||
if let Ok(seg) = maybe_seg {
|
if let Ok(seg) = maybe_seg {
|
||||||
self.drawing.add_to_compound(seg, zone);
|
self.drawing.add_to_compound(seg, zone);
|
||||||
|
|
@ -151,19 +126,8 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
self.drawing.move_dot(dot, to)
|
self.drawing.move_dot(dot, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_zone(
|
pub fn add_zone(&mut self, weight: ZoneWeight) -> GenericIndex<ZoneWeight> {
|
||||||
&mut self,
|
self.drawing.add_compound(weight)
|
||||||
weight: ZoneWeight,
|
|
||||||
maybe_pin: Option<String>,
|
|
||||||
) -> GenericIndex<ZoneWeight> {
|
|
||||||
let zone = self.drawing.add_compound(weight);
|
|
||||||
|
|
||||||
if let Some(pin) = maybe_pin {
|
|
||||||
self.node_to_pin
|
|
||||||
.insert(GenericNode::Compound(zone.into()), pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
zone
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zones<W: 'static>(
|
pub fn zones<W: 'static>(
|
||||||
|
|
@ -173,10 +137,6 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
self.drawing.compounds(node)
|
self.drawing.compounds(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_pin(&self, node: NodeIndex) -> Option<&String> {
|
|
||||||
self.node_to_pin.get(&node)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn band_length(&self, face: DotIndex) -> f64 {
|
pub fn band_length(&self, face: DotIndex) -> f64 {
|
||||||
// TODO.
|
// TODO.
|
||||||
0.0
|
0.0
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,6 @@ impl<'a, R: RulesTrait> Router<'a, R> {
|
||||||
) -> Result<BandIndex, RouterError> {
|
) -> Result<BandIndex, RouterError> {
|
||||||
let from = self.navmesh.from();
|
let from = self.navmesh.from();
|
||||||
let to = self.navmesh.to();
|
let to = self.navmesh.to();
|
||||||
//let mut tracer = self.tracer();
|
|
||||||
let mut tracer = Tracer::new(self.layout);
|
let mut tracer = Tracer::new(self.layout);
|
||||||
let trace = tracer.start(from, width);
|
let trace = tracer.start(from, width);
|
||||||
|
|
||||||
|
|
@ -201,10 +200,6 @@ impl<'a, R: RulesTrait> Router<'a, R> {
|
||||||
self.route_band(width, observer)
|
self.route_band(width, observer)
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/*fn tracer(&mut self) -> Tracer<R> {
|
|
||||||
Tracer::new(self.layout)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
pub fn layout(&mut self) -> &mut Layout<R> {
|
pub fn layout(&mut self) -> &mut Layout<R> {
|
||||||
self.layout
|
self.layout
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,14 @@ use topola::{
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
let design = DsnDesign::load_from_file("tests/data/0603_breakout/0603_breakout.dsn").unwrap();
|
let design = DsnDesign::load_from_file("tests/data/0603_breakout/0603_breakout.dsn").unwrap();
|
||||||
let mut invoker = Invoker::new(Autorouter::new(design.make_layout()).unwrap());
|
let mut invoker = Invoker::new(Autorouter::new(design.make_board()).unwrap());
|
||||||
let file = File::open("tests/data/0603_breakout/autoroute_all.cmd").unwrap();
|
let file = File::open("tests/data/0603_breakout/autoroute_all.cmd").unwrap();
|
||||||
invoker.replay(serde_json::from_reader(file).unwrap());
|
invoker.replay(serde_json::from_reader(file).unwrap());
|
||||||
|
|
||||||
let mut unionfind = UnionFind::new(
|
let mut unionfind = UnionFind::new(
|
||||||
invoker
|
invoker
|
||||||
.autorouter()
|
.autorouter()
|
||||||
|
.board()
|
||||||
.layout()
|
.layout()
|
||||||
.drawing()
|
.drawing()
|
||||||
.geometry()
|
.geometry()
|
||||||
|
|
@ -34,6 +35,7 @@ fn test() {
|
||||||
|
|
||||||
for edge in invoker
|
for edge in invoker
|
||||||
.autorouter()
|
.autorouter()
|
||||||
|
.board()
|
||||||
.layout()
|
.layout()
|
||||||
.drawing()
|
.drawing()
|
||||||
.geometry()
|
.geometry()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue