mirror of https://codeberg.org/topola/topola.git
drawing,layout: move zones upwards, from drawing to layout
This generally largely drawings from groupings. We need this because it will be easier to handle all groupings on the level of layout as continents and bands, which are groupings too, are to be tracked there. There's a lot of rough edges when it comes to typing and contracts.
This commit is contained in:
parent
5cef59227a
commit
9feb32955c
|
|
@ -5,9 +5,10 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use topola::{
|
use topola::{
|
||||||
drawing::{graph::MakePrimitive, primitive::MakeShape, zone::MakePolygon, Drawing},
|
drawing::{graph::MakePrimitive, primitive::MakeShape, Drawing},
|
||||||
dsn::{design::DsnDesign, rules::DsnRules},
|
dsn::{design::DsnDesign, rules::DsnRules},
|
||||||
geometry::primitive::{BendShape, DotShape, PrimitiveShape, SegShape},
|
geometry::primitive::{BendShape, DotShape, PrimitiveShape, SegShape},
|
||||||
|
layout::{zone::MakePolygon, Layout},
|
||||||
math::Circle,
|
math::Circle,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -24,7 +25,7 @@ pub struct App {
|
||||||
text_channel: (Sender<String>, Receiver<String>),
|
text_channel: (Sender<String>, Receiver<String>),
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
drawing: Option<Drawing<DsnRules>>,
|
layout: Option<Layout<DsnRules>>,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
from_rect: egui::emath::Rect,
|
from_rect: egui::emath::Rect,
|
||||||
|
|
@ -36,7 +37,7 @@ impl Default for App {
|
||||||
// Example stuff:
|
// Example stuff:
|
||||||
label: "Hello World!".to_owned(),
|
label: "Hello World!".to_owned(),
|
||||||
text_channel: channel(),
|
text_channel: channel(),
|
||||||
drawing: None,
|
layout: None,
|
||||||
from_rect: egui::Rect::from_x_y_ranges(0.0..=1000000.0, 0.0..=500000.0),
|
from_rect: egui::Rect::from_x_y_ranges(0.0..=1000000.0, 0.0..=500000.0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -65,12 +66,12 @@ 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();
|
||||||
self.drawing = Some(design.make_drawing());
|
self.layout = Some(design.make_layout());
|
||||||
}
|
}
|
||||||
} 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();
|
||||||
self.drawing = Some(design.make_drawing());
|
self.layout = Some(design.make_layout());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,27 +139,27 @@ impl eframe::App for App {
|
||||||
let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect);
|
let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect);
|
||||||
let mut painter = Painter::new(ui, transform);
|
let mut painter = Painter::new(ui, transform);
|
||||||
|
|
||||||
if let Some(drawing) = &self.drawing {
|
if let Some(layout) = &self.layout {
|
||||||
for node in drawing.layer_primitive_nodes(1) {
|
for node in layout.drawing().layer_primitive_nodes(1) {
|
||||||
let shape = node.primitive(drawing).shape();
|
let shape = node.primitive(layout.drawing()).shape();
|
||||||
painter.paint_shape(&shape, egui::Color32::from_rgb(52, 52, 200));
|
painter.paint_shape(&shape, egui::Color32::from_rgb(52, 52, 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
for zone in drawing.layer_zones(1) {
|
for zone in layout.layer_zones(1) {
|
||||||
painter.paint_polygon(
|
painter.paint_polygon(
|
||||||
&zone.polygon(&drawing),
|
&zone.polygon(&layout.drawing()),
|
||||||
egui::Color32::from_rgb(52, 52, 200),
|
egui::Color32::from_rgb(52, 52, 200),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
for node in drawing.layer_primitive_nodes(0) {
|
for node in layout.drawing().layer_primitive_nodes(0) {
|
||||||
let shape = node.primitive(drawing).shape();
|
let shape = node.primitive(layout.drawing()).shape();
|
||||||
painter.paint_shape(&shape, egui::Color32::from_rgb(200, 52, 52));
|
painter.paint_shape(&shape, egui::Color32::from_rgb(200, 52, 52));
|
||||||
}
|
}
|
||||||
|
|
||||||
for zone in drawing.layer_zones(0) {
|
for zone in layout.layer_zones(0) {
|
||||||
painter.paint_polygon(
|
painter.paint_polygon(
|
||||||
&zone.polygon(&drawing),
|
&zone.polygon(&layout.drawing()),
|
||||||
egui::Color32::from_rgb(200, 52, 52),
|
egui::Color32::from_rgb(200, 52, 52),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ use topola::drawing::primitive::MakeShape;
|
||||||
use topola::drawing::rules::{Conditions, RulesTrait};
|
use topola::drawing::rules::{Conditions, RulesTrait};
|
||||||
use topola::drawing::seg::FixedSegWeight;
|
use topola::drawing::seg::FixedSegWeight;
|
||||||
use topola::drawing::zone::MakePolygon;
|
use topola::drawing::zone::MakePolygon;
|
||||||
use topola::drawing::{Drawing, Infringement, LayoutException};
|
use topola::drawing::{Infringement, Layout, LayoutException};
|
||||||
use topola::dsn::design::DsnDesign;
|
use topola::dsn::design::DsnDesign;
|
||||||
use topola::geometry::primitive::{PrimitiveShape, PrimitiveShapeTrait};
|
use topola::geometry::primitive::{PrimitiveShape, PrimitiveShapeTrait};
|
||||||
use topola::layout::connectivity::BandIndex;
|
use topola::layout::connectivity::BandIndex;
|
||||||
|
|
@ -80,7 +80,7 @@ impl RulesTrait for SimpleRules {
|
||||||
// Clunky enum to work around borrow checker.
|
// Clunky enum to work around borrow checker.
|
||||||
enum RouterOrDrawing<'a, R: RulesTrait> {
|
enum RouterOrDrawing<'a, R: RulesTrait> {
|
||||||
Router(&'a mut Router<R>),
|
Router(&'a mut Router<R>),
|
||||||
Layout(&'a Drawing<R>),
|
Layout(&'a Layout<R>),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EmptyRouterObserver;
|
struct EmptyRouterObserver;
|
||||||
|
|
@ -260,7 +260,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 drawing = design.make_drawing();
|
let drawing = design.make_layout();
|
||||||
let layout = Layout::new(drawing);
|
let layout = Layout::new(drawing);
|
||||||
let mut router = Router::new(layout);
|
let mut router = Router::new(layout);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,7 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
|
||||||
Some(self.guide().head(prev_dot))
|
Some(self.guide().head(prev_dot))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn guide(&self) -> Guide<R> {
|
fn guide(&self) -> Guide<impl Copy, R> {
|
||||||
Guide::new(self.layout.drawing())
|
Guide::new(self.layout.drawing())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,12 @@ use super::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Collect<'a, R: RulesTrait> {
|
pub struct Collect<'a, GW: Copy, R: RulesTrait> {
|
||||||
drawing: &'a Drawing<R>,
|
drawing: &'a Drawing<GW, R>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> Collect<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> Collect<'a, GW, R> {
|
||||||
pub fn new(drawing: &'a Drawing<R>) -> Self {
|
pub fn new(drawing: &'a Drawing<GW, R>) -> Self {
|
||||||
Self { drawing }
|
Self { drawing }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,13 @@ use contracts::debug_ensures;
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
|
|
||||||
use rstar::{RTreeObject, AABB};
|
use rstar::{RTree, RTreeObject, AABB};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use super::graph::GetLayer;
|
use super::graph::GetLayer;
|
||||||
use super::loose::{GetNextLoose, Loose, LooseIndex};
|
use super::loose::{GetNextLoose, Loose, LooseIndex};
|
||||||
use super::rules::RulesTrait;
|
use super::rules::RulesTrait;
|
||||||
use super::segbend::Segbend;
|
use super::segbend::Segbend;
|
||||||
use super::zone::SolidZoneWeight;
|
|
||||||
use crate::drawing::bend::BendIndex;
|
use crate::drawing::bend::BendIndex;
|
||||||
use crate::drawing::collect::Collect;
|
use crate::drawing::collect::Collect;
|
||||||
use crate::drawing::dot::DotWeight;
|
use crate::drawing::dot::DotWeight;
|
||||||
|
|
@ -26,9 +25,9 @@ use crate::drawing::{
|
||||||
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
|
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
|
||||||
SeqLooseSegIndex, SeqLooseSegWeight,
|
SeqLooseSegIndex, SeqLooseSegWeight,
|
||||||
},
|
},
|
||||||
zone::{PourZoneIndex, SolidZoneIndex, ZoneIndex, ZoneWeight},
|
|
||||||
};
|
};
|
||||||
use crate::geometry::grouping::GroupingManagerTrait;
|
use crate::geometry::grouping::GroupingManagerTrait;
|
||||||
|
use crate::geometry::with_rtree::BboxedIndex;
|
||||||
use crate::geometry::Node;
|
use crate::geometry::Node;
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
primitive::{PrimitiveShape, PrimitiveShapeTrait},
|
primitive::{PrimitiveShape, PrimitiveShapeTrait},
|
||||||
|
|
@ -37,6 +36,7 @@ use crate::geometry::{
|
||||||
SegWeightTrait,
|
SegWeightTrait,
|
||||||
};
|
};
|
||||||
use crate::graph::{GenericIndex, GetNodeIndex};
|
use crate::graph::{GenericIndex, GetNodeIndex};
|
||||||
|
use crate::layout::zone::{ZoneIndex, ZoneWeight};
|
||||||
use crate::math::NoTangents;
|
use crate::math::NoTangents;
|
||||||
use crate::wraparoundable::{GetWraparound, Wraparoundable, WraparoundableIndex};
|
use crate::wraparoundable::{GetWraparound, Wraparoundable, WraparoundableIndex};
|
||||||
|
|
||||||
|
|
@ -70,13 +70,13 @@ pub struct Collision(pub PrimitiveShape, pub PrimitiveIndex);
|
||||||
pub struct AlreadyConnected(pub usize, pub PrimitiveIndex);
|
pub struct AlreadyConnected(pub usize, pub PrimitiveIndex);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Drawing<R: RulesTrait> {
|
pub struct Drawing<GW: Copy, R: RulesTrait> {
|
||||||
geometry_with_rtree: GeometryWithRtree<
|
geometry_with_rtree: GeometryWithRtree<
|
||||||
PrimitiveWeight,
|
PrimitiveWeight,
|
||||||
DotWeight,
|
DotWeight,
|
||||||
SegWeight,
|
SegWeight,
|
||||||
BendWeight,
|
BendWeight,
|
||||||
ZoneWeight,
|
GW,
|
||||||
PrimitiveIndex,
|
PrimitiveIndex,
|
||||||
DotIndex,
|
DotIndex,
|
||||||
SegIndex,
|
SegIndex,
|
||||||
|
|
@ -85,7 +85,7 @@ pub struct Drawing<R: RulesTrait> {
|
||||||
rules: R,
|
rules: R,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RulesTrait> Drawing<R> {
|
impl<GW: Copy, R: RulesTrait> Drawing<GW, R> {
|
||||||
pub fn new(rules: R) -> Self {
|
pub fn new(rules: R) -> Self {
|
||||||
Self {
|
Self {
|
||||||
geometry_with_rtree: GeometryWithRtree::new(2),
|
geometry_with_rtree: GeometryWithRtree::new(2),
|
||||||
|
|
@ -153,19 +153,7 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
#[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, Infringement> {
|
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, Infringement> {
|
||||||
self.add_dot_infringably(weight, None, None)
|
self.add_dot_infringably(weight, None)
|
||||||
}
|
|
||||||
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 1))]
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count() + 1))]
|
|
||||||
#[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
|
||||||
#[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
|
||||||
pub fn add_zone_fixed_dot(
|
|
||||||
&mut self,
|
|
||||||
weight: FixedDotWeight,
|
|
||||||
zone: ZoneIndex,
|
|
||||||
) -> Result<FixedDotIndex, Infringement> {
|
|
||||||
self.add_dot_infringably(weight, Some(zone), None)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 1))]
|
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 1))]
|
||||||
|
|
@ -173,7 +161,6 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
fn add_dot_infringably<W: DotWeightTrait<PrimitiveWeight> + GetLayer>(
|
fn add_dot_infringably<W: DotWeightTrait<PrimitiveWeight> + GetLayer>(
|
||||||
&mut self,
|
&mut self,
|
||||||
weight: W,
|
weight: W,
|
||||||
maybe_zone: Option<ZoneIndex>,
|
|
||||||
infringables: Option<&[PrimitiveIndex]>,
|
infringables: Option<&[PrimitiveIndex]>,
|
||||||
) -> Result<GenericIndex<W>, Infringement>
|
) -> Result<GenericIndex<W>, Infringement>
|
||||||
where
|
where
|
||||||
|
|
@ -182,11 +169,6 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
let dot = self.geometry_with_rtree.add_dot(weight);
|
let dot = self.geometry_with_rtree.add_dot(weight);
|
||||||
self.fail_and_remove_if_infringes_except(dot.into(), infringables)?;
|
self.fail_and_remove_if_infringes_except(dot.into(), infringables)?;
|
||||||
|
|
||||||
if let Some(zone) = maybe_zone {
|
|
||||||
self.geometry_with_rtree
|
|
||||||
.assign_to_grouping(dot, GenericIndex::new(zone.node_index()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(dot)
|
Ok(dot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,21 +182,7 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
to: FixedDotIndex,
|
to: FixedDotIndex,
|
||||||
weight: FixedSegWeight,
|
weight: FixedSegWeight,
|
||||||
) -> Result<FixedSegIndex, Infringement> {
|
) -> Result<FixedSegIndex, Infringement> {
|
||||||
self.add_seg_infringably(from.into(), to.into(), weight, None, None)
|
self.add_seg_infringably(from.into(), to.into(), weight, None)
|
||||||
}
|
|
||||||
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 1))]
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count() + 3))]
|
|
||||||
#[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
|
||||||
#[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
|
||||||
pub fn add_zone_fixed_seg(
|
|
||||||
&mut self,
|
|
||||||
from: FixedDotIndex,
|
|
||||||
to: FixedDotIndex,
|
|
||||||
weight: FixedSegWeight,
|
|
||||||
zone: ZoneIndex,
|
|
||||||
) -> Result<FixedSegIndex, Infringement> {
|
|
||||||
self.add_seg_infringably(from.into(), to.into(), weight, Some(zone), None)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 4))]
|
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 4))]
|
||||||
|
|
@ -418,16 +386,16 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
cw: bool,
|
cw: bool,
|
||||||
infringables: Option<&[PrimitiveIndex]>,
|
infringables: Option<&[PrimitiveIndex]>,
|
||||||
) -> Result<Segbend, LayoutException> {
|
) -> Result<Segbend, LayoutException> {
|
||||||
let seg_to = self.add_dot_infringably(dot_weight, None, infringables)?;
|
let seg_to = self.add_dot_infringably(dot_weight, infringables)?;
|
||||||
let seg = self
|
let seg = self
|
||||||
.add_seg_infringably(from, seg_to.into(), seg_weight, None, infringables)
|
.add_seg_infringably(from, seg_to.into(), seg_weight, infringables)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
self.geometry_with_rtree.remove_dot(seg_to.into());
|
self.geometry_with_rtree.remove_dot(seg_to.into());
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let to = self
|
let to = self
|
||||||
.add_dot_infringably(dot_weight, None, infringables)
|
.add_dot_infringably(dot_weight, infringables)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
self.geometry_with_rtree.remove_seg(seg.into());
|
self.geometry_with_rtree.remove_seg(seg.into());
|
||||||
self.geometry_with_rtree.remove_dot(seg_to.into());
|
self.geometry_with_rtree.remove_dot(seg_to.into());
|
||||||
|
|
@ -485,7 +453,7 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
to: FixedDotIndex,
|
to: FixedDotIndex,
|
||||||
weight: LoneLooseSegWeight,
|
weight: LoneLooseSegWeight,
|
||||||
) -> Result<LoneLooseSegIndex, Infringement> {
|
) -> Result<LoneLooseSegIndex, Infringement> {
|
||||||
let seg = self.add_seg_infringably(from.into(), to.into(), weight, None, Some(&[]))?;
|
let seg = self.add_seg_infringably(from.into(), to.into(), weight, Some(&[]))?;
|
||||||
Ok(seg)
|
Ok(seg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -499,7 +467,7 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
to: LooseDotIndex,
|
to: LooseDotIndex,
|
||||||
weight: SeqLooseSegWeight,
|
weight: SeqLooseSegWeight,
|
||||||
) -> Result<SeqLooseSegIndex, Infringement> {
|
) -> Result<SeqLooseSegIndex, Infringement> {
|
||||||
let seg = self.add_seg_infringably(from, to.into(), weight, None, Some(&[]))?;
|
let seg = self.add_seg_infringably(from, to.into(), weight, Some(&[]))?;
|
||||||
Ok(seg)
|
Ok(seg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -512,7 +480,6 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
from: DotIndex,
|
from: DotIndex,
|
||||||
to: DotIndex,
|
to: DotIndex,
|
||||||
weight: W,
|
weight: W,
|
||||||
maybe_zone: Option<ZoneIndex>,
|
|
||||||
infringables: Option<&[PrimitiveIndex]>,
|
infringables: Option<&[PrimitiveIndex]>,
|
||||||
) -> Result<GenericIndex<W>, Infringement>
|
) -> Result<GenericIndex<W>, Infringement>
|
||||||
where
|
where
|
||||||
|
|
@ -521,11 +488,6 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
let seg = self.geometry_with_rtree.add_seg(from, to, weight);
|
let seg = self.geometry_with_rtree.add_seg(from, to, weight);
|
||||||
self.fail_and_remove_if_infringes_except(seg.into(), infringables)?;
|
self.fail_and_remove_if_infringes_except(seg.into(), infringables)?;
|
||||||
|
|
||||||
if let Some(zone) = maybe_zone {
|
|
||||||
self.geometry_with_rtree
|
|
||||||
.assign_to_grouping(seg, GenericIndex::new(zone.node_index()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(seg)
|
Ok(seg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -647,14 +609,6 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
self.geometry_with_rtree.flip_bend(bend.into());
|
self.geometry_with_rtree.flip_bend(bend.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_solid_zone(&mut self, weight: SolidZoneWeight) -> SolidZoneIndex {
|
|
||||||
GenericIndex::new(
|
|
||||||
self.geometry_with_rtree
|
|
||||||
.add_grouping(weight.into())
|
|
||||||
.node_index(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn segbend(&self, dot: LooseDotIndex) -> Segbend {
|
pub fn segbend(&self, dot: LooseDotIndex) -> Segbend {
|
||||||
Segbend::from_dot(dot, self)
|
Segbend::from_dot(dot, self)
|
||||||
}
|
}
|
||||||
|
|
@ -709,60 +663,12 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zones(&self) -> impl Iterator<Item = ZoneIndex> + '_ {
|
|
||||||
self.geometry_with_rtree
|
|
||||||
.rtree()
|
|
||||||
.iter()
|
|
||||||
.filter_map(|wrapper| {
|
|
||||||
if let Node::Grouping(zone) = wrapper.data {
|
|
||||||
Some(match self.geometry().grouping_weight(zone) {
|
|
||||||
ZoneWeight::Solid(..) => {
|
|
||||||
ZoneIndex::Solid(SolidZoneIndex::new(zone.node_index()))
|
|
||||||
}
|
|
||||||
ZoneWeight::Pour(..) => {
|
|
||||||
ZoneIndex::Pour(PourZoneIndex::new(zone.node_index()))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn layer_zones(&self, layer: u64) -> impl Iterator<Item = ZoneIndex> + '_ {
|
|
||||||
self.geometry_with_rtree
|
|
||||||
.rtree()
|
|
||||||
.locate_in_envelope_intersecting(&AABB::from_corners(
|
|
||||||
[-f64::INFINITY, -f64::INFINITY, layer as f64],
|
|
||||||
[f64::INFINITY, f64::INFINITY, layer as f64],
|
|
||||||
))
|
|
||||||
.filter_map(|wrapper| {
|
|
||||||
if let Node::Grouping(zone) = wrapper.data {
|
|
||||||
Some(match self.geometry().grouping_weight(zone) {
|
|
||||||
ZoneWeight::Solid(..) => {
|
|
||||||
ZoneIndex::Solid(SolidZoneIndex::new(zone.node_index()))
|
|
||||||
}
|
|
||||||
ZoneWeight::Pour(..) => {
|
|
||||||
ZoneIndex::Pour(PourZoneIndex::new(zone.node_index()))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn zone_members(&self, zone: ZoneIndex) -> impl Iterator<Item = PrimitiveIndex> + '_ {
|
|
||||||
self.geometry()
|
|
||||||
.grouping_members(GenericIndex::new(zone.node_index()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn node_count(&self) -> usize {
|
pub fn node_count(&self) -> usize {
|
||||||
self.geometry_with_rtree.graph().node_count()
|
self.geometry_with_rtree.graph().node_count()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RulesTrait> Drawing<R> {
|
impl<GW: Copy, R: RulesTrait> Drawing<GW, R> {
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), Infringement> {
|
pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), Infringement> {
|
||||||
|
|
@ -906,7 +812,7 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RulesTrait> Drawing<R> {
|
impl<GW: Copy, R: RulesTrait> Drawing<GW, R> {
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
pub fn geometry(
|
pub fn geometry(
|
||||||
|
|
@ -916,7 +822,7 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
DotWeight,
|
DotWeight,
|
||||||
SegWeight,
|
SegWeight,
|
||||||
BendWeight,
|
BendWeight,
|
||||||
ZoneWeight,
|
GW,
|
||||||
PrimitiveIndex,
|
PrimitiveIndex,
|
||||||
DotIndex,
|
DotIndex,
|
||||||
SegIndex,
|
SegIndex,
|
||||||
|
|
@ -925,6 +831,12 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
self.geometry_with_rtree.geometry()
|
self.geometry_with_rtree.geometry()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
|
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
|
pub fn rtree(&self) -> &RTree<BboxedIndex<Node<PrimitiveIndex, GenericIndex<GW>>>> {
|
||||||
|
self.geometry_with_rtree.rtree()
|
||||||
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
pub fn rules(&self) -> &R {
|
pub fn rules(&self) -> &R {
|
||||||
|
|
@ -933,31 +845,46 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
|
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
pub fn guide(&self) -> Guide<R> {
|
pub fn guide(&self) -> Guide<GW, R> {
|
||||||
Guide::new(self)
|
Guide::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
pub fn collect(&self) -> Collect<R> {
|
pub fn collect(&self) -> Collect<GW, R> {
|
||||||
Collect::new(self)
|
Collect::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
pub fn primitive<W>(&self, index: GenericIndex<W>) -> GenericPrimitive<W, R> {
|
pub fn primitive<W>(&self, index: GenericIndex<W>) -> GenericPrimitive<W, GW, R> {
|
||||||
GenericPrimitive::new(index, self)
|
GenericPrimitive::new(index, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
pub fn wraparoundable(&self, index: WraparoundableIndex) -> Wraparoundable<R> {
|
pub fn wraparoundable(&self, index: WraparoundableIndex) -> Wraparoundable<GW, R> {
|
||||||
Wraparoundable::new(index, self)
|
Wraparoundable::new(index, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
pub fn loose(&self, index: LooseIndex) -> Loose<R> {
|
pub fn loose(&self, index: LooseIndex) -> Loose<GW, R> {
|
||||||
Loose::new(index, self)
|
Loose::new(index, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<GW: Copy, R: RulesTrait> GroupingManagerTrait<GW, GenericIndex<GW>> for Drawing<GW, R> {
|
||||||
|
fn add_grouping(&mut self, weight: GW) -> GenericIndex<GW> {
|
||||||
|
self.geometry_with_rtree.add_grouping(weight)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_grouping(&mut self, grouping: GenericIndex<GW>) {
|
||||||
|
self.geometry_with_rtree.remove_grouping(grouping);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assign_to_grouping<W>(&mut self, primitive: GenericIndex<W>, grouping: GenericIndex<GW>) {
|
||||||
|
self.geometry_with_rtree
|
||||||
|
.assign_to_grouping(primitive, grouping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,10 @@ pub trait GetMaybeNet {
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait MakePrimitive {
|
pub trait MakePrimitive {
|
||||||
fn primitive<'a, R: RulesTrait>(&self, drawing: &'a Drawing<R>) -> Primitive<'a, R>;
|
fn primitive<'a, GW: Copy, R: RulesTrait>(
|
||||||
|
&self,
|
||||||
|
drawing: &'a Drawing<GW, R>,
|
||||||
|
) -> Primitive<'a, GW, R>;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_weight {
|
macro_rules! impl_weight {
|
||||||
|
|
@ -58,7 +61,10 @@ macro_rules! impl_weight {
|
||||||
pub type $index_struct = GenericIndex<$weight_struct>;
|
pub type $index_struct = GenericIndex<$weight_struct>;
|
||||||
|
|
||||||
impl MakePrimitive for $index_struct {
|
impl MakePrimitive for $index_struct {
|
||||||
fn primitive<'a, R: RulesTrait>(&self, drawing: &'a Drawing<R>) -> Primitive<'a, R> {
|
fn primitive<'a, GW: Copy, R: RulesTrait>(
|
||||||
|
&self,
|
||||||
|
drawing: &'a Drawing<GW, R>,
|
||||||
|
) -> Primitive<'a, GW, R> {
|
||||||
Primitive::$weight_variant(GenericPrimitive::new(*self, drawing))
|
Primitive::$weight_variant(GenericPrimitive::new(*self, drawing))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,12 +56,12 @@ impl HeadTrait for SegbendHead {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Guide<'a, R: RulesTrait> {
|
pub struct Guide<'a, GW: Copy, R: RulesTrait> {
|
||||||
drawing: &'a Drawing<R>,
|
drawing: &'a Drawing<GW, R>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> Guide<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> Guide<'a, GW, R> {
|
||||||
pub fn new(drawing: &'a Drawing<R>) -> Self {
|
pub fn new(drawing: &'a Drawing<GW, R>) -> Self {
|
||||||
Self { drawing }
|
Self { drawing }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,16 +40,16 @@ impl From<LooseIndex> for PrimitiveIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(GetNextLoose, GetLayout, GetNodeIndex)]
|
#[enum_dispatch(GetNextLoose, GetDrawing, GetNodeIndex)]
|
||||||
pub enum Loose<'a, R: RulesTrait> {
|
pub enum Loose<'a, GW: Copy, R: RulesTrait> {
|
||||||
Dot(LooseDot<'a, R>),
|
Dot(LooseDot<'a, GW, R>),
|
||||||
LoneSeg(LoneLooseSeg<'a, R>),
|
LoneSeg(LoneLooseSeg<'a, GW, R>),
|
||||||
SeqSeg(SeqLooseSeg<'a, R>),
|
SeqSeg(SeqLooseSeg<'a, GW, R>),
|
||||||
Bend(LooseBend<'a, R>),
|
Bend(LooseBend<'a, GW, R>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> Loose<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> Loose<'a, GW, R> {
|
||||||
pub fn new(index: LooseIndex, drawing: &'a Drawing<R>) -> Self {
|
pub fn new(index: LooseIndex, drawing: &'a Drawing<GW, R>) -> Self {
|
||||||
match index {
|
match index {
|
||||||
LooseIndex::Dot(dot) => drawing.primitive(dot).into(),
|
LooseIndex::Dot(dot) => drawing.primitive(dot).into(),
|
||||||
LooseIndex::LoneSeg(seg) => drawing.primitive(seg).into(),
|
LooseIndex::LoneSeg(seg) => drawing.primitive(seg).into(),
|
||||||
|
|
@ -59,7 +59,7 @@ impl<'a, R: RulesTrait> Loose<'a, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetNextLoose for LooseDot<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetNextLoose for LooseDot<'a, GW, R> {
|
||||||
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
||||||
let bend = self.bend();
|
let bend = self.bend();
|
||||||
let Some(prev) = maybe_prev else {
|
let Some(prev) = maybe_prev else {
|
||||||
|
|
@ -74,13 +74,13 @@ impl<'a, R: RulesTrait> GetNextLoose for LooseDot<'a, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetNextLoose for LoneLooseSeg<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetNextLoose for LoneLooseSeg<'a, GW, R> {
|
||||||
fn next_loose(&self, _maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
fn next_loose(&self, _maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetNextLoose for SeqLooseSeg<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetNextLoose for SeqLooseSeg<'a, GW, R> {
|
||||||
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
||||||
let ends = self.joints();
|
let ends = self.joints();
|
||||||
let Some(prev) = maybe_prev else {
|
let Some(prev) = maybe_prev else {
|
||||||
|
|
@ -98,7 +98,7 @@ impl<'a, R: RulesTrait> GetNextLoose for SeqLooseSeg<'a, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetNextLoose for LooseBend<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetNextLoose for LooseBend<'a, GW, R> {
|
||||||
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
||||||
let ends = self.joints();
|
let ends = self.joints();
|
||||||
let Some(prev) = maybe_prev else {
|
let Some(prev) = maybe_prev else {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,5 @@ pub mod primitive;
|
||||||
pub mod rules;
|
pub mod rules;
|
||||||
pub mod seg;
|
pub mod seg;
|
||||||
pub mod segbend;
|
pub mod segbend;
|
||||||
pub mod zone;
|
|
||||||
|
|
||||||
pub use drawing::*;
|
pub use drawing::*;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ use crate::{
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait GetDrawing<'a, R: RulesTrait> {
|
pub trait GetDrawing<'a, R: RulesTrait> {
|
||||||
fn drawing(&self) -> &Drawing<R>;
|
fn drawing(&self) -> &Drawing<impl Copy, R>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
|
|
@ -117,7 +117,9 @@ pub trait GetInnerOuter<'a, R: RulesTrait>: GetDrawing<'a, R> + GetBendIndex {
|
||||||
|
|
||||||
macro_rules! impl_primitive {
|
macro_rules! impl_primitive {
|
||||||
($primitive_struct:ident, $weight_struct:ident) => {
|
($primitive_struct:ident, $weight_struct:ident) => {
|
||||||
impl<'a, R: RulesTrait> GetWeight<$weight_struct> for $primitive_struct<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetWeight<$weight_struct>
|
||||||
|
for $primitive_struct<'a, GW, R>
|
||||||
|
{
|
||||||
fn weight(&self) -> $weight_struct {
|
fn weight(&self) -> $weight_struct {
|
||||||
if let PrimitiveWeight::$primitive_struct(weight) = self.tagged_weight() {
|
if let PrimitiveWeight::$primitive_struct(weight) = self.tagged_weight() {
|
||||||
weight
|
weight
|
||||||
|
|
@ -127,13 +129,13 @@ macro_rules! impl_primitive {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetLayer for $primitive_struct<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetLayer for $primitive_struct<'a, GW, R> {
|
||||||
fn layer(&self) -> u64 {
|
fn layer(&self) -> u64 {
|
||||||
self.weight().layer()
|
self.weight().layer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetMaybeNet for $primitive_struct<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetMaybeNet for $primitive_struct<'a, GW, R> {
|
||||||
fn maybe_net(&self) -> Option<usize> {
|
fn maybe_net(&self) -> Option<usize> {
|
||||||
self.weight().maybe_net()
|
self.weight().maybe_net()
|
||||||
}
|
}
|
||||||
|
|
@ -157,29 +159,29 @@ macro_rules! impl_loose_primitive {
|
||||||
GetLayer,
|
GetLayer,
|
||||||
GetMaybeNet,
|
GetMaybeNet,
|
||||||
GetWidth,
|
GetWidth,
|
||||||
GetLayout,
|
GetDrawing,
|
||||||
MakeShape,
|
MakeShape,
|
||||||
GetLimbs,
|
GetLimbs,
|
||||||
GetConditions
|
GetConditions
|
||||||
)]
|
)]
|
||||||
pub enum Primitive<'a, R: RulesTrait> {
|
pub enum Primitive<'a, GW: Copy, R: RulesTrait> {
|
||||||
FixedDot(FixedDot<'a, R>),
|
FixedDot(FixedDot<'a, GW, R>),
|
||||||
LooseDot(LooseDot<'a, R>),
|
LooseDot(LooseDot<'a, GW, R>),
|
||||||
FixedSeg(FixedSeg<'a, R>),
|
FixedSeg(FixedSeg<'a, GW, R>),
|
||||||
LoneLooseSeg(LoneLooseSeg<'a, R>),
|
LoneLooseSeg(LoneLooseSeg<'a, GW, R>),
|
||||||
SeqLooseSeg(SeqLooseSeg<'a, R>),
|
SeqLooseSeg(SeqLooseSeg<'a, GW, R>),
|
||||||
FixedBend(FixedBend<'a, R>),
|
FixedBend(FixedBend<'a, GW, R>),
|
||||||
LooseBend(LooseBend<'a, R>),
|
LooseBend(LooseBend<'a, GW, R>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GenericPrimitive<'a, W, R: RulesTrait> {
|
pub struct GenericPrimitive<'a, W, GW: Copy, R: RulesTrait> {
|
||||||
pub index: GenericIndex<W>,
|
pub index: GenericIndex<W>,
|
||||||
drawing: &'a Drawing<R>,
|
drawing: &'a Drawing<GW, R>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W, R: RulesTrait> GenericPrimitive<'a, W, R> {
|
impl<'a, W, GW: Copy, R: RulesTrait> GenericPrimitive<'a, W, GW, R> {
|
||||||
pub fn new(index: GenericIndex<W>, drawing: &'a Drawing<R>) -> Self {
|
pub fn new(index: GenericIndex<W>, drawing: &'a Drawing<GW, R>) -> Self {
|
||||||
Self { index, drawing }
|
Self { index, drawing }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,41 +199,43 @@ impl<'a, W, R: RulesTrait> GenericPrimitive<'a, W, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primitive<WW>(&self, index: GenericIndex<WW>) -> GenericPrimitive<WW, R> {
|
fn primitive<WW>(&self, index: GenericIndex<WW>) -> GenericPrimitive<WW, GW, R> {
|
||||||
GenericPrimitive::new(index, &self.drawing)
|
GenericPrimitive::new(index, &self.drawing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W, R: RulesTrait> GetInterior<PrimitiveIndex> for GenericPrimitive<'a, W, R> {
|
impl<'a, W, GW: Copy, R: RulesTrait> GetInterior<PrimitiveIndex>
|
||||||
|
for GenericPrimitive<'a, W, GW, R>
|
||||||
|
{
|
||||||
fn interior(&self) -> Vec<PrimitiveIndex> {
|
fn interior(&self) -> Vec<PrimitiveIndex> {
|
||||||
vec![self.tagged_weight().retag(self.index.node_index())]
|
vec![self.tagged_weight().retag(self.index.node_index())]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W, R: RulesTrait> GetDrawing<'a, R> for GenericPrimitive<'a, W, R> {
|
impl<'a, W, GW: Copy, R: RulesTrait> GetDrawing<'a, R> for GenericPrimitive<'a, W, GW, R> {
|
||||||
fn drawing(&self) -> &Drawing<R> {
|
fn drawing(&self) -> &Drawing<impl Copy, R> {
|
||||||
self.drawing
|
self.drawing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W, R: RulesTrait> GetNodeIndex for GenericPrimitive<'a, W, R> {
|
impl<'a, W, GW: Copy, R: RulesTrait> GetNodeIndex for GenericPrimitive<'a, W, GW, R> {
|
||||||
fn node_index(&self) -> NodeIndex<usize> {
|
fn node_index(&self) -> NodeIndex<usize> {
|
||||||
self.index.node_index()
|
self.index.node_index()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W: GetWidth, R: RulesTrait> GetWidth for GenericPrimitive<'a, W, R>
|
impl<'a, W: GetWidth, GW: Copy, R: RulesTrait> GetWidth for GenericPrimitive<'a, W, GW, R>
|
||||||
where
|
where
|
||||||
GenericPrimitive<'a, W, R>: GetWeight<W>,
|
GenericPrimitive<'a, W, GW, R>: GetWeight<W>,
|
||||||
{
|
{
|
||||||
fn width(&self) -> f64 {
|
fn width(&self) -> f64 {
|
||||||
self.weight().width()
|
self.weight().width()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W, R: RulesTrait> GetConditions for GenericPrimitive<'a, W, R>
|
impl<'a, W, GW: Copy, R: RulesTrait> GetConditions for GenericPrimitive<'a, W, GW, R>
|
||||||
where
|
where
|
||||||
GenericPrimitive<'a, W, R>: GetMaybeNet,
|
GenericPrimitive<'a, W, GW, R>: GetMaybeNet,
|
||||||
{
|
{
|
||||||
fn conditions(&self) -> Conditions {
|
fn conditions(&self) -> Conditions {
|
||||||
Conditions {
|
Conditions {
|
||||||
|
|
@ -242,10 +246,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type FixedDot<'a, R> = GenericPrimitive<'a, FixedDotWeight, R>;
|
pub type FixedDot<'a, GW, R> = GenericPrimitive<'a, FixedDotWeight, GW, R>;
|
||||||
impl_fixed_primitive!(FixedDot, FixedDotWeight);
|
impl_fixed_primitive!(FixedDot, FixedDotWeight);
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> FixedDot<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> FixedDot<'a, GW, R> {
|
||||||
pub fn first_loose(&self, _band: BandIndex) -> Option<LooseIndex> {
|
pub fn first_loose(&self, _band: BandIndex) -> Option<LooseIndex> {
|
||||||
self.drawing
|
self.drawing
|
||||||
.geometry()
|
.geometry()
|
||||||
|
|
@ -269,13 +273,13 @@ impl<'a, R: RulesTrait> FixedDot<'a, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> MakeShape for FixedDot<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> MakeShape for FixedDot<'a, GW, R> {
|
||||||
fn shape(&self) -> PrimitiveShape {
|
fn shape(&self) -> PrimitiveShape {
|
||||||
self.drawing.geometry().dot_shape(self.index.into())
|
self.drawing.geometry().dot_shape(self.index.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetLimbs for FixedDot<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetLimbs for FixedDot<'a, GW, R> {
|
||||||
fn segs(&self) -> Vec<SegIndex> {
|
fn segs(&self) -> Vec<SegIndex> {
|
||||||
self.drawing
|
self.drawing
|
||||||
.geometry()
|
.geometry()
|
||||||
|
|
@ -291,12 +295,12 @@ impl<'a, R: RulesTrait> GetLimbs for FixedDot<'a, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetFirstRail<'a, R> for FixedDot<'a, R> {}
|
impl<'a, GW: Copy, R: RulesTrait> GetFirstRail<'a, R> for FixedDot<'a, GW, R> {}
|
||||||
|
|
||||||
pub type LooseDot<'a, R> = GenericPrimitive<'a, LooseDotWeight, R>;
|
pub type LooseDot<'a, GW, R> = GenericPrimitive<'a, LooseDotWeight, GW, R>;
|
||||||
impl_loose_primitive!(LooseDot, LooseDotWeight);
|
impl_loose_primitive!(LooseDot, LooseDotWeight);
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> LooseDot<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> LooseDot<'a, GW, R> {
|
||||||
pub fn seg(&self) -> Option<SeqLooseSegIndex> {
|
pub fn seg(&self) -> Option<SeqLooseSegIndex> {
|
||||||
self.drawing
|
self.drawing
|
||||||
.geometry()
|
.geometry()
|
||||||
|
|
@ -315,13 +319,13 @@ impl<'a, R: RulesTrait> LooseDot<'a, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> MakeShape for LooseDot<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> MakeShape for LooseDot<'a, GW, R> {
|
||||||
fn shape(&self) -> PrimitiveShape {
|
fn shape(&self) -> PrimitiveShape {
|
||||||
self.drawing.geometry().dot_shape(self.index.into())
|
self.drawing.geometry().dot_shape(self.index.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetLimbs for LooseDot<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetLimbs for LooseDot<'a, GW, R> {
|
||||||
fn segs(&self) -> Vec<SegIndex> {
|
fn segs(&self) -> Vec<SegIndex> {
|
||||||
if let Some(seg) = self.seg() {
|
if let Some(seg) = self.seg() {
|
||||||
vec![seg.into()]
|
vec![seg.into()]
|
||||||
|
|
@ -335,18 +339,18 @@ impl<'a, R: RulesTrait> GetLimbs for LooseDot<'a, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type FixedSeg<'a, R> = GenericPrimitive<'a, FixedSegWeight, R>;
|
pub type FixedSeg<'a, GW, R> = GenericPrimitive<'a, FixedSegWeight, GW, R>;
|
||||||
impl_fixed_primitive!(FixedSeg, FixedSegWeight);
|
impl_fixed_primitive!(FixedSeg, FixedSegWeight);
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> MakeShape for FixedSeg<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> MakeShape for FixedSeg<'a, GW, R> {
|
||||||
fn shape(&self) -> PrimitiveShape {
|
fn shape(&self) -> PrimitiveShape {
|
||||||
self.drawing.geometry().seg_shape(self.index.into())
|
self.drawing.geometry().seg_shape(self.index.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetLimbs for FixedSeg<'a, R> {}
|
impl<'a, GW: Copy, R: RulesTrait> GetLimbs for FixedSeg<'a, GW, R> {}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetJoints<FixedDotIndex, FixedDotIndex> for FixedSeg<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetJoints<FixedDotIndex, FixedDotIndex> for FixedSeg<'a, GW, R> {
|
||||||
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||||
let (from, to) = self.drawing.geometry().seg_joints(self.index.into());
|
let (from, to) = self.drawing.geometry().seg_joints(self.index.into());
|
||||||
(
|
(
|
||||||
|
|
@ -356,20 +360,25 @@ impl<'a, R: RulesTrait> GetJoints<FixedDotIndex, FixedDotIndex> for FixedSeg<'a,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetOtherJoint<FixedDotIndex, FixedDotIndex> for FixedSeg<'a, R> {}
|
impl<'a, GW: Copy, R: RulesTrait> GetOtherJoint<FixedDotIndex, FixedDotIndex>
|
||||||
|
for FixedSeg<'a, GW, R>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
pub type LoneLooseSeg<'a, R> = GenericPrimitive<'a, LoneLooseSegWeight, R>;
|
pub type LoneLooseSeg<'a, GW, R> = GenericPrimitive<'a, LoneLooseSegWeight, GW, R>;
|
||||||
impl_loose_primitive!(LoneLooseSeg, LoneLooseSegWeight);
|
impl_loose_primitive!(LoneLooseSeg, LoneLooseSegWeight);
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> MakeShape for LoneLooseSeg<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> MakeShape for LoneLooseSeg<'a, GW, R> {
|
||||||
fn shape(&self) -> PrimitiveShape {
|
fn shape(&self) -> PrimitiveShape {
|
||||||
self.drawing.geometry().seg_shape(self.index.into())
|
self.drawing.geometry().seg_shape(self.index.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetLimbs for LoneLooseSeg<'a, R> {}
|
impl<'a, GW: Copy, R: RulesTrait> GetLimbs for LoneLooseSeg<'a, GW, R> {}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetJoints<FixedDotIndex, FixedDotIndex> for LoneLooseSeg<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetJoints<FixedDotIndex, FixedDotIndex>
|
||||||
|
for LoneLooseSeg<'a, GW, R>
|
||||||
|
{
|
||||||
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||||
let (from, to) = self.drawing.geometry().seg_joints(self.index.into());
|
let (from, to) = self.drawing.geometry().seg_joints(self.index.into());
|
||||||
(
|
(
|
||||||
|
|
@ -379,20 +388,23 @@ impl<'a, R: RulesTrait> GetJoints<FixedDotIndex, FixedDotIndex> for LoneLooseSeg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetOtherJoint<FixedDotIndex, FixedDotIndex> for LoneLooseSeg<'a, R> {}
|
impl<'a, GW: Copy, R: RulesTrait> GetOtherJoint<FixedDotIndex, FixedDotIndex>
|
||||||
|
for LoneLooseSeg<'a, GW, R>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
pub type SeqLooseSeg<'a, R> = GenericPrimitive<'a, SeqLooseSegWeight, R>;
|
pub type SeqLooseSeg<'a, GW, R> = GenericPrimitive<'a, SeqLooseSegWeight, GW, R>;
|
||||||
impl_loose_primitive!(SeqLooseSeg, SeqLooseSegWeight);
|
impl_loose_primitive!(SeqLooseSeg, SeqLooseSegWeight);
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> MakeShape for SeqLooseSeg<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> MakeShape for SeqLooseSeg<'a, GW, R> {
|
||||||
fn shape(&self) -> PrimitiveShape {
|
fn shape(&self) -> PrimitiveShape {
|
||||||
self.drawing.geometry().seg_shape(self.index.into())
|
self.drawing.geometry().seg_shape(self.index.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetLimbs for SeqLooseSeg<'a, R> {}
|
impl<'a, GW: Copy, R: RulesTrait> GetLimbs for SeqLooseSeg<'a, GW, R> {}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetJoints<DotIndex, LooseDotIndex> for SeqLooseSeg<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetJoints<DotIndex, LooseDotIndex> for SeqLooseSeg<'a, GW, R> {
|
||||||
fn joints(&self) -> (DotIndex, LooseDotIndex) {
|
fn joints(&self) -> (DotIndex, LooseDotIndex) {
|
||||||
let joints = self.drawing.geometry().seg_joints(self.index.into());
|
let joints = self.drawing.geometry().seg_joints(self.index.into());
|
||||||
if let DotWeight::Fixed(..) = self.drawing.geometry().dot_weight(joints.0) {
|
if let DotWeight::Fixed(..) = self.drawing.geometry().dot_weight(joints.0) {
|
||||||
|
|
@ -414,26 +426,29 @@ impl<'a, R: RulesTrait> GetJoints<DotIndex, LooseDotIndex> for SeqLooseSeg<'a, R
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetOtherJoint<DotIndex, LooseDotIndex> for SeqLooseSeg<'a, R> {}
|
impl<'a, GW: Copy, R: RulesTrait> GetOtherJoint<DotIndex, LooseDotIndex>
|
||||||
|
for SeqLooseSeg<'a, GW, R>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
pub type FixedBend<'a, R> = GenericPrimitive<'a, FixedBendWeight, R>;
|
pub type FixedBend<'a, GW, R> = GenericPrimitive<'a, FixedBendWeight, GW, R>;
|
||||||
impl_fixed_primitive!(FixedBend, FixedBendWeight);
|
impl_fixed_primitive!(FixedBend, FixedBendWeight);
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetBendIndex for FixedBend<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetBendIndex for FixedBend<'a, GW, R> {
|
||||||
fn bend_index(&self) -> BendIndex {
|
fn bend_index(&self) -> BendIndex {
|
||||||
self.index.into()
|
self.index.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> MakeShape for FixedBend<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> MakeShape for FixedBend<'a, GW, R> {
|
||||||
fn shape(&self) -> PrimitiveShape {
|
fn shape(&self) -> PrimitiveShape {
|
||||||
self.drawing.geometry().bend_shape(self.index.into())
|
self.drawing.geometry().bend_shape(self.index.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetLimbs for FixedBend<'a, R> {}
|
impl<'a, GW: Copy, R: RulesTrait> GetLimbs for FixedBend<'a, GW, R> {}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetJoints<FixedDotIndex, FixedDotIndex> for FixedBend<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetJoints<FixedDotIndex, FixedDotIndex> for FixedBend<'a, GW, R> {
|
||||||
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||||
let (from, to) = self.drawing.geometry().bend_joints(self.index.into());
|
let (from, to) = self.drawing.geometry().bend_joints(self.index.into());
|
||||||
(
|
(
|
||||||
|
|
@ -443,41 +458,44 @@ impl<'a, R: RulesTrait> GetJoints<FixedDotIndex, FixedDotIndex> for FixedBend<'a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetOtherJoint<FixedDotIndex, FixedDotIndex> for FixedBend<'a, R> {}
|
impl<'a, GW: Copy, R: RulesTrait> GetOtherJoint<FixedDotIndex, FixedDotIndex>
|
||||||
impl<'a, R: RulesTrait> GetFirstRail<'a, R> for FixedBend<'a, R> {}
|
for FixedBend<'a, GW, R>
|
||||||
impl<'a, R: RulesTrait> GetCore<'a, R> for FixedBend<'a, R> {} // TODO: Fixed bends don't have cores actually.
|
{
|
||||||
//impl<'a, R: QueryRules> GetInnerOuter for FixedBend<'a, R> {}
|
}
|
||||||
|
impl<'a, GW: Copy, R: RulesTrait> GetFirstRail<'a, R> for FixedBend<'a, GW, R> {}
|
||||||
|
impl<'a, GW: Copy, R: RulesTrait> GetCore<'a, R> for FixedBend<'a, GW, R> {} // TODO: Fixed bends don't have cores actually.
|
||||||
|
//impl<'a, R: QueryRules> GetInnerOuter for FixedBend<'a, GW, R> {}
|
||||||
|
|
||||||
pub type LooseBend<'a, R> = GenericPrimitive<'a, LooseBendWeight, R>;
|
pub type LooseBend<'a, GW, R> = GenericPrimitive<'a, LooseBendWeight, GW, R>;
|
||||||
impl_loose_primitive!(LooseBend, LooseBendWeight);
|
impl_loose_primitive!(LooseBend, LooseBendWeight);
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetBendIndex for LooseBend<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetBendIndex for LooseBend<'a, GW, R> {
|
||||||
fn bend_index(&self) -> BendIndex {
|
fn bend_index(&self) -> BendIndex {
|
||||||
self.index.into()
|
self.index.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> From<LooseBend<'a, R>> for BendIndex {
|
impl<'a, GW: Copy, R: RulesTrait> From<LooseBend<'a, GW, R>> for BendIndex {
|
||||||
fn from(bend: LooseBend<'a, R>) -> BendIndex {
|
fn from(bend: LooseBend<'a, GW, R>) -> BendIndex {
|
||||||
bend.index.into()
|
bend.index.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> MakeShape for LooseBend<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> MakeShape for LooseBend<'a, GW, R> {
|
||||||
fn shape(&self) -> PrimitiveShape {
|
fn shape(&self) -> PrimitiveShape {
|
||||||
self.drawing.geometry().bend_shape(self.index.into())
|
self.drawing.geometry().bend_shape(self.index.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetLimbs for LooseBend<'a, R> {}
|
impl<'a, GW: Copy, R: RulesTrait> GetLimbs for LooseBend<'a, GW, R> {}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetOffset for LooseBend<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetOffset for LooseBend<'a, GW, R> {
|
||||||
fn offset(&self) -> f64 {
|
fn offset(&self) -> f64 {
|
||||||
self.weight().offset
|
self.weight().offset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetJoints<LooseDotIndex, LooseDotIndex> for LooseBend<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetJoints<LooseDotIndex, LooseDotIndex> for LooseBend<'a, GW, R> {
|
||||||
fn joints(&self) -> (LooseDotIndex, LooseDotIndex) {
|
fn joints(&self) -> (LooseDotIndex, LooseDotIndex) {
|
||||||
let (from, to) = self.drawing.geometry().bend_joints(self.index.into());
|
let (from, to) = self.drawing.geometry().bend_joints(self.index.into());
|
||||||
(
|
(
|
||||||
|
|
@ -487,6 +505,9 @@ impl<'a, R: RulesTrait> GetJoints<LooseDotIndex, LooseDotIndex> for LooseBend<'a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetOtherJoint<LooseDotIndex, LooseDotIndex> for LooseBend<'a, R> {}
|
impl<'a, GW: Copy, R: RulesTrait> GetOtherJoint<LooseDotIndex, LooseDotIndex>
|
||||||
impl<'a, R: RulesTrait> GetCore<'a, R> for LooseBend<'a, R> {}
|
for LooseBend<'a, GW, R>
|
||||||
impl<'a, R: RulesTrait> GetInnerOuter<'a, R> for LooseBend<'a, R> {}
|
{
|
||||||
|
}
|
||||||
|
impl<'a, GW: Copy, R: RulesTrait> GetCore<'a, R> for LooseBend<'a, GW, R> {}
|
||||||
|
impl<'a, GW: Copy, R: RulesTrait> GetInnerOuter<'a, R> for LooseBend<'a, GW, R> {}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ pub struct Segbend {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Segbend {
|
impl Segbend {
|
||||||
pub fn from_dot(dot: LooseDotIndex, drawing: &Drawing<impl RulesTrait>) -> Self {
|
pub fn from_dot(dot: LooseDotIndex, drawing: &Drawing<impl Copy, impl RulesTrait>) -> Self {
|
||||||
let bend = LooseDot::new(dot, drawing).bend();
|
let bend = LooseDot::new(dot, drawing).bend();
|
||||||
let dot = LooseBend::new(bend, drawing).other_joint(dot);
|
let dot = LooseBend::new(bend, drawing).other_joint(dot);
|
||||||
let seg = LooseDot::new(dot, drawing).seg().unwrap();
|
let seg = LooseDot::new(dot, drawing).seg().unwrap();
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,18 @@ use geo::{point, Point, Rotate, Translate};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{
|
drawing::{dot::FixedDotWeight, seg::FixedSegWeight, Drawing},
|
||||||
dot::FixedDotWeight,
|
|
||||||
seg::FixedSegWeight,
|
|
||||||
zone::{SolidZoneWeight, ZoneIndex},
|
|
||||||
Drawing,
|
|
||||||
},
|
|
||||||
dsn::{
|
dsn::{
|
||||||
de,
|
de,
|
||||||
rules::DsnRules,
|
rules::DsnRules,
|
||||||
structure::{self, DsnFile, Layer, Pcb, Shape},
|
structure::{self, DsnFile, Layer, Pcb, Shape},
|
||||||
},
|
},
|
||||||
|
geometry::grouping::GroupingManagerTrait,
|
||||||
|
graph::{GenericIndex, GetNodeIndex},
|
||||||
|
layout::{
|
||||||
|
zone::{SolidZoneWeight, ZoneIndex},
|
||||||
|
Layout,
|
||||||
|
},
|
||||||
math::Circle,
|
math::Circle,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -45,9 +46,9 @@ impl DsnDesign {
|
||||||
Ok(Self { pcb })
|
Ok(Self { pcb })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_drawing(&self) -> Drawing<DsnRules> {
|
pub fn make_layout(&self) -> Layout<DsnRules> {
|
||||||
let rules = DsnRules::from_pcb(&self.pcb);
|
let rules = DsnRules::from_pcb(&self.pcb);
|
||||||
let mut layout = Drawing::new(rules);
|
let mut layout = 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(
|
||||||
|
|
@ -57,7 +58,7 @@ 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.rules().net_ids.get(&net.name).unwrap();
|
let net_id = 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)
|
||||||
|
|
@ -176,7 +177,7 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
for via in &self.pcb.wiring.via_vec {
|
for via in &self.pcb.wiring.via_vec {
|
||||||
let net_id = *layout.rules().net_ids.get(&via.net).unwrap();
|
let net_id = *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
|
||||||
|
|
@ -271,8 +272,13 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
for wire in self.pcb.wiring.wire_vec.iter() {
|
for wire in self.pcb.wiring.wire_vec.iter() {
|
||||||
let layer_id = *layout.rules().layer_ids.get(&wire.path.layer).unwrap();
|
let layer_id = *layout
|
||||||
let net_id = *layout.rules().net_ids.get(&wire.net).unwrap();
|
.drawing()
|
||||||
|
.rules()
|
||||||
|
.layer_ids
|
||||||
|
.get(&wire.path.layer)
|
||||||
|
.unwrap();
|
||||||
|
let net_id = *layout.drawing().rules().net_ids.get(&wire.net).unwrap();
|
||||||
|
|
||||||
Self::add_path(
|
Self::add_path(
|
||||||
&mut layout,
|
&mut layout,
|
||||||
|
|
@ -291,12 +297,12 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layer(
|
fn layer(
|
||||||
drawing: &Drawing<DsnRules>,
|
layout: &Layout<DsnRules>,
|
||||||
layer_vec: &Vec<Layer>,
|
layer_vec: &Vec<Layer>,
|
||||||
layer_name: &str,
|
layer_name: &str,
|
||||||
front: bool,
|
front: bool,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
let image_layer = *drawing.rules().layer_ids.get(layer_name).unwrap();
|
let image_layer = *layout.drawing().rules().layer_ids.get(layer_name).unwrap();
|
||||||
|
|
||||||
if front {
|
if front {
|
||||||
image_layer as usize
|
image_layer as usize
|
||||||
|
|
@ -306,7 +312,7 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_circle(
|
fn add_circle(
|
||||||
drawing: &mut Drawing<DsnRules>,
|
layout: &mut Layout<DsnRules>,
|
||||||
place_pos: Point,
|
place_pos: Point,
|
||||||
place_rot: f64,
|
place_rot: f64,
|
||||||
pin_pos: Point,
|
pin_pos: Point,
|
||||||
|
|
@ -320,7 +326,7 @@ impl DsnDesign {
|
||||||
r,
|
r,
|
||||||
};
|
};
|
||||||
|
|
||||||
drawing
|
layout
|
||||||
.add_fixed_dot(FixedDotWeight {
|
.add_fixed_dot(FixedDotWeight {
|
||||||
circle,
|
circle,
|
||||||
layer,
|
layer,
|
||||||
|
|
@ -330,7 +336,7 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_rect(
|
fn add_rect(
|
||||||
drawing: &mut Drawing<DsnRules>,
|
layout: &mut Layout<DsnRules>,
|
||||||
place_pos: Point,
|
place_pos: Point,
|
||||||
place_rot: f64,
|
place_rot: f64,
|
||||||
pin_pos: Point,
|
pin_pos: Point,
|
||||||
|
|
@ -342,13 +348,16 @@ impl DsnDesign {
|
||||||
layer: u64,
|
layer: u64,
|
||||||
net: usize,
|
net: usize,
|
||||||
) {
|
) {
|
||||||
let zone = drawing.add_solid_zone(SolidZoneWeight {
|
let zone = layout.add_grouping(
|
||||||
|
SolidZoneWeight {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
});
|
}
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
|
||||||
// Corners.
|
// Corners.
|
||||||
let dot_1_1 = drawing
|
let dot_1_1 = layout
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -358,11 +367,10 @@ impl DsnDesign {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
},
|
},
|
||||||
zone.into(),
|
ZoneIndex::Solid(GenericIndex::new(zone.node_index())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let dot_2_1 = layout
|
||||||
let dot_2_1 = drawing
|
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -372,10 +380,10 @@ impl DsnDesign {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
},
|
},
|
||||||
zone.into(),
|
ZoneIndex::Solid(GenericIndex::new(zone.node_index())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let dot_2_2 = drawing
|
let dot_2_2 = layout
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -385,10 +393,10 @@ impl DsnDesign {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
},
|
},
|
||||||
zone.into(),
|
ZoneIndex::Solid(GenericIndex::new(zone.node_index())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let dot_1_2 = drawing
|
let dot_1_2 = layout
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -398,11 +406,11 @@ impl DsnDesign {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
},
|
},
|
||||||
zone.into(),
|
ZoneIndex::Solid(GenericIndex::new(zone.node_index())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// Sides.
|
// Sides.
|
||||||
drawing
|
layout
|
||||||
.add_zone_fixed_seg(
|
.add_zone_fixed_seg(
|
||||||
dot_1_1,
|
dot_1_1,
|
||||||
dot_2_1,
|
dot_2_1,
|
||||||
|
|
@ -411,10 +419,10 @@ impl DsnDesign {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
},
|
},
|
||||||
zone.into(),
|
ZoneIndex::Solid(GenericIndex::new(zone.node_index())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
drawing
|
layout
|
||||||
.add_zone_fixed_seg(
|
.add_zone_fixed_seg(
|
||||||
dot_2_1,
|
dot_2_1,
|
||||||
dot_2_2,
|
dot_2_2,
|
||||||
|
|
@ -423,10 +431,10 @@ impl DsnDesign {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
},
|
},
|
||||||
zone.into(),
|
ZoneIndex::Solid(GenericIndex::new(zone.node_index())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
drawing
|
layout
|
||||||
.add_zone_fixed_seg(
|
.add_zone_fixed_seg(
|
||||||
dot_2_2,
|
dot_2_2,
|
||||||
dot_1_2,
|
dot_1_2,
|
||||||
|
|
@ -435,10 +443,10 @@ impl DsnDesign {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
},
|
},
|
||||||
zone.into(),
|
ZoneIndex::Solid(GenericIndex::new(zone.node_index())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
drawing
|
layout
|
||||||
.add_zone_fixed_seg(
|
.add_zone_fixed_seg(
|
||||||
dot_1_2,
|
dot_1_2,
|
||||||
dot_1_1,
|
dot_1_1,
|
||||||
|
|
@ -447,13 +455,13 @@ impl DsnDesign {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
},
|
},
|
||||||
zone.into(),
|
ZoneIndex::Solid(GenericIndex::new(zone.node_index())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_path(
|
fn add_path(
|
||||||
drawing: &mut Drawing<DsnRules>,
|
layout: &mut Layout<DsnRules>,
|
||||||
place_pos: Point,
|
place_pos: Point,
|
||||||
place_rot: f64,
|
place_rot: f64,
|
||||||
pin_pos: Point,
|
pin_pos: Point,
|
||||||
|
|
@ -464,7 +472,7 @@ impl DsnDesign {
|
||||||
net: usize,
|
net: usize,
|
||||||
) {
|
) {
|
||||||
// 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 = drawing
|
let mut prev_index = layout
|
||||||
.add_fixed_dot(FixedDotWeight {
|
.add_fixed_dot(FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: Self::pos(
|
pos: Self::pos(
|
||||||
|
|
@ -484,7 +492,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 = drawing
|
let index = layout
|
||||||
.add_fixed_dot(FixedDotWeight {
|
.add_fixed_dot(FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: Self::pos(
|
pos: Self::pos(
|
||||||
|
|
@ -504,7 +512,7 @@ impl DsnDesign {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// add a seg between the current and previous coords
|
// add a seg between the current and previous coords
|
||||||
let _ = drawing
|
let _ = layout
|
||||||
.add_fixed_seg(
|
.add_fixed_seg(
|
||||||
prev_index,
|
prev_index,
|
||||||
index,
|
index,
|
||||||
|
|
@ -521,7 +529,7 @@ impl DsnDesign {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_polygon(
|
fn add_polygon(
|
||||||
drawing: &mut Drawing<DsnRules>,
|
layout: &mut Layout<DsnRules>,
|
||||||
place_pos: Point,
|
place_pos: Point,
|
||||||
place_rot: f64,
|
place_rot: f64,
|
||||||
pin_pos: Point,
|
pin_pos: Point,
|
||||||
|
|
@ -531,13 +539,16 @@ impl DsnDesign {
|
||||||
layer: u64,
|
layer: u64,
|
||||||
net: usize,
|
net: usize,
|
||||||
) {
|
) {
|
||||||
let zone = drawing.add_solid_zone(SolidZoneWeight {
|
let zone = layout.add_grouping(
|
||||||
|
SolidZoneWeight {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
});
|
}
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
|
||||||
// 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 = drawing
|
let mut prev_index = layout
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -554,13 +565,15 @@ impl DsnDesign {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
},
|
},
|
||||||
zone.into(),
|
// TODO: This manual retagging shouldn't be necessary, `.into()` should suffice.
|
||||||
|
//GenericIndex::new(zone.node_index()).into(),
|
||||||
|
ZoneIndex::Solid(GenericIndex::new(zone.node_index())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// 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 = drawing
|
let index = layout
|
||||||
.add_zone_fixed_dot(
|
.add_zone_fixed_dot(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
|
|
@ -578,12 +591,13 @@ impl DsnDesign {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
},
|
},
|
||||||
zone.into(),
|
// TODO: This manual retagging shouldn't be necessary, `.into()` should suffice.
|
||||||
|
ZoneIndex::Solid(GenericIndex::new(zone.node_index())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// add a seg between the current and previous coords
|
// add a seg between the current and previous coords
|
||||||
let _ = drawing
|
let _ = layout
|
||||||
.add_zone_fixed_seg(
|
.add_zone_fixed_seg(
|
||||||
prev_index,
|
prev_index,
|
||||||
index,
|
index,
|
||||||
|
|
@ -592,7 +606,8 @@ impl DsnDesign {
|
||||||
layer,
|
layer,
|
||||||
maybe_net: Some(net),
|
maybe_net: Some(net),
|
||||||
},
|
},
|
||||||
zone.into(),
|
// TODO: This manual retagging shouldn't be necessary, `.into()` should suffice.
|
||||||
|
ZoneIndex::Solid(GenericIndex::new(zone.node_index())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ impl RTreeObject for Bbox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type BboxedIndex<I> = GeomWithData<Bbox, I>;
|
pub type BboxedIndex<I> = GeomWithData<Bbox, I>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GeometryWithRtree<
|
pub struct GeometryWithRtree<
|
||||||
|
|
@ -354,6 +354,7 @@ impl<
|
||||||
&self.geometry
|
&self.geometry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX: The type appears wrong? I don't think it should contain GW?
|
||||||
pub fn rtree(&self) -> &RTree<BboxedIndex<Node<PI, GenericIndex<GW>>>> {
|
pub fn rtree(&self) -> &RTree<BboxedIndex<Node<PI, GenericIndex<GW>>>> {
|
||||||
&self.rtree
|
&self.rtree
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,41 @@
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
use petgraph::stable_graph::StableDiGraph;
|
use petgraph::stable_graph::StableDiGraph;
|
||||||
|
use rstar::AABB;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{
|
drawing::{
|
||||||
bend::LooseBendWeight,
|
bend::LooseBendWeight,
|
||||||
dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight},
|
dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
||||||
|
graph::{PrimitiveIndex, Retag},
|
||||||
rules::RulesTrait,
|
rules::RulesTrait,
|
||||||
seg::{LoneLooseSegIndex, LoneLooseSegWeight, SeqLooseSegIndex, SeqLooseSegWeight},
|
seg::{
|
||||||
|
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SeqLooseSegIndex,
|
||||||
|
SeqLooseSegWeight,
|
||||||
|
},
|
||||||
segbend::Segbend,
|
segbend::Segbend,
|
||||||
Drawing, Infringement, LayoutException,
|
Drawing, Infringement, LayoutException,
|
||||||
},
|
},
|
||||||
graph::GetNodeIndex,
|
geometry::{
|
||||||
|
grouping::GroupingManagerTrait, BendWeightTrait, DotWeightTrait, Geometry, GeometryLabel,
|
||||||
|
GetWidth, Node, SegWeightTrait,
|
||||||
|
},
|
||||||
|
graph::{GenericIndex, GetNodeIndex},
|
||||||
|
layout::{
|
||||||
|
connectivity::{
|
||||||
|
BandIndex, BandWeight, ConnectivityLabel, ConnectivityWeight, ContinentIndex,
|
||||||
|
},
|
||||||
|
zone::{PourZoneIndex, SolidZoneIndex, ZoneIndex, ZoneWeight},
|
||||||
|
},
|
||||||
wraparoundable::WraparoundableIndex,
|
wraparoundable::WraparoundableIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::connectivity::{
|
|
||||||
BandIndex, BandWeight, ConnectivityLabel, ConnectivityWeight, ContinentIndex,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Layout<R: RulesTrait> {
|
pub struct Layout<R: RulesTrait> {
|
||||||
drawing: Drawing<R>, // Shouldn't be public, but is for now because `Draw` needs it.
|
drawing: Drawing<ZoneWeight, R>, // Shouldn't be public, but is for now because `Draw` needs it.
|
||||||
connectivity: StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>,
|
connectivity: StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RulesTrait> Layout<R> {
|
impl<R: RulesTrait> Layout<R> {
|
||||||
pub fn new(drawing: Drawing<R>) -> Self {
|
pub fn new(drawing: Drawing<ZoneWeight, R>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
drawing,
|
drawing,
|
||||||
connectivity: StableDiGraph::default(),
|
connectivity: StableDiGraph::default(),
|
||||||
|
|
@ -72,6 +83,51 @@ 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(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, Infringement> {
|
||||||
|
self.drawing.add_fixed_dot(weight)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_zone_fixed_dot(
|
||||||
|
&mut self,
|
||||||
|
weight: FixedDotWeight,
|
||||||
|
zone: ZoneIndex,
|
||||||
|
) -> Result<FixedDotIndex, Infringement> {
|
||||||
|
let maybe_dot = self.drawing.add_fixed_dot(weight);
|
||||||
|
|
||||||
|
if let Ok(dot) = maybe_dot {
|
||||||
|
self.drawing
|
||||||
|
.assign_to_grouping(dot, GenericIndex::new(zone.node_index()));
|
||||||
|
}
|
||||||
|
|
||||||
|
maybe_dot
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_fixed_seg(
|
||||||
|
&mut self,
|
||||||
|
from: FixedDotIndex,
|
||||||
|
to: FixedDotIndex,
|
||||||
|
weight: FixedSegWeight,
|
||||||
|
) -> Result<FixedSegIndex, Infringement> {
|
||||||
|
self.drawing.add_fixed_seg(from, to, weight)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_zone_fixed_seg(
|
||||||
|
&mut self,
|
||||||
|
from: FixedDotIndex,
|
||||||
|
to: FixedDotIndex,
|
||||||
|
weight: FixedSegWeight,
|
||||||
|
zone: ZoneIndex,
|
||||||
|
) -> Result<FixedSegIndex, Infringement> {
|
||||||
|
let maybe_seg = self.add_fixed_seg(from, to, weight);
|
||||||
|
|
||||||
|
if let Ok(seg) = maybe_seg {
|
||||||
|
self.drawing
|
||||||
|
.assign_to_grouping(seg, GenericIndex::new(zone.node_index()));
|
||||||
|
}
|
||||||
|
|
||||||
|
maybe_seg
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_lone_loose_seg(
|
pub fn add_lone_loose_seg(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: FixedDotIndex,
|
from: FixedDotIndex,
|
||||||
|
|
@ -107,12 +163,74 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
0.0
|
0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawing(&self) -> &Drawing<R> {
|
|
||||||
&self.drawing
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn continent(&self, dot: FixedDotIndex) -> ContinentIndex {
|
pub fn continent(&self, dot: FixedDotIndex) -> ContinentIndex {
|
||||||
// TODO.
|
// TODO.
|
||||||
ContinentIndex::new(0.into())
|
ContinentIndex::new(0.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn zones(&self) -> impl Iterator<Item = ZoneIndex> + '_ {
|
||||||
|
self.drawing.rtree().iter().filter_map(|wrapper| {
|
||||||
|
if let Node::Grouping(zone) = wrapper.data {
|
||||||
|
Some(match self.drawing.geometry().grouping_weight(zone) {
|
||||||
|
ZoneWeight::Solid(..) => {
|
||||||
|
ZoneIndex::Solid(SolidZoneIndex::new(zone.node_index()))
|
||||||
|
}
|
||||||
|
ZoneWeight::Pour(..) => ZoneIndex::Pour(PourZoneIndex::new(zone.node_index())),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn layer_zones(&self, layer: u64) -> impl Iterator<Item = ZoneIndex> + '_ {
|
||||||
|
self.drawing
|
||||||
|
.rtree()
|
||||||
|
.locate_in_envelope_intersecting(&AABB::from_corners(
|
||||||
|
[-f64::INFINITY, -f64::INFINITY, layer as f64],
|
||||||
|
[f64::INFINITY, f64::INFINITY, layer as f64],
|
||||||
|
))
|
||||||
|
.filter_map(|wrapper| {
|
||||||
|
if let Node::Grouping(zone) = wrapper.data {
|
||||||
|
Some(match self.drawing.geometry().grouping_weight(zone) {
|
||||||
|
ZoneWeight::Solid(..) => {
|
||||||
|
ZoneIndex::Solid(SolidZoneIndex::new(zone.node_index()))
|
||||||
|
}
|
||||||
|
ZoneWeight::Pour(..) => {
|
||||||
|
ZoneIndex::Pour(PourZoneIndex::new(zone.node_index()))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn zone_members(&self, zone: ZoneIndex) -> impl Iterator<Item = PrimitiveIndex> + '_ {
|
||||||
|
self.drawing
|
||||||
|
.geometry()
|
||||||
|
.grouping_members(GenericIndex::new(zone.node_index()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn drawing(&self) -> &Drawing<impl Copy, R> {
|
||||||
|
&self.drawing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: RulesTrait> GroupingManagerTrait<ZoneWeight, GenericIndex<ZoneWeight>> for Layout<R> {
|
||||||
|
fn add_grouping(&mut self, weight: ZoneWeight) -> GenericIndex<ZoneWeight> {
|
||||||
|
self.drawing.add_grouping(weight)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_grouping(&mut self, grouping: GenericIndex<ZoneWeight>) {
|
||||||
|
self.drawing.remove_grouping(grouping);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assign_to_grouping<W>(
|
||||||
|
&mut self,
|
||||||
|
primitive: GenericIndex<W>,
|
||||||
|
grouping: GenericIndex<ZoneWeight>,
|
||||||
|
) {
|
||||||
|
self.drawing.assign_to_grouping(primitive, grouping);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod connectivity;
|
pub mod connectivity;
|
||||||
mod layout;
|
mod layout;
|
||||||
|
pub mod zone;
|
||||||
|
|
||||||
pub use layout::*;
|
pub use layout::*;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use crate::{
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait MakePolygon {
|
pub trait MakePolygon {
|
||||||
fn polygon<R: RulesTrait>(&self, drawing: &Drawing<R>) -> Polygon;
|
fn polygon<R: RulesTrait>(&self, drawing: &Drawing<impl Copy, R>) -> Polygon;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(GetNodeIndex, MakePolygon)]
|
#[enum_dispatch(GetNodeIndex, MakePolygon)]
|
||||||
|
|
@ -55,12 +55,12 @@ impl<'a> GetMaybeNet for SolidZoneWeight {
|
||||||
pub type SolidZoneIndex = GenericIndex<SolidZoneWeight>;
|
pub type SolidZoneIndex = GenericIndex<SolidZoneWeight>;
|
||||||
|
|
||||||
impl MakePolygon for SolidZoneIndex {
|
impl MakePolygon for SolidZoneIndex {
|
||||||
fn polygon<R: RulesTrait>(&self, drawing: &Drawing<R>) -> Polygon {
|
fn polygon<R: RulesTrait>(&self, drawing: &Drawing<impl Copy, R>) -> Polygon {
|
||||||
Polygon::new(
|
Polygon::new(
|
||||||
LineString::from(
|
LineString::from(
|
||||||
drawing
|
drawing
|
||||||
.geometry()
|
.geometry()
|
||||||
.grouping_members(GenericIndex::<ZoneWeight>::new(self.node_index()))
|
.grouping_members(GenericIndex::new(self.node_index()))
|
||||||
.filter_map(|primitive_node| {
|
.filter_map(|primitive_node| {
|
||||||
if let Ok(dot) = DotIndex::try_from(primitive_node) {
|
if let Ok(dot) = DotIndex::try_from(primitive_node) {
|
||||||
Some(drawing.geometry().dot_weight(dot).pos())
|
Some(drawing.geometry().dot_weight(dot).pos())
|
||||||
|
|
@ -96,12 +96,12 @@ impl<'a> GetMaybeNet for PourZoneWeight {
|
||||||
pub type PourZoneIndex = GenericIndex<PourZoneWeight>;
|
pub type PourZoneIndex = GenericIndex<PourZoneWeight>;
|
||||||
|
|
||||||
impl MakePolygon for PourZoneIndex {
|
impl MakePolygon for PourZoneIndex {
|
||||||
fn polygon<R: RulesTrait>(&self, drawing: &Drawing<R>) -> Polygon {
|
fn polygon<R: RulesTrait>(&self, drawing: &Drawing<impl Copy, R>) -> Polygon {
|
||||||
Polygon::new(
|
Polygon::new(
|
||||||
LineString::from(
|
LineString::from(
|
||||||
drawing
|
drawing
|
||||||
.geometry()
|
.geometry()
|
||||||
.grouping_members(GenericIndex::<ZoneWeight>::new(self.node_index()))
|
.grouping_members(GenericIndex::new(self.node_index()))
|
||||||
.filter_map(|primitive_node| {
|
.filter_map(|primitive_node| {
|
||||||
if let Ok(dot) = DotIndex::try_from(primitive_node) {
|
if let Ok(dot) = DotIndex::try_from(primitive_node) {
|
||||||
Some(drawing.geometry().dot_weight(dot).pos())
|
Some(drawing.geometry().dot_weight(dot).pos())
|
||||||
|
|
@ -83,7 +83,7 @@ pub struct Mesh {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mesh {
|
impl Mesh {
|
||||||
pub fn new(layout: &Drawing<impl RulesTrait>) -> Self {
|
pub fn new(layout: &Drawing<impl Copy, impl RulesTrait>) -> Self {
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
triangulation: Triangulation::new(layout),
|
triangulation: Triangulation::new(layout),
|
||||||
vertex_to_triangulation_vertex: Vec::new(),
|
vertex_to_triangulation_vertex: Vec::new(),
|
||||||
|
|
@ -93,7 +93,10 @@ impl Mesh {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate(&mut self, drawing: &Drawing<impl RulesTrait>) -> Result<(), InsertionError> {
|
pub fn generate(
|
||||||
|
&mut self,
|
||||||
|
drawing: &Drawing<impl Copy, impl RulesTrait>,
|
||||||
|
) -> Result<(), InsertionError> {
|
||||||
for node in drawing.primitive_nodes() {
|
for node in drawing.primitive_nodes() {
|
||||||
let center = node.primitive(drawing).shape().center();
|
let center = node.primitive(drawing).shape().center();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@ pub struct Triangulation<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I
|
||||||
impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
|
impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
|
||||||
Triangulation<I, W>
|
Triangulation<I, W>
|
||||||
{
|
{
|
||||||
pub fn new(layout: &Drawing<impl RulesTrait>) -> Self {
|
pub fn new(drawing: &Drawing<impl Copy, impl RulesTrait>) -> Self {
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
triangulation: <DelaunayTriangulation<W> as spade::Triangulation>::new(),
|
triangulation: <DelaunayTriangulation<W> as spade::Triangulation>::new(),
|
||||||
vertex_to_handle: Vec::new(),
|
vertex_to_handle: Vec::new(),
|
||||||
index_marker: PhantomData,
|
index_marker: PhantomData,
|
||||||
};
|
};
|
||||||
this.vertex_to_handle
|
this.vertex_to_handle
|
||||||
.resize(layout.geometry().graph().node_bound(), None);
|
.resize(drawing.geometry().graph().node_bound(), None);
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,15 +45,15 @@ impl From<BendIndex> for WraparoundableIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(GetWraparound, GetLayout, GetNodeIndex)]
|
#[enum_dispatch(GetWraparound, GetDrawing, GetNodeIndex)]
|
||||||
pub enum Wraparoundable<'a, R: RulesTrait> {
|
pub enum Wraparoundable<'a, GW: Copy, R: RulesTrait> {
|
||||||
FixedDot(FixedDot<'a, R>),
|
FixedDot(FixedDot<'a, GW, R>),
|
||||||
FixedBend(FixedBend<'a, R>),
|
FixedBend(FixedBend<'a, GW, R>),
|
||||||
LooseBend(LooseBend<'a, R>),
|
LooseBend(LooseBend<'a, GW, R>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> Wraparoundable<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> Wraparoundable<'a, GW, R> {
|
||||||
pub fn new(index: WraparoundableIndex, drawing: &'a Drawing<R>) -> Self {
|
pub fn new(index: WraparoundableIndex, drawing: &'a Drawing<GW, R>) -> Self {
|
||||||
match index {
|
match index {
|
||||||
WraparoundableIndex::FixedDot(dot) => drawing.primitive(dot).into(),
|
WraparoundableIndex::FixedDot(dot) => drawing.primitive(dot).into(),
|
||||||
WraparoundableIndex::FixedBend(bend) => drawing.primitive(bend).into(),
|
WraparoundableIndex::FixedBend(bend) => drawing.primitive(bend).into(),
|
||||||
|
|
@ -62,19 +62,19 @@ impl<'a, R: RulesTrait> Wraparoundable<'a, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetWraparound for FixedDot<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetWraparound for FixedDot<'a, GW, R> {
|
||||||
fn wraparound(&self) -> Option<LooseBendIndex> {
|
fn wraparound(&self) -> Option<LooseBendIndex> {
|
||||||
self.first_rail()
|
self.first_rail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetWraparound for LooseBend<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetWraparound for LooseBend<'a, GW, R> {
|
||||||
fn wraparound(&self) -> Option<LooseBendIndex> {
|
fn wraparound(&self) -> Option<LooseBendIndex> {
|
||||||
self.outer()
|
self.outer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> GetWraparound for FixedBend<'a, R> {
|
impl<'a, GW: Copy, R: RulesTrait> GetWraparound for FixedBend<'a, GW, R> {
|
||||||
fn wraparound(&self) -> Option<LooseBendIndex> {
|
fn wraparound(&self) -> Option<LooseBendIndex> {
|
||||||
self.first_rail()
|
self.first_rail()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue