mirror of https://codeberg.org/topola/topola.git
dsn: encapsulate DSN structure in new `DsnDesign` struct
Using a placeholder instead of rules and disabled routing for now. Also did some formatting corrections.
This commit is contained in:
parent
3f6bad2ed6
commit
473a877845
|
|
@ -13,6 +13,7 @@ use geo::point;
|
||||||
use painter::Painter;
|
use painter::Painter;
|
||||||
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
||||||
use topola::draw::DrawException;
|
use topola::draw::DrawException;
|
||||||
|
use topola::dsn::design::DsnDesign;
|
||||||
use topola::layout::connectivity::BandIndex;
|
use topola::layout::connectivity::BandIndex;
|
||||||
use topola::layout::dot::FixedDotWeight;
|
use topola::layout::dot::FixedDotWeight;
|
||||||
use topola::layout::geometry::shape::{Shape, ShapeTrait};
|
use topola::layout::geometry::shape::{Shape, ShapeTrait};
|
||||||
|
|
@ -48,9 +49,6 @@ use topola::tracer::{Trace, Tracer};
|
||||||
use topola::math::Circle;
|
use topola::math::Circle;
|
||||||
use topola::router::Router;
|
use topola::router::Router;
|
||||||
|
|
||||||
use topola::dsn::de::from_str;
|
|
||||||
use topola::dsn::structure::Pcb;
|
|
||||||
|
|
||||||
struct SimpleRules {
|
struct SimpleRules {
|
||||||
net_clearances: HashMap<(i64, i64), f64>,
|
net_clearances: HashMap<(i64, i64), f64>,
|
||||||
}
|
}
|
||||||
|
|
@ -237,7 +235,7 @@ fn main() -> Result<(), anyhow::Error> {
|
||||||
|
|
||||||
let mut event_pump = sdl_context.event_pump().unwrap();
|
let mut event_pump = sdl_context.event_pump().unwrap();
|
||||||
let _i = 0;
|
let _i = 0;
|
||||||
let mut router = Router::new(SimpleRules {
|
/*let mut router = Router::new(Layout::new(SimpleRules {
|
||||||
net_clearances: HashMap::from([
|
net_clearances: HashMap::from([
|
||||||
((1, 2), 8.0),
|
((1, 2), 8.0),
|
||||||
((2, 1), 8.0),
|
((2, 1), 8.0),
|
||||||
|
|
@ -246,88 +244,12 @@ fn main() -> Result<(), anyhow::Error> {
|
||||||
((3, 4), 15.0),
|
((3, 4), 15.0),
|
||||||
((4, 3), 15.0),
|
((4, 3), 15.0),
|
||||||
]),
|
]),
|
||||||
});
|
}));*/
|
||||||
|
let design = DsnDesign::load_from_file("tests/data/test.dsn")?;
|
||||||
let contents = std::fs::read_to_string("tests/data/test.dsn")?;
|
let layout = design.make_layout();
|
||||||
let pcb = from_str::<Pcb>(&contents)?;
|
let mut router = Router::new(layout);
|
||||||
//dbg!(&pcb);
|
//dbg!(&pcb);
|
||||||
|
|
||||||
// this holds the mapping of net names to numerical IDs (here for now)
|
|
||||||
let net_ids: HashMap<String, usize> = HashMap::from_iter(
|
|
||||||
pcb.network.classes[0].nets
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(id, net)| (net.clone(), id))
|
|
||||||
);
|
|
||||||
|
|
||||||
// add vias to layout and save indices of dots in the order they appear in the file
|
|
||||||
let dot_indices: Vec<_> = pcb.wiring.vias
|
|
||||||
.iter()
|
|
||||||
.map(|via| {
|
|
||||||
let net_id = net_ids.get(&via.net.0).unwrap();
|
|
||||||
let component = router.layout.add_component(*net_id as i64);
|
|
||||||
|
|
||||||
// no way to resolve the name or layer support yet
|
|
||||||
// pick the first layer of the first object found
|
|
||||||
let circle = &pcb.library.padstacks[0].shapes[0].0;
|
|
||||||
let circle = Circle {
|
|
||||||
pos: (
|
|
||||||
via.x as f64 / 100.0,
|
|
||||||
-via.y as f64 / 100.0,
|
|
||||||
).into(),
|
|
||||||
r: circle.radius as f64 / 100.0,
|
|
||||||
};
|
|
||||||
|
|
||||||
router.layout.add_fixed_dot(FixedDotWeight {
|
|
||||||
component,
|
|
||||||
circle,
|
|
||||||
}).unwrap()
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
for wire in pcb.wiring.wires.iter() {
|
|
||||||
let net_id = net_ids.get(&wire.net.0).unwrap();
|
|
||||||
let component = router.layout.add_component(*net_id as i64);
|
|
||||||
|
|
||||||
// add the first coordinate in the wire path as a dot and save its index
|
|
||||||
let mut prev_index = router.layout.add_fixed_dot(FixedDotWeight {
|
|
||||||
component,
|
|
||||||
circle: Circle {
|
|
||||||
pos: (
|
|
||||||
wire.path.coords[0].x as f64 / 100.0,
|
|
||||||
-wire.path.coords[0].y as f64 / 100.0,
|
|
||||||
).into(),
|
|
||||||
r: wire.path.width as f64 / 100.0,
|
|
||||||
}
|
|
||||||
}).unwrap();
|
|
||||||
|
|
||||||
// iterate through path coords starting from the second
|
|
||||||
for coord in wire.path.coords.iter().skip(1) {
|
|
||||||
let index = router.layout.add_fixed_dot(FixedDotWeight {
|
|
||||||
component,
|
|
||||||
circle: Circle {
|
|
||||||
pos: (
|
|
||||||
coord.x as f64 / 100.0,
|
|
||||||
-coord.y as f64 / 100.0,
|
|
||||||
).into(),
|
|
||||||
r: wire.path.width as f64 / 100.0,
|
|
||||||
}
|
|
||||||
}).unwrap();
|
|
||||||
|
|
||||||
// add a seg between the current and previous coords
|
|
||||||
let _ = router.layout.add_fixed_seg(
|
|
||||||
prev_index,
|
|
||||||
index,
|
|
||||||
FixedSegWeight {
|
|
||||||
component,
|
|
||||||
width: wire.path.width as f64 / 100.0,
|
|
||||||
},
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
prev_index = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render_times(
|
render_times(
|
||||||
&mut event_pump,
|
&mut event_pump,
|
||||||
&window,
|
&window,
|
||||||
|
|
@ -343,13 +265,13 @@ fn main() -> Result<(), anyhow::Error> {
|
||||||
);
|
);
|
||||||
|
|
||||||
// these are both on net 1 in the test file
|
// these are both on net 1 in the test file
|
||||||
let _ = router.route_band(
|
/*let _ = router.route_band(
|
||||||
dot_indices[1],
|
dot_indices[1],
|
||||||
dot_indices[2],
|
dot_indices[2],
|
||||||
3.0,
|
3.0,
|
||||||
//&mut EmptyRouterObserver,
|
//&mut EmptyRouterObserver,
|
||||||
&mut DebugRouterObserver::new(&mut event_pump, &window, &mut renderer, &font_context),
|
&mut DebugRouterObserver::new(&mut event_pump, &window, &mut renderer, &font_context),
|
||||||
)?;
|
)?;*/
|
||||||
|
|
||||||
render_times(
|
render_times(
|
||||||
&mut event_pump,
|
&mut event_pump,
|
||||||
|
|
|
||||||
193
src/dsn/de.rs
193
src/dsn/de.rs
|
|
@ -1,5 +1,5 @@
|
||||||
|
use serde::de::{self, DeserializeSeed, SeqAccess, Visitor};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::de::{self, Visitor, SeqAccess, DeserializeSeed};
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, Error>;
|
type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
@ -32,8 +32,7 @@ impl de::Error for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Deserializer<'de>
|
struct Deserializer<'de> {
|
||||||
{
|
|
||||||
input: &'de str,
|
input: &'de str,
|
||||||
line: usize,
|
line: usize,
|
||||||
column: usize,
|
column: usize,
|
||||||
|
|
@ -72,9 +71,11 @@ impl<'de> Deserializer<'de> {
|
||||||
let mut iter = self.input.chars();
|
let mut iter = self.input.chars();
|
||||||
if iter.next() != Some('(') {
|
if iter.next() != Some('(') {
|
||||||
None
|
None
|
||||||
}
|
} else {
|
||||||
else {
|
Some(
|
||||||
Some(iter.take_while(|c| c != &' ' && c != &'\r' && c != &'\n').collect::<String>())
|
iter.take_while(|c| c != &' ' && c != &'\r' && c != &'\n')
|
||||||
|
.collect::<String>(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,8 +89,7 @@ impl<'de> Deserializer<'de> {
|
||||||
if chr == '\n' {
|
if chr == '\n' {
|
||||||
self.line += 1;
|
self.line += 1;
|
||||||
self.column = 0;
|
self.column = 0;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
self.column += 1;
|
self.column += 1;
|
||||||
}
|
}
|
||||||
Ok(chr)
|
Ok(chr)
|
||||||
|
|
@ -99,8 +99,7 @@ impl<'de> Deserializer<'de> {
|
||||||
while let Ok(chr) = self.peek() {
|
while let Ok(chr) = self.peek() {
|
||||||
if chr != ' ' && chr != '\r' && chr != '\n' {
|
if chr != ' ' && chr != '\r' && chr != '\n' {
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
self.next().unwrap();
|
self.next().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +112,7 @@ impl<'de> Deserializer<'de> {
|
||||||
"on" => Ok(true),
|
"on" => Ok(true),
|
||||||
"off" => Ok(false),
|
"off" => Ok(false),
|
||||||
_ => Err(Error::ExpectedBool),
|
_ => Err(Error::ExpectedBool),
|
||||||
}
|
},
|
||||||
Err(_) => Err(Error::ExpectedBool),
|
Err(_) => Err(Error::ExpectedBool),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -126,8 +125,7 @@ impl<'de> Deserializer<'de> {
|
||||||
let chr = self.peek()?;
|
let chr = self.peek()?;
|
||||||
if self.string_quote == Some(chr) {
|
if self.string_quote == Some(chr) {
|
||||||
self.parse_quoted()
|
self.parse_quoted()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
self.parse_unquoted()
|
self.parse_unquoted()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -138,12 +136,10 @@ impl<'de> Deserializer<'de> {
|
||||||
let chr = self.peek()?;
|
let chr = self.peek()?;
|
||||||
if chr != ' ' && chr != '\r' && chr != '\n' && chr != '(' && chr != ')' {
|
if chr != ' ' && chr != '\r' && chr != '\n' && chr != '(' && chr != ')' {
|
||||||
string.push(self.next()?); // can't fail because of earlier peek
|
string.push(self.next()?); // can't fail because of earlier peek
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if string.len() > 0 {
|
if string.len() > 0 {
|
||||||
return Ok(string);
|
return Ok(string);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
dbg!(self.line, self.column);
|
dbg!(self.line, self.column);
|
||||||
return Err(Error::ExpectedUnquoted);
|
return Err(Error::ExpectedUnquoted);
|
||||||
}
|
}
|
||||||
|
|
@ -170,8 +166,7 @@ impl<'de> Deserializer<'de> {
|
||||||
if Some(chr) == self.string_quote {
|
if Some(chr) == self.string_quote {
|
||||||
self.next().unwrap();
|
self.next().unwrap();
|
||||||
return Ok(string);
|
return Ok(string);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
string.push(self.next()?); // can't fail because of earlier peek
|
string.push(self.next()?); // can't fail because of earlier peek
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -195,15 +190,15 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V:
|
where
|
||||||
Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
|
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
|
||||||
where V:
|
where
|
||||||
Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
let value = self.parse_bool()?;
|
let value = self.parse_bool()?;
|
||||||
self.skip_ws();
|
self.skip_ws();
|
||||||
|
|
@ -220,17 +215,20 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_i8<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_i8<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
fn deserialize_i16<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_i16<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
|
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
let value = self.parse_unquoted()?;
|
let value = self.parse_unquoted()?;
|
||||||
self.skip_ws();
|
self.skip_ws();
|
||||||
|
|
@ -239,22 +237,26 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
visitor.visit_i32(value.parse().unwrap())
|
visitor.visit_i32(value.parse().unwrap())
|
||||||
}
|
}
|
||||||
fn deserialize_i64<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_i64<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
fn deserialize_u8<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_u8<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
fn deserialize_u16<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_u16<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
|
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
let value = self.parse_unquoted()?;
|
let value = self.parse_unquoted()?;
|
||||||
self.skip_ws();
|
self.skip_ws();
|
||||||
|
|
@ -263,12 +265,14 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
visitor.visit_u32(value.parse().unwrap())
|
visitor.visit_u32(value.parse().unwrap())
|
||||||
}
|
}
|
||||||
fn deserialize_u64<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_u64<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
|
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
let value = self.parse_unquoted()?;
|
let value = self.parse_unquoted()?;
|
||||||
self.skip_ws();
|
self.skip_ws();
|
||||||
|
|
@ -277,12 +281,14 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
visitor.visit_f32(value.parse().unwrap())
|
visitor.visit_f32(value.parse().unwrap())
|
||||||
}
|
}
|
||||||
fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
|
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
let chr = self.next()?;
|
let chr = self.next()?;
|
||||||
self.skip_ws();
|
self.skip_ws();
|
||||||
|
|
@ -299,14 +305,15 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
|
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
|
||||||
where V:
|
where
|
||||||
Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
let string = self.parse_string()?;
|
let string = self.parse_string()?;
|
||||||
self.skip_ws();
|
self.skip_ws();
|
||||||
|
|
@ -316,43 +323,40 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_byte_buf<V>(
|
fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
self,
|
where
|
||||||
_visitor: V
|
V: Visitor<'de>,
|
||||||
) -> Result<V::Value>
|
|
||||||
where V: Visitor<'de>,
|
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
|
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
if self.next_option_empty_hint {
|
if self.next_option_empty_hint {
|
||||||
visitor.visit_none()
|
visitor.visit_none()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
visitor.visit_some(self)
|
visitor.visit_some(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_unit_struct<V>(
|
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
|
||||||
self,
|
where
|
||||||
name: &'static str,
|
V: Visitor<'de>,
|
||||||
visitor: V
|
|
||||||
) -> Result<V::Value>
|
|
||||||
where V: Visitor<'de>,
|
|
||||||
{
|
{
|
||||||
if self.next()? != '(' {
|
if self.next()? != '(' {
|
||||||
return Err(Error::ExpectedOpeningParen);
|
return Err(Error::ExpectedOpeningParen);
|
||||||
|
|
@ -374,12 +378,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
visitor.visit_unit()
|
visitor.visit_unit()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_newtype_struct<V>(
|
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
|
||||||
self,
|
where
|
||||||
name: &'static str,
|
V: Visitor<'de>,
|
||||||
visitor: V
|
|
||||||
) -> Result<V::Value>
|
|
||||||
where V: Visitor<'de>,
|
|
||||||
{
|
{
|
||||||
if self.next()? != '(' {
|
if self.next()? != '(' {
|
||||||
return Err(Error::ExpectedOpeningParen);
|
return Err(Error::ExpectedOpeningParen);
|
||||||
|
|
@ -413,18 +414,16 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
|
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
self.last_deserialized_type = None;
|
self.last_deserialized_type = None;
|
||||||
visitor.visit_seq(ArrayIndices::new(self))
|
visitor.visit_seq(ArrayIndices::new(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_tuple<V>(
|
fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
|
||||||
self,
|
where
|
||||||
_len: usize,
|
V: Visitor<'de>,
|
||||||
_visitor: V
|
|
||||||
) -> Result<V::Value>
|
|
||||||
where V: Visitor<'de>,
|
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
@ -433,15 +432,17 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
self,
|
self,
|
||||||
_name: &'static str,
|
_name: &'static str,
|
||||||
_len: usize,
|
_len: usize,
|
||||||
_visitor: V
|
_visitor: V,
|
||||||
) -> Result<V::Value>
|
) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value>
|
fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
@ -450,9 +451,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
self,
|
self,
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
fields: &'static [&'static str],
|
fields: &'static [&'static str],
|
||||||
visitor: V
|
visitor: V,
|
||||||
) -> Result<V::Value>
|
) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
if self.next()? != '(' {
|
if self.next()? != '(' {
|
||||||
return Err(Error::ExpectedOpeningParen);
|
return Err(Error::ExpectedOpeningParen);
|
||||||
|
|
@ -481,27 +483,24 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
self,
|
self,
|
||||||
_name: &'static str,
|
_name: &'static str,
|
||||||
_variants: &'static [&'static str],
|
_variants: &'static [&'static str],
|
||||||
_visitor: V
|
_visitor: V,
|
||||||
) -> Result<V::Value>
|
) -> Result<V::Value>
|
||||||
where V: Visitor<'de>,
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_identifier<V>(
|
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
|
||||||
self,
|
where
|
||||||
visitor: V
|
V: Visitor<'de>,
|
||||||
) -> Result<V::Value>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
{
|
||||||
visitor.visit_string(self.parse_string()?)
|
visitor.visit_string(self.parse_string()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_ignored_any<V>(
|
fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value>
|
||||||
self,
|
where
|
||||||
_visitor: V
|
V: Visitor<'de>,
|
||||||
) -> Result<V::Value>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
{
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
@ -513,9 +512,7 @@ struct NewtypeStructFields<'a, 'de: 'a> {
|
||||||
|
|
||||||
impl<'a, 'de> NewtypeStructFields<'a, 'de> {
|
impl<'a, 'de> NewtypeStructFields<'a, 'de> {
|
||||||
fn new(de: &'a mut Deserializer<'de>) -> Self {
|
fn new(de: &'a mut Deserializer<'de>) -> Self {
|
||||||
Self {
|
Self { de }
|
||||||
de,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -523,7 +520,8 @@ impl<'de, 'a> SeqAccess<'de> for NewtypeStructFields<'a, 'de> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn next_element_seed<S>(&mut self, seed: S) -> Result<Option<S::Value>>
|
fn next_element_seed<S>(&mut self, seed: S) -> Result<Option<S::Value>>
|
||||||
where S: DeserializeSeed<'de>,
|
where
|
||||||
|
S: DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
if self.de.peek()? == ')' {
|
if self.de.peek()? == ')' {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
|
@ -539,9 +537,7 @@ struct ArrayIndices<'a, 'de: 'a> {
|
||||||
|
|
||||||
impl<'a, 'de> ArrayIndices<'a, 'de> {
|
impl<'a, 'de> ArrayIndices<'a, 'de> {
|
||||||
fn new(de: &'a mut Deserializer<'de>) -> Self {
|
fn new(de: &'a mut Deserializer<'de>) -> Self {
|
||||||
Self {
|
Self { de }
|
||||||
de,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -549,7 +545,8 @@ impl<'de, 'a> SeqAccess<'de> for ArrayIndices<'a, 'de> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn next_element_seed<S>(&mut self, seed: S) -> Result<Option<S::Value>>
|
fn next_element_seed<S>(&mut self, seed: S) -> Result<Option<S::Value>>
|
||||||
where S: DeserializeSeed<'de>,
|
where
|
||||||
|
S: DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
if self.de.peek()? == ')' {
|
if self.de.peek()? == ')' {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
|
@ -570,7 +567,6 @@ impl<'de, 'a> SeqAccess<'de> for ArrayIndices<'a, 'de> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct StructFields<'a, 'de: 'a> {
|
struct StructFields<'a, 'de: 'a> {
|
||||||
de: &'a mut Deserializer<'de>,
|
de: &'a mut Deserializer<'de>,
|
||||||
current_field: usize,
|
current_field: usize,
|
||||||
|
|
@ -591,7 +587,8 @@ impl<'de, 'a> SeqAccess<'de> for StructFields<'a, 'de> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn next_element_seed<S>(&mut self, seed: S) -> Result<Option<S::Value>>
|
fn next_element_seed<S>(&mut self, seed: S) -> Result<Option<S::Value>>
|
||||||
where S: DeserializeSeed<'de>,
|
where
|
||||||
|
S: DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
if self.de.peek()? == ')' {
|
if self.de.peek()? == ')' {
|
||||||
if self.current_field < self.fields.len() {
|
if self.current_field < self.fields.len() {
|
||||||
|
|
@ -606,8 +603,7 @@ impl<'de, 'a> SeqAccess<'de> for StructFields<'a, 'de> {
|
||||||
// then even though our bet here was wrong (and we just lied to serde)
|
// then even though our bet here was wrong (and we just lied to serde)
|
||||||
// the deserializer we handed off to will see the same closing paren
|
// the deserializer we handed off to will see the same closing paren
|
||||||
// (that we reacted to just now) and still return a sensible error.
|
// (that we reacted to just now) and still return a sensible error.
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -616,12 +612,10 @@ impl<'de, 'a> SeqAccess<'de> for StructFields<'a, 'de> {
|
||||||
if let Some(lookahead) = self.de.next_name_lookahead() {
|
if let Some(lookahead) = self.de.next_name_lookahead() {
|
||||||
if lookahead != self.fields[self.current_field] {
|
if lookahead != self.fields[self.current_field] {
|
||||||
self.de.next_option_empty_hint = true;
|
self.de.next_option_empty_hint = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
self.de.next_option_empty_hint = false;
|
self.de.next_option_empty_hint = false;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
self.de.next_option_empty_hint = false;
|
self.de.next_option_empty_hint = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -629,4 +623,3 @@ impl<'de, 'a> SeqAccess<'de> for StructFields<'a, 'de> {
|
||||||
seed.deserialize(&mut *self.de).map(Some)
|
seed.deserialize(&mut *self.de).map(Some)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
layout::{dot::FixedDotWeight, seg::FixedSegWeight, Layout},
|
||||||
|
math::Circle,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
de::{from_str, Error},
|
||||||
|
structure::Pcb,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct DsnDesign {
|
||||||
|
pcb: Pcb,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DsnDesign {
|
||||||
|
pub fn load_from_file(filename: &str) -> Result<Self, Error> {
|
||||||
|
let contents = std::fs::read_to_string(filename).unwrap(); // TODO: remove unwrap.
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
pcb: from_str::<Pcb>(&contents)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_layout(&self) -> Layout<&Pcb> {
|
||||||
|
let mut layout = Layout::new(&self.pcb);
|
||||||
|
|
||||||
|
// this holds the mapping of net names to numerical IDs (here for now)
|
||||||
|
let net_ids: HashMap<String, usize> = HashMap::from_iter(
|
||||||
|
self.pcb.network.classes[0]
|
||||||
|
.nets
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(id, net)| (net.clone(), id)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// add vias to layout and save indices of dots in the order they appear in the file
|
||||||
|
let _dot_indices: Vec<_> = self
|
||||||
|
.pcb
|
||||||
|
.wiring
|
||||||
|
.vias
|
||||||
|
.iter()
|
||||||
|
.map(|via| {
|
||||||
|
let net_id = net_ids.get(&via.net.0).unwrap();
|
||||||
|
let component = layout.add_component(*net_id as i64);
|
||||||
|
|
||||||
|
// no way to resolve the name or layer support yet
|
||||||
|
// pick the first layer of the first object found
|
||||||
|
let circle = &self.pcb.library.padstacks[0].shapes[0].0;
|
||||||
|
let circle = Circle {
|
||||||
|
pos: (via.x as f64 / 100.0, -via.y as f64 / 100.0).into(),
|
||||||
|
r: circle.radius as f64 / 100.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
layout
|
||||||
|
.add_fixed_dot(FixedDotWeight { component, circle })
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for wire in self.pcb.wiring.wires.iter() {
|
||||||
|
let net_id = net_ids.get(&wire.net.0).unwrap();
|
||||||
|
let component = layout.add_component(*net_id as i64);
|
||||||
|
|
||||||
|
// add the first coordinate in the wire path as a dot and save its index
|
||||||
|
let mut prev_index = layout
|
||||||
|
.add_fixed_dot(FixedDotWeight {
|
||||||
|
component,
|
||||||
|
circle: Circle {
|
||||||
|
pos: (
|
||||||
|
wire.path.coords[0].x as f64 / 100.0,
|
||||||
|
-wire.path.coords[0].y as f64 / 100.0,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
r: wire.path.width as f64 / 100.0,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// iterate through path coords starting from the second
|
||||||
|
for coord in wire.path.coords.iter().skip(1) {
|
||||||
|
let index = layout
|
||||||
|
.add_fixed_dot(FixedDotWeight {
|
||||||
|
component,
|
||||||
|
circle: Circle {
|
||||||
|
pos: (coord.x as f64 / 100.0, -coord.y as f64 / 100.0).into(),
|
||||||
|
r: wire.path.width as f64 / 100.0,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// add a seg between the current and previous coords
|
||||||
|
let _ = layout
|
||||||
|
.add_fixed_seg(
|
||||||
|
prev_index,
|
||||||
|
index,
|
||||||
|
FixedSegWeight {
|
||||||
|
component,
|
||||||
|
width: wire.path.width as f64 / 100.0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
prev_index = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,4 @@
|
||||||
pub mod de;
|
mod de;
|
||||||
pub mod structure;
|
pub mod design;
|
||||||
|
mod rules;
|
||||||
|
mod structure;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
use crate::layout::rules::{Conditions, RulesTrait};
|
||||||
|
|
||||||
|
use super::structure::Pcb;
|
||||||
|
|
||||||
|
impl<'a> RulesTrait for &'a Pcb {
|
||||||
|
fn clearance(&self, _conditions1: &Conditions, _conditions2: &Conditions) -> f64 {
|
||||||
|
// Placeholder for now.
|
||||||
|
10.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clearance_net_limit(&self, _net: i64) -> f64 {
|
||||||
|
// Placeholder for now.
|
||||||
|
10.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -92,7 +92,7 @@ pub struct Placement;
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
#[serde(rename = "library")]
|
#[serde(rename = "library")]
|
||||||
pub struct Library {
|
pub struct Library {
|
||||||
pub padstacks: Vec<Padstack>
|
pub padstacks: Vec<Padstack>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
|
|
@ -192,7 +192,9 @@ impl From<FlatPath> for Path {
|
||||||
Path {
|
Path {
|
||||||
layer: flat.layer,
|
layer: flat.layer,
|
||||||
width: flat.width,
|
width: flat.width,
|
||||||
coords: flat.coords.chunks(2)
|
coords: flat
|
||||||
|
.coords
|
||||||
|
.chunks(2)
|
||||||
.map(|pair| Point {
|
.map(|pair| Point {
|
||||||
x: pair[0],
|
x: pair[0],
|
||||||
// it's possible to return an error instead of panicking if this From were TryFrom,
|
// it's possible to return an error instead of panicking if this From were TryFrom,
|
||||||
|
|
@ -236,4 +238,3 @@ pub struct Clearance {
|
||||||
pub value: f32,
|
pub value: f32,
|
||||||
pub r#type: Option<Type>,
|
pub r#type: Option<Type>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,8 @@ use crate::wraparoundable::{GetWraparound, WraparoundableIndex};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
bend::LooseBendIndex,
|
bend::LooseBendIndex,
|
||||||
dot::DotIndex,
|
|
||||||
graph::GeometryIndex,
|
graph::GeometryIndex,
|
||||||
primitive::{GetCore, GetInnerOuter, GetJoints},
|
primitive::{GetInnerOuter, GetJoints},
|
||||||
rules::RulesTrait,
|
rules::RulesTrait,
|
||||||
Layout,
|
Layout,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@ impl ShapeTrait for BendShape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn envelope(&self, margin: f64) -> AABB<[f64; 2]> {
|
fn envelope(&self, _margin: f64) -> AABB<[f64; 2]> {
|
||||||
let halfwidth = self.c.r + self.width;
|
let halfwidth = self.c.r + self.width;
|
||||||
AABB::from_corners(
|
AABB::from_corners(
|
||||||
[self.c.pos.x() - halfwidth, self.c.pos.y() - halfwidth],
|
[self.c.pos.x() - halfwidth, self.c.pos.y() - halfwidth],
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ impl<'a, R: RulesTrait> Guide<'a, R> {
|
||||||
math::tangent_segment(from_circle, from_cw, to_circle, Some(cw))
|
math::tangent_segment(from_circle, from_cw, to_circle, Some(cw))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn head_around_dot_offset(&self, head: &Head, around: DotIndex, width: f64) -> f64 {
|
pub fn head_around_dot_offset(&self, head: &Head, around: DotIndex, _width: f64) -> f64 {
|
||||||
self.layout.rules().clearance(
|
self.layout.rules().clearance(
|
||||||
&self.conditions(around.into()),
|
&self.conditions(around.into()),
|
||||||
&self.conditions(head.face().into()),
|
&self.conditions(head.face().into()),
|
||||||
|
|
@ -158,7 +158,7 @@ impl<'a, R: RulesTrait> Guide<'a, R> {
|
||||||
math::tangent_segment(from_circle, from_cw, to_circle, Some(cw))
|
math::tangent_segment(from_circle, from_cw, to_circle, Some(cw))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn head_around_bend_offset(&self, head: &Head, around: BendIndex, width: f64) -> f64 {
|
pub fn head_around_bend_offset(&self, head: &Head, around: BendIndex, _width: f64) -> f64 {
|
||||||
self.layout.rules().clearance(
|
self.layout.rules().clearance(
|
||||||
&self.conditions(head.face().into()),
|
&self.conditions(head.face().into()),
|
||||||
&self.conditions(around.into()),
|
&self.conditions(around.into()),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use contracts::debug_ensures;
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
use petgraph::stable_graph::StableDiGraph;
|
use petgraph::stable_graph::StableDiGraph;
|
||||||
use petgraph::visit::EdgeRef;
|
|
||||||
|
|
||||||
use rstar::RTreeObject;
|
use rstar::RTreeObject;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
@ -26,15 +25,13 @@ use crate::layout::geometry::{
|
||||||
};
|
};
|
||||||
use crate::layout::guide::Guide;
|
use crate::layout::guide::Guide;
|
||||||
use crate::layout::primitive::GetLimbs;
|
use crate::layout::primitive::GetLimbs;
|
||||||
use crate::layout::rules::{Conditions, GetConditions};
|
use crate::layout::rules::GetConditions;
|
||||||
use crate::layout::{
|
use crate::layout::{
|
||||||
bend::{FixedBendIndex, LooseBendIndex, LooseBendWeight},
|
bend::{FixedBendIndex, LooseBendIndex, LooseBendWeight},
|
||||||
dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
||||||
geometry::shape::{Shape, ShapeTrait},
|
geometry::shape::{Shape, ShapeTrait},
|
||||||
graph::{GeometryIndex, GeometryWeight, GetComponentIndex, MakePrimitive},
|
graph::{GeometryIndex, GeometryWeight, GetComponentIndex, MakePrimitive},
|
||||||
primitive::{
|
primitive::{GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetOtherJoint, MakeShape},
|
||||||
GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetOtherJoint, GetWeight, MakeShape,
|
|
||||||
},
|
|
||||||
seg::{
|
seg::{
|
||||||
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
|
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
|
||||||
SeqLooseSegIndex, SeqLooseSegWeight,
|
SeqLooseSegIndex, SeqLooseSegWeight,
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ use crate::layout::{
|
||||||
shape::{Shape, ShapeTrait},
|
shape::{Shape, ShapeTrait},
|
||||||
GetOffset, GetWidth,
|
GetOffset, GetWidth,
|
||||||
},
|
},
|
||||||
graph::{GeometryIndex, GeometryWeight, GetBandIndex, GetComponentIndex, MakePrimitive, Retag},
|
graph::{GeometryIndex, GeometryWeight, GetBandIndex, GetComponentIndex, Retag},
|
||||||
loose::{Loose, LooseIndex},
|
loose::LooseIndex,
|
||||||
Layout,
|
Layout,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ pub mod draw;
|
||||||
pub mod graph;
|
pub mod graph;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod layout;
|
pub mod layout;
|
||||||
|
pub mod dsn;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
pub mod mesh;
|
pub mod mesh;
|
||||||
pub mod router;
|
pub mod router;
|
||||||
pub mod tracer;
|
pub mod tracer;
|
||||||
pub mod triangulation;
|
pub mod triangulation;
|
||||||
pub mod wraparoundable;
|
pub mod wraparoundable;
|
||||||
pub mod dsn;
|
|
||||||
|
|
|
||||||
|
|
@ -144,10 +144,8 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Mesh, f64>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RulesTrait> Router<R> {
|
impl<R: RulesTrait> Router<R> {
|
||||||
pub fn new(rules: R) -> Self {
|
pub fn new(layout: Layout<R>) -> Self {
|
||||||
Router {
|
Router { layout }
|
||||||
layout: Layout::new(rules),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn route_band(
|
pub fn route_band(
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,7 @@ use crate::{
|
||||||
bend::{BendIndex, FixedBendIndex, LooseBendIndex},
|
bend::{BendIndex, FixedBendIndex, LooseBendIndex},
|
||||||
dot::FixedDotIndex,
|
dot::FixedDotIndex,
|
||||||
graph::{GeometryIndex, MakePrimitive},
|
graph::{GeometryIndex, MakePrimitive},
|
||||||
primitive::{
|
primitive::{FixedBend, FixedDot, GetFirstRail, GetInnerOuter, LooseBend, Primitive},
|
||||||
FixedBend, FixedDot, GetFirstRail, GetInnerOuter, GetLayout, LooseBend, Primitive,
|
|
||||||
},
|
|
||||||
rules::RulesTrait,
|
rules::RulesTrait,
|
||||||
Layout,
|
Layout,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue