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 petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
||||
use topola::draw::DrawException;
|
||||
use topola::dsn::design::DsnDesign;
|
||||
use topola::layout::connectivity::BandIndex;
|
||||
use topola::layout::dot::FixedDotWeight;
|
||||
use topola::layout::geometry::shape::{Shape, ShapeTrait};
|
||||
|
|
@ -48,9 +49,6 @@ use topola::tracer::{Trace, Tracer};
|
|||
use topola::math::Circle;
|
||||
use topola::router::Router;
|
||||
|
||||
use topola::dsn::de::from_str;
|
||||
use topola::dsn::structure::Pcb;
|
||||
|
||||
struct SimpleRules {
|
||||
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 _i = 0;
|
||||
let mut router = Router::new(SimpleRules {
|
||||
/*let mut router = Router::new(Layout::new(SimpleRules {
|
||||
net_clearances: HashMap::from([
|
||||
((1, 2), 8.0),
|
||||
((2, 1), 8.0),
|
||||
|
|
@ -246,88 +244,12 @@ fn main() -> Result<(), anyhow::Error> {
|
|||
((3, 4), 15.0),
|
||||
((4, 3), 15.0),
|
||||
]),
|
||||
});
|
||||
|
||||
let contents = std::fs::read_to_string("tests/data/test.dsn")?;
|
||||
let pcb = from_str::<Pcb>(&contents)?;
|
||||
}));*/
|
||||
let design = DsnDesign::load_from_file("tests/data/test.dsn")?;
|
||||
let layout = design.make_layout();
|
||||
let mut router = Router::new(layout);
|
||||
//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(
|
||||
&mut event_pump,
|
||||
&window,
|
||||
|
|
@ -343,13 +265,13 @@ fn main() -> Result<(), anyhow::Error> {
|
|||
);
|
||||
|
||||
// these are both on net 1 in the test file
|
||||
let _ = router.route_band(
|
||||
/*let _ = router.route_band(
|
||||
dot_indices[1],
|
||||
dot_indices[2],
|
||||
3.0,
|
||||
//&mut EmptyRouterObserver,
|
||||
&mut DebugRouterObserver::new(&mut event_pump, &window, &mut renderer, &font_context),
|
||||
)?;
|
||||
)?;*/
|
||||
|
||||
render_times(
|
||||
&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::de::{self, Visitor, SeqAccess, DeserializeSeed};
|
||||
use thiserror::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,
|
||||
line: usize,
|
||||
column: usize,
|
||||
|
|
@ -72,9 +71,11 @@ impl<'de> Deserializer<'de> {
|
|||
let mut iter = self.input.chars();
|
||||
if iter.next() != Some('(') {
|
||||
None
|
||||
}
|
||||
else {
|
||||
Some(iter.take_while(|c| c != &' ' && c != &'\r' && c != &'\n').collect::<String>())
|
||||
} else {
|
||||
Some(
|
||||
iter.take_while(|c| c != &' ' && c != &'\r' && c != &'\n')
|
||||
.collect::<String>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,8 +89,7 @@ impl<'de> Deserializer<'de> {
|
|||
if chr == '\n' {
|
||||
self.line += 1;
|
||||
self.column = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
self.column += 1;
|
||||
}
|
||||
Ok(chr)
|
||||
|
|
@ -99,8 +99,7 @@ impl<'de> Deserializer<'de> {
|
|||
while let Ok(chr) = self.peek() {
|
||||
if chr != ' ' && chr != '\r' && chr != '\n' {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
self.next().unwrap();
|
||||
}
|
||||
}
|
||||
|
|
@ -113,7 +112,7 @@ impl<'de> Deserializer<'de> {
|
|||
"on" => Ok(true),
|
||||
"off" => Ok(false),
|
||||
_ => Err(Error::ExpectedBool),
|
||||
}
|
||||
},
|
||||
Err(_) => Err(Error::ExpectedBool),
|
||||
}
|
||||
}
|
||||
|
|
@ -126,8 +125,7 @@ impl<'de> Deserializer<'de> {
|
|||
let chr = self.peek()?;
|
||||
if self.string_quote == Some(chr) {
|
||||
self.parse_quoted()
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
self.parse_unquoted()
|
||||
}
|
||||
}
|
||||
|
|
@ -138,12 +136,10 @@ impl<'de> Deserializer<'de> {
|
|||
let chr = self.peek()?;
|
||||
if chr != ' ' && chr != '\r' && chr != '\n' && chr != '(' && chr != ')' {
|
||||
string.push(self.next()?); // can't fail because of earlier peek
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if string.len() > 0 {
|
||||
return Ok(string);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dbg!(self.line, self.column);
|
||||
return Err(Error::ExpectedUnquoted);
|
||||
}
|
||||
|
|
@ -170,8 +166,7 @@ impl<'de> Deserializer<'de> {
|
|||
if Some(chr) == self.string_quote {
|
||||
self.next().unwrap();
|
||||
return Ok(string);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
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;
|
||||
|
||||
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V:
|
||||
Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V:
|
||||
Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let value = self.parse_bool()?;
|
||||
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>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
fn deserialize_i16<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let value = self.parse_unquoted()?;
|
||||
self.skip_ws();
|
||||
|
|
@ -239,22 +237,26 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
visitor.visit_i32(value.parse().unwrap())
|
||||
}
|
||||
fn deserialize_i64<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
fn deserialize_u8<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
fn deserialize_u16<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let value = self.parse_unquoted()?;
|
||||
self.skip_ws();
|
||||
|
|
@ -263,12 +265,14 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
visitor.visit_u32(value.parse().unwrap())
|
||||
}
|
||||
fn deserialize_u64<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let value = self.parse_unquoted()?;
|
||||
self.skip_ws();
|
||||
|
|
@ -277,12 +281,14 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
visitor.visit_f32(value.parse().unwrap())
|
||||
}
|
||||
fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let chr = self.next()?;
|
||||
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>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V:
|
||||
Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let string = self.parse_string()?;
|
||||
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>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn deserialize_byte_buf<V>(
|
||||
self,
|
||||
_visitor: V
|
||||
) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
if self.next_option_empty_hint {
|
||||
visitor.visit_none()
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
visitor.visit_some(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn deserialize_unit_struct<V>(
|
||||
self,
|
||||
name: &'static str,
|
||||
visitor: V
|
||||
) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
if self.next()? != '(' {
|
||||
return Err(Error::ExpectedOpeningParen);
|
||||
|
|
@ -374,12 +378,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
visitor.visit_unit()
|
||||
}
|
||||
|
||||
fn deserialize_newtype_struct<V>(
|
||||
self,
|
||||
name: &'static str,
|
||||
visitor: V
|
||||
) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
if self.next()? != '(' {
|
||||
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>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
self.last_deserialized_type = None;
|
||||
visitor.visit_seq(ArrayIndices::new(self))
|
||||
}
|
||||
|
||||
fn deserialize_tuple<V>(
|
||||
self,
|
||||
_len: usize,
|
||||
_visitor: V
|
||||
) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
|
|
@ -433,15 +432,17 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
_visitor: V
|
||||
_visitor: V,
|
||||
) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
|
|
@ -450,9 +451,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
self,
|
||||
name: &'static str,
|
||||
fields: &'static [&'static str],
|
||||
visitor: V
|
||||
visitor: V,
|
||||
) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
if self.next()? != '(' {
|
||||
return Err(Error::ExpectedOpeningParen);
|
||||
|
|
@ -481,27 +483,24 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
self,
|
||||
_name: &'static str,
|
||||
_variants: &'static [&'static str],
|
||||
_visitor: V
|
||||
_visitor: V,
|
||||
) -> Result<V::Value>
|
||||
where V: Visitor<'de>,
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn deserialize_identifier<V>(
|
||||
self,
|
||||
visitor: V
|
||||
) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
visitor.visit_string(self.parse_string()?)
|
||||
}
|
||||
|
||||
fn deserialize_ignored_any<V>(
|
||||
self,
|
||||
_visitor: V
|
||||
) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
|
|
@ -513,9 +512,7 @@ struct NewtypeStructFields<'a, 'de: 'a> {
|
|||
|
||||
impl<'a, 'de> NewtypeStructFields<'a, 'de> {
|
||||
fn new(de: &'a mut Deserializer<'de>) -> Self {
|
||||
Self {
|
||||
de,
|
||||
}
|
||||
Self { de }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -523,7 +520,8 @@ impl<'de, 'a> SeqAccess<'de> for NewtypeStructFields<'a, 'de> {
|
|||
type Error = Error;
|
||||
|
||||
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()? == ')' {
|
||||
return Ok(None);
|
||||
|
|
@ -539,9 +537,7 @@ struct ArrayIndices<'a, 'de: 'a> {
|
|||
|
||||
impl<'a, 'de> ArrayIndices<'a, 'de> {
|
||||
fn new(de: &'a mut Deserializer<'de>) -> Self {
|
||||
Self {
|
||||
de,
|
||||
}
|
||||
Self { de }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -549,7 +545,8 @@ impl<'de, 'a> SeqAccess<'de> for ArrayIndices<'a, 'de> {
|
|||
type Error = Error;
|
||||
|
||||
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()? == ')' {
|
||||
return Ok(None);
|
||||
|
|
@ -570,7 +567,6 @@ impl<'de, 'a> SeqAccess<'de> for ArrayIndices<'a, 'de> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
struct StructFields<'a, 'de: 'a> {
|
||||
de: &'a mut Deserializer<'de>,
|
||||
current_field: usize,
|
||||
|
|
@ -591,7 +587,8 @@ impl<'de, 'a> SeqAccess<'de> for StructFields<'a, 'de> {
|
|||
type Error = Error;
|
||||
|
||||
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.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)
|
||||
// the deserializer we handed off to will see the same closing paren
|
||||
// (that we reacted to just now) and still return a sensible error.
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
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 lookahead != self.fields[self.current_field] {
|
||||
self.de.next_option_empty_hint = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
self.de.next_option_empty_hint = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
pub mod structure;
|
||||
mod de;
|
||||
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)]
|
||||
#[serde(rename = "library")]
|
||||
pub struct Library {
|
||||
pub padstacks: Vec<Padstack>
|
||||
pub padstacks: Vec<Padstack>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
|
|
@ -192,7 +192,9 @@ impl From<FlatPath> for Path {
|
|||
Path {
|
||||
layer: flat.layer,
|
||||
width: flat.width,
|
||||
coords: flat.coords.chunks(2)
|
||||
coords: flat
|
||||
.coords
|
||||
.chunks(2)
|
||||
.map(|pair| Point {
|
||||
x: pair[0],
|
||||
// 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 r#type: Option<Type>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@ use crate::wraparoundable::{GetWraparound, WraparoundableIndex};
|
|||
|
||||
use super::{
|
||||
bend::LooseBendIndex,
|
||||
dot::DotIndex,
|
||||
graph::GeometryIndex,
|
||||
primitive::{GetCore, GetInnerOuter, GetJoints},
|
||||
primitive::{GetInnerOuter, GetJoints},
|
||||
rules::RulesTrait,
|
||||
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;
|
||||
AABB::from_corners(
|
||||
[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))
|
||||
}
|
||||
|
||||
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.conditions(around.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))
|
||||
}
|
||||
|
||||
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.conditions(head.face().into()),
|
||||
&self.conditions(around.into()),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ use contracts::debug_ensures;
|
|||
use enum_dispatch::enum_dispatch;
|
||||
use geo::Point;
|
||||
use petgraph::stable_graph::StableDiGraph;
|
||||
use petgraph::visit::EdgeRef;
|
||||
|
||||
use rstar::RTreeObject;
|
||||
use thiserror::Error;
|
||||
|
|
@ -26,15 +25,13 @@ use crate::layout::geometry::{
|
|||
};
|
||||
use crate::layout::guide::Guide;
|
||||
use crate::layout::primitive::GetLimbs;
|
||||
use crate::layout::rules::{Conditions, GetConditions};
|
||||
use crate::layout::rules::GetConditions;
|
||||
use crate::layout::{
|
||||
bend::{FixedBendIndex, LooseBendIndex, LooseBendWeight},
|
||||
dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
||||
geometry::shape::{Shape, ShapeTrait},
|
||||
graph::{GeometryIndex, GeometryWeight, GetComponentIndex, MakePrimitive},
|
||||
primitive::{
|
||||
GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetOtherJoint, GetWeight, MakeShape,
|
||||
},
|
||||
primitive::{GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetOtherJoint, MakeShape},
|
||||
seg::{
|
||||
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
|
||||
SeqLooseSegIndex, SeqLooseSegWeight,
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ use crate::layout::{
|
|||
shape::{Shape, ShapeTrait},
|
||||
GetOffset, GetWidth,
|
||||
},
|
||||
graph::{GeometryIndex, GeometryWeight, GetBandIndex, GetComponentIndex, MakePrimitive, Retag},
|
||||
loose::{Loose, LooseIndex},
|
||||
graph::{GeometryIndex, GeometryWeight, GetBandIndex, GetComponentIndex, Retag},
|
||||
loose::LooseIndex,
|
||||
Layout,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ pub mod draw;
|
|||
pub mod graph;
|
||||
#[macro_use]
|
||||
pub mod layout;
|
||||
pub mod dsn;
|
||||
pub mod math;
|
||||
pub mod mesh;
|
||||
pub mod router;
|
||||
pub mod tracer;
|
||||
pub mod triangulation;
|
||||
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> {
|
||||
pub fn new(rules: R) -> Self {
|
||||
Router {
|
||||
layout: Layout::new(rules),
|
||||
}
|
||||
pub fn new(layout: Layout<R>) -> Self {
|
||||
Router { layout }
|
||||
}
|
||||
|
||||
pub fn route_band(
|
||||
|
|
|
|||
|
|
@ -7,9 +7,7 @@ use crate::{
|
|||
bend::{BendIndex, FixedBendIndex, LooseBendIndex},
|
||||
dot::FixedDotIndex,
|
||||
graph::{GeometryIndex, MakePrimitive},
|
||||
primitive::{
|
||||
FixedBend, FixedDot, GetFirstRail, GetInnerOuter, GetLayout, LooseBend, Primitive,
|
||||
},
|
||||
primitive::{FixedBend, FixedDot, GetFirstRail, GetInnerOuter, LooseBend, Primitive},
|
||||
rules::RulesTrait,
|
||||
Layout,
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue