mirror of https://codeberg.org/topola/topola.git
refactor(geometry): introduce CompoundEntryKind to suppport entry metadata
example usages would be marking the apex of a polygon explicitly, or marking the nodes of a polygon which are part of the convex hull - make ManageCompounds more generic - removes unnecessary bounds on handles/refs
This commit is contained in:
parent
594bb51a57
commit
861869ab7c
|
|
@ -108,7 +108,7 @@ impl Ratsnest {
|
|||
|
||||
for node in layout.drawing().layer_primitive_nodes(layer) {
|
||||
if let PrimitiveIndex::FixedDot(dot) = node {
|
||||
if layout.polys(dot).next().is_none() {
|
||||
if layout.drawing().compounds(dot).next().is_none() {
|
||||
handle_rvw(
|
||||
layout.drawing().primitive(dot).maybe_net(),
|
||||
RatvertexIndex::FixedDot(dot),
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use crate::{
|
|||
},
|
||||
geometry::{edit::ApplyGeometryEdit, GenericNode, GetLayer},
|
||||
graph::{GenericIndex, MakeRef},
|
||||
layout::{poly::PolyWeight, CompoundWeight, Layout, LayoutEdit, NodeIndex},
|
||||
layout::{poly::PolyWeight, CompoundEntryKind, CompoundWeight, Layout, LayoutEdit, NodeIndex},
|
||||
};
|
||||
|
||||
/// Represents a band between two pins.
|
||||
|
|
@ -225,6 +225,7 @@ impl<M: AccessMesadata>
|
|||
SegWeight,
|
||||
BendWeight,
|
||||
CompoundWeight,
|
||||
CompoundEntryKind,
|
||||
PrimitiveIndex,
|
||||
DotIndex,
|
||||
SegIndex,
|
||||
|
|
|
|||
|
|
@ -37,24 +37,28 @@ impl From<BandTermsegIndex> for LooseIndex {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, CW, R> MakeRef<'a, BandRef<'a, CW, R>, Drawing<CW, R>> for BandTermsegIndex {
|
||||
fn ref_(&self, drawing: &'a Drawing<CW, R>) -> BandRef<'a, CW, R> {
|
||||
impl<'a, CW: 'a, Cek: 'a, R: 'a> MakeRef<'a, Drawing<CW, Cek, R>> for BandTermsegIndex {
|
||||
type Output = BandRef<'a, CW, Cek, R>;
|
||||
fn ref_(&self, drawing: &'a Drawing<CW, Cek, R>) -> BandRef<'a, CW, Cek, R> {
|
||||
BandRef::new(*self, drawing)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BandRef<'a, CW, R> {
|
||||
pub struct BandRef<'a, CW, Cek, R> {
|
||||
first_seg: BandTermsegIndex,
|
||||
drawing: &'a Drawing<CW, R>,
|
||||
drawing: &'a Drawing<CW, Cek, R>,
|
||||
}
|
||||
|
||||
impl<'a, CW, R> BandRef<'a, CW, R> {
|
||||
pub fn new(first_seg: BandTermsegIndex, drawing: &'a Drawing<CW, R>) -> BandRef<'a, CW, R> {
|
||||
impl<'a, CW: 'a, Cek: 'a, R: 'a> BandRef<'a, CW, Cek, R> {
|
||||
pub fn new(
|
||||
first_seg: BandTermsegIndex,
|
||||
drawing: &'a Drawing<CW, Cek, R>,
|
||||
) -> BandRef<'a, CW, Cek, R> {
|
||||
Self { first_seg, drawing }
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> MeasureLength for BandRef<'_, CW, R> {
|
||||
impl<CW: Clone, Cek: Copy, R: AccessRules> MeasureLength for BandRef<'_, CW, Cek, R> {
|
||||
fn length(&self) -> f64 {
|
||||
match self.first_seg {
|
||||
BandTermsegIndex::Straight(seg) => {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,10 @@ pub struct Cane {
|
|||
}
|
||||
|
||||
impl Cane {
|
||||
pub fn from_dot(dot: LooseDotIndex, drawing: &Drawing<impl Copy, impl AccessRules>) -> Self {
|
||||
pub fn from_dot(
|
||||
dot: LooseDotIndex,
|
||||
drawing: &Drawing<impl Clone, impl Copy, impl AccessRules>,
|
||||
) -> Self {
|
||||
let bend = LooseDot::new(dot, drawing).bend();
|
||||
let dot = LooseBend::new(bend, drawing).other_joint(dot);
|
||||
let seg = LooseDot::new(dot, drawing).seg().unwrap();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ pub trait Collect {
|
|||
fn wraparounded_bows(&self, around: GearIndex) -> Vec<PrimitiveIndex>;
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> Collect for Drawing<CW, R> {
|
||||
impl<CW: Clone, Cek: Copy, R: AccessRules> Collect for Drawing<CW, Cek, R> {
|
||||
fn loose_band_uid(&self, start_loose: LooseIndex) -> BandUid {
|
||||
BandUid::from((
|
||||
self.loose_band_first_seg(start_loose),
|
||||
|
|
@ -92,7 +92,7 @@ trait CollectPrivate {
|
|||
fn loose_band_last_seg(&self, start_loose: LooseIndex) -> BandTermsegIndex;
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> CollectPrivate for Drawing<CW, R> {
|
||||
impl<CW: Clone, Cek: Copy, R: AccessRules> CollectPrivate for Drawing<CW, Cek, R> {
|
||||
fn loose_band_first_seg(&self, start_loose: LooseIndex) -> BandTermsegIndex {
|
||||
if let LooseIndex::LoneSeg(seg) = start_loose {
|
||||
return BandTermsegIndex::Straight(seg);
|
||||
|
|
|
|||
|
|
@ -93,11 +93,12 @@ pub struct Collision(pub PrimitiveShape, pub PrimitiveIndex);
|
|||
#[error("{1:?} is already connected to net {0}")]
|
||||
pub struct AlreadyConnected(pub usize, pub PrimitiveIndex);
|
||||
|
||||
pub type DrawingEdit<CW> = GeometryEdit<
|
||||
pub type DrawingEdit<CW, Cek> = GeometryEdit<
|
||||
DotWeight,
|
||||
SegWeight,
|
||||
BendWeight,
|
||||
CW,
|
||||
Cek,
|
||||
PrimitiveIndex,
|
||||
DotIndex,
|
||||
SegIndex,
|
||||
|
|
@ -105,13 +106,14 @@ pub type DrawingEdit<CW> = GeometryEdit<
|
|||
>;
|
||||
|
||||
#[derive(Clone, Debug, Getters)]
|
||||
pub struct Drawing<CW, R> {
|
||||
pub struct Drawing<CW, Cek, R> {
|
||||
recording_geometry_with_rtree: RecordingGeometryWithRtree<
|
||||
PrimitiveWeight,
|
||||
DotWeight,
|
||||
SegWeight,
|
||||
BendWeight,
|
||||
CW,
|
||||
Cek,
|
||||
PrimitiveIndex,
|
||||
DotIndex,
|
||||
SegIndex,
|
||||
|
|
@ -120,8 +122,64 @@ pub struct Drawing<CW, R> {
|
|||
rules: R,
|
||||
}
|
||||
|
||||
impl<CW, Cek, R> Drawing<CW, Cek, R> {
|
||||
pub fn geometry(
|
||||
&self,
|
||||
) -> &Geometry<
|
||||
PrimitiveWeight,
|
||||
DotWeight,
|
||||
SegWeight,
|
||||
BendWeight,
|
||||
CW,
|
||||
Cek,
|
||||
PrimitiveIndex,
|
||||
DotIndex,
|
||||
SegIndex,
|
||||
BendIndex,
|
||||
> {
|
||||
self.recording_geometry_with_rtree.geometry()
|
||||
}
|
||||
|
||||
pub fn rtree(&self) -> &RTree<BboxedIndex<GenericNode<PrimitiveIndex, GenericIndex<CW>>>> {
|
||||
self.recording_geometry_with_rtree.rtree()
|
||||
}
|
||||
|
||||
pub fn rules_mut(&mut self) -> &mut R {
|
||||
&mut self.rules
|
||||
}
|
||||
|
||||
pub fn primitive<W>(&self, index: GenericIndex<W>) -> GenericPrimitive<'_, W, CW, Cek, R> {
|
||||
GenericPrimitive::new(index, self)
|
||||
}
|
||||
|
||||
pub fn loose(&self, index: LooseIndex) -> Loose<'_, CW, Cek, R> {
|
||||
Loose::new(index, self)
|
||||
}
|
||||
|
||||
pub fn layer_count(&self) -> usize {
|
||||
self.recording_geometry_with_rtree.layer_count()
|
||||
}
|
||||
|
||||
pub fn node_count(&self) -> usize {
|
||||
self.recording_geometry_with_rtree.graph().node_count()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Clone, Cek: Copy, R> Drawing<CW, Cek, R> {
|
||||
pub fn compound_weight(&self, compound: GenericIndex<CW>) -> &CW {
|
||||
self.recording_geometry_with_rtree.compound_weight(compound)
|
||||
}
|
||||
|
||||
pub fn compounds<'a, W: 'a>(
|
||||
&'a self,
|
||||
node: GenericIndex<W>,
|
||||
) -> impl Iterator<Item = (Cek, GenericIndex<CW>)> + 'a {
|
||||
self.recording_geometry_with_rtree.compounds(node)
|
||||
}
|
||||
}
|
||||
|
||||
#[debug_invariant(self.test_if_looses_dont_infringe_each_other())]
|
||||
impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||
impl<CW: Clone, Cek: Copy, R: AccessRules> Drawing<CW, Cek, R> {
|
||||
pub fn new(rules: R, layer_count: usize) -> Self {
|
||||
Self {
|
||||
recording_geometry_with_rtree: RecordingGeometryWithRtree::new(layer_count),
|
||||
|
|
@ -131,7 +189,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
|
||||
pub fn remove_band(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
band: BandTermsegIndex,
|
||||
) -> Result<(), DrawingException> {
|
||||
match band {
|
||||
|
|
@ -208,7 +266,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn add_fixed_dot(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
weight: FixedDotWeight,
|
||||
) -> Result<FixedDotIndex, Infringement> {
|
||||
self.add_dot_with_infringables(recorder, weight, Some(&[]))
|
||||
|
|
@ -216,7 +274,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
|
||||
#[debug_ensures(self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count() - 1))]
|
||||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn remove_fixed_dot(&mut self, recorder: &mut DrawingEdit<CW>, dot: FixedDotIndex) {
|
||||
pub fn remove_fixed_dot(&mut self, recorder: &mut DrawingEdit<CW, Cek>, dot: FixedDotIndex) {
|
||||
self.recording_geometry_with_rtree
|
||||
.remove_dot(recorder, dot.into());
|
||||
}
|
||||
|
|
@ -225,7 +283,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn add_fixed_dot_infringably(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
weight: FixedDotWeight,
|
||||
) -> FixedDotIndex {
|
||||
self.add_dot_infringably(recorder, weight)
|
||||
|
|
@ -235,7 +293,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count()))]
|
||||
fn add_dot_with_infringables<W: AccessDotWeight + Into<PrimitiveWeight> + GetLayer>(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
weight: W,
|
||||
infringables: Option<&[PrimitiveIndex]>,
|
||||
) -> Result<GenericIndex<W>, Infringement>
|
||||
|
|
@ -253,7 +311,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn add_fixed_seg(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: FixedDotIndex,
|
||||
to: FixedDotIndex,
|
||||
weight: FixedSegWeight,
|
||||
|
|
@ -265,7 +323,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count() + 2))]
|
||||
pub fn add_fixed_seg_infringably(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: FixedDotIndex,
|
||||
to: FixedDotIndex,
|
||||
weight: FixedSegWeight,
|
||||
|
|
@ -279,7 +337,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn add_lone_loose_seg(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: FixedDotIndex,
|
||||
to: FixedDotIndex,
|
||||
weight: LoneLooseSegWeight,
|
||||
|
|
@ -295,7 +353,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn add_seq_loose_seg(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: DotIndex,
|
||||
to: LooseDotIndex,
|
||||
weight: SeqLooseSegWeight,
|
||||
|
|
@ -310,7 +368,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
fn add_seg_with_infringables<W: AccessSegWeight + Into<PrimitiveWeight> + GetLayer>(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: DotIndex,
|
||||
to: DotIndex,
|
||||
weight: W,
|
||||
|
|
@ -332,7 +390,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
fn add_loose_bend_with_infringables(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: LooseDotIndex,
|
||||
to: LooseDotIndex,
|
||||
around: GearIndex,
|
||||
|
|
@ -397,7 +455,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
fn add_core_bend_with_infringables<W: AccessBendWeight + Into<PrimitiveWeight> + GetLayer>(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: DotIndex,
|
||||
to: DotIndex,
|
||||
core: FixedDotIndex,
|
||||
|
|
@ -421,7 +479,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
fn add_outer_bend_with_infringables(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: LooseDotIndex,
|
||||
to: LooseDotIndex,
|
||||
inner: BendIndex,
|
||||
|
|
@ -467,7 +525,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
|
||||
#[debug_ensures(self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count()))]
|
||||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn flip_bend(&mut self, recorder: &mut DrawingEdit<CW>, bend: FixedBendIndex) {
|
||||
pub fn flip_bend(&mut self, recorder: &mut DrawingEdit<CW, Cek>, bend: FixedBendIndex) {
|
||||
self.recording_geometry_with_rtree
|
||||
.flip_bend(recorder, bend.into());
|
||||
}
|
||||
|
|
@ -478,7 +536,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
|| self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count() + 1))]
|
||||
fn reattach_bend(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
bend: LooseBendIndex,
|
||||
maybe_new_inner: Option<LooseBendIndex>,
|
||||
) {
|
||||
|
|
@ -495,7 +553,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn insert_cane(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: DotIndex,
|
||||
around: GearIndex,
|
||||
dot_weight: LooseDotWeight,
|
||||
|
|
@ -539,7 +597,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
|
||||
fn update_this_and_outward_bows_intern(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
around: LooseBendIndex,
|
||||
) -> Result<(), DrawingException> {
|
||||
let mut maybe_rail = Some(around);
|
||||
|
|
@ -618,7 +676,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
fn update_this_and_outward_bows(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
around: LooseBendIndex,
|
||||
) -> Result<(), DrawingException> {
|
||||
let mut temp_recorder = DrawingEdit::new();
|
||||
|
|
@ -638,7 +696,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn add_cane(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: DotIndex,
|
||||
around: GearIndex,
|
||||
dot_weight: LooseDotWeight,
|
||||
|
|
@ -664,7 +722,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
fn add_cane_with_infringables(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: DotIndex,
|
||||
around: GearIndex,
|
||||
dot_weight: LooseDotWeight,
|
||||
|
|
@ -723,7 +781,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count() - 4))]
|
||||
pub fn remove_cane(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
cane: &Cane,
|
||||
face: LooseDotIndex,
|
||||
) {
|
||||
|
|
@ -760,7 +818,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn move_dot(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
dot: DotIndex,
|
||||
to: Point,
|
||||
) -> Result<(), Infringement> {
|
||||
|
|
@ -774,7 +832,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
fn move_dot_with_infringables(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
dot: DotIndex,
|
||||
to: Point,
|
||||
infringables: Option<&[PrimitiveIndex]>,
|
||||
|
|
@ -810,7 +868,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
fn shift_bend_with_infringables(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
bend: BendIndex,
|
||||
offset: f64,
|
||||
infringables: Option<&[PrimitiveIndex]>,
|
||||
|
|
@ -852,12 +910,12 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||
impl<CW: Clone, Cek: Copy, R: AccessRules> Drawing<CW, Cek, R> {
|
||||
#[debug_ensures(self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count() + 1))]
|
||||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
fn add_dot_infringably<W: AccessDotWeight + Into<PrimitiveWeight> + GetLayer>(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
weight: W,
|
||||
) -> GenericIndex<W>
|
||||
where
|
||||
|
|
@ -870,7 +928,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count() + 2))]
|
||||
fn add_seg_infringably<W: AccessSegWeight + Into<PrimitiveWeight> + GetLayer>(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
from: DotIndex,
|
||||
to: DotIndex,
|
||||
weight: W,
|
||||
|
|
@ -882,24 +940,33 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
.add_seg(recorder, from, to, weight)
|
||||
}
|
||||
|
||||
pub fn add_compound(&mut self, recorder: &mut DrawingEdit<CW>, weight: CW) -> GenericIndex<CW> {
|
||||
pub fn add_compound(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
weight: CW,
|
||||
) -> GenericIndex<CW> {
|
||||
self.recording_geometry_with_rtree
|
||||
.add_compound(recorder, weight)
|
||||
}
|
||||
|
||||
pub fn remove_compound(&mut self, recorder: &mut DrawingEdit<CW>, compound: GenericIndex<CW>) {
|
||||
pub fn remove_compound(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
compound: GenericIndex<CW>,
|
||||
) {
|
||||
self.recording_geometry_with_rtree
|
||||
.remove_compound(recorder, compound);
|
||||
}
|
||||
|
||||
pub fn add_to_compound<W>(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
primitive: GenericIndex<W>,
|
||||
entry_kind: Cek,
|
||||
compound: GenericIndex<CW>,
|
||||
) {
|
||||
self.recording_geometry_with_rtree
|
||||
.add_to_compound(recorder, primitive, compound);
|
||||
.add_to_compound(recorder, primitive, entry_kind, compound);
|
||||
}
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count()))]
|
||||
|
|
@ -907,7 +974,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count() - 1))]
|
||||
fn fail_and_remove_if_infringes_except(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW>,
|
||||
recorder: &mut DrawingEdit<CW, Cek>,
|
||||
node: PrimitiveIndex,
|
||||
maybe_except: Option<&[PrimitiveIndex]>,
|
||||
) -> Result<(), Infringement> {
|
||||
|
|
@ -1022,17 +1089,6 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn compound_weight(&self, compound: GenericIndex<CW>) -> CW {
|
||||
self.recording_geometry_with_rtree.compound_weight(compound)
|
||||
}
|
||||
|
||||
pub fn compounds<'a, W: 'a>(
|
||||
&'a self,
|
||||
node: GenericIndex<W>,
|
||||
) -> impl Iterator<Item = GenericIndex<CW>> + 'a {
|
||||
self.recording_geometry_with_rtree.compounds(node)
|
||||
}
|
||||
|
||||
pub fn is_node_in_layer(
|
||||
&self,
|
||||
index: GenericNode<PrimitiveIndex, GenericIndex<CW>>,
|
||||
|
|
@ -1078,48 +1134,6 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn geometry(
|
||||
&self,
|
||||
) -> &Geometry<
|
||||
PrimitiveWeight,
|
||||
DotWeight,
|
||||
SegWeight,
|
||||
BendWeight,
|
||||
CW,
|
||||
PrimitiveIndex,
|
||||
DotIndex,
|
||||
SegIndex,
|
||||
BendIndex,
|
||||
> {
|
||||
self.recording_geometry_with_rtree.geometry()
|
||||
}
|
||||
|
||||
pub fn rtree(&self) -> &RTree<BboxedIndex<GenericNode<PrimitiveIndex, GenericIndex<CW>>>> {
|
||||
self.recording_geometry_with_rtree.rtree()
|
||||
}
|
||||
|
||||
#[debug_ensures(self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count()))]
|
||||
#[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn rules_mut(&mut self) -> &mut R {
|
||||
&mut self.rules
|
||||
}
|
||||
|
||||
pub fn primitive<W>(&self, index: GenericIndex<W>) -> GenericPrimitive<W, CW, R> {
|
||||
GenericPrimitive::new(index, self)
|
||||
}
|
||||
|
||||
pub fn loose(&self, index: LooseIndex) -> Loose<CW, R> {
|
||||
Loose::new(index, self)
|
||||
}
|
||||
|
||||
pub fn layer_count(&self) -> usize {
|
||||
self.recording_geometry_with_rtree.layer_count()
|
||||
}
|
||||
|
||||
pub fn node_count(&self) -> usize {
|
||||
self.recording_geometry_with_rtree.graph().node_count()
|
||||
}
|
||||
|
||||
fn test_if_looses_dont_infringe_each_other(&self) -> bool {
|
||||
!self
|
||||
.primitive_nodes()
|
||||
|
|
@ -1158,19 +1172,20 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules>
|
||||
impl<CW: Clone, Cek: Copy, R: AccessRules>
|
||||
ApplyGeometryEdit<
|
||||
DotWeight,
|
||||
SegWeight,
|
||||
BendWeight,
|
||||
CW,
|
||||
Cek,
|
||||
PrimitiveIndex,
|
||||
DotIndex,
|
||||
SegIndex,
|
||||
BendIndex,
|
||||
> for Drawing<CW, R>
|
||||
> for Drawing<CW, Cek, R>
|
||||
{
|
||||
fn apply(&mut self, edit: &DrawingEdit<CW>) {
|
||||
fn apply(&mut self, edit: &DrawingEdit<CW, Cek>) {
|
||||
self.recording_geometry_with_rtree.apply(edit);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,10 @@ pub enum GearIndex {
|
|||
LooseBend(LooseBendIndex),
|
||||
}
|
||||
|
||||
impl<'a, CW: Copy, R: AccessRules> MakeRef<'a, GearRef<'a, CW, R>, Drawing<CW, R>> for GearIndex {
|
||||
fn ref_(&self, drawing: &'a Drawing<CW, R>) -> GearRef<'a, CW, R> {
|
||||
GearRef::new(*self, drawing)
|
||||
impl<'a, CW: 'a, Cek: 'a, R: 'a> MakeRef<'a, Drawing<CW, Cek, R>> for GearIndex {
|
||||
type Output = GearRef<'a, CW, Cek, R>;
|
||||
fn ref_(&self, drawing: &'a Drawing<CW, Cek, R>) -> GearRef<'a, CW, Cek, R> {
|
||||
GearRef::<'a, CW, Cek, R>::new(*self, drawing)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,14 +57,14 @@ impl From<BendIndex> for GearIndex {
|
|||
}
|
||||
|
||||
#[enum_dispatch(GetNextGear, GetDrawing, GetPetgraphIndex)]
|
||||
pub enum GearRef<'a, CW: Copy, R: AccessRules> {
|
||||
FixedDot(FixedDot<'a, CW, R>),
|
||||
FixedBend(FixedBend<'a, CW, R>),
|
||||
LooseBend(LooseBend<'a, CW, R>),
|
||||
pub enum GearRef<'a, CW, Cek, R> {
|
||||
FixedDot(FixedDot<'a, CW, Cek, R>),
|
||||
FixedBend(FixedBend<'a, CW, Cek, R>),
|
||||
LooseBend(LooseBend<'a, CW, Cek, R>),
|
||||
}
|
||||
|
||||
impl<'a, CW: Copy, R: AccessRules> GearRef<'a, CW, R> {
|
||||
pub fn new(index: GearIndex, drawing: &'a Drawing<CW, R>) -> Self {
|
||||
impl<'a, CW, Cek, R> GearRef<'a, CW, Cek, R> {
|
||||
pub fn new(index: GearIndex, drawing: &'a Drawing<CW, Cek, R>) -> Self {
|
||||
match index {
|
||||
GearIndex::FixedDot(dot) => drawing.primitive(dot).into(),
|
||||
GearIndex::FixedBend(bend) => drawing.primitive(bend).into(),
|
||||
|
|
@ -72,19 +73,19 @@ impl<'a, CW: Copy, R: AccessRules> GearRef<'a, CW, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetNextGear for FixedDot<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetNextGear for FixedDot<'_, CW, Cek, R> {
|
||||
fn next_gear(&self) -> Option<LooseBendIndex> {
|
||||
self.first_gear()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetNextGear for LooseBend<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetNextGear for LooseBend<'_, CW, Cek, R> {
|
||||
fn next_gear(&self) -> Option<LooseBendIndex> {
|
||||
self.outer()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetNextGear for FixedBend<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetNextGear for FixedBend<'_, CW, Cek, R> {
|
||||
fn next_gear(&self) -> Option<LooseBendIndex> {
|
||||
self.first_gear()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@ pub trait GetMaybeNet {
|
|||
|
||||
#[enum_dispatch]
|
||||
pub trait MakePrimitive {
|
||||
fn primitive<'a, CW: Copy, R: AccessRules>(
|
||||
fn primitive<'a, CW: Clone, Cek: Copy, R: AccessRules>(
|
||||
&self,
|
||||
drawing: &'a Drawing<CW, R>,
|
||||
) -> Primitive<'a, CW, R>;
|
||||
drawing: &'a Drawing<CW, Cek, R>,
|
||||
) -> Primitive<'a, CW, Cek, R>;
|
||||
}
|
||||
|
||||
macro_rules! impl_weight_forward {
|
||||
|
|
@ -76,10 +76,10 @@ macro_rules! impl_weight_forward {
|
|||
pub type $index_struct = GenericIndex<$weight_struct>;
|
||||
|
||||
impl MakePrimitive for $index_struct {
|
||||
fn primitive<'a, CW: Copy, R: AccessRules>(
|
||||
fn primitive<'a, CW: Clone, Cek: Copy, R: AccessRules>(
|
||||
&self,
|
||||
drawing: &'a Drawing<CW, R>,
|
||||
) -> Primitive<'a, CW, R> {
|
||||
drawing: &'a crate::drawing::Drawing<CW, Cek, R>,
|
||||
) -> Primitive<'a, CW, Cek, R> {
|
||||
Primitive::$weight_variant(GenericPrimitive::new(*self, drawing))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ pub trait Guide {
|
|||
fn head(&self, face: DotIndex) -> Head;
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> Guide for Drawing<CW, R> {
|
||||
impl<CW: Clone, Cek: Copy, R: AccessRules> Guide for Drawing<CW, Cek, R> {
|
||||
fn head_into_dot_segment(
|
||||
&self,
|
||||
head: &Head,
|
||||
|
|
@ -223,7 +223,7 @@ trait GuidePrivate {
|
|||
fn conditions(&self, node: PrimitiveIndex) -> Option<Conditions<'_>>;
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GuidePrivate for Drawing<CW, R> {
|
||||
impl<CW: Clone, Cek: Copy, R: AccessRules> GuidePrivate for Drawing<CW, Cek, R> {
|
||||
fn clearance(&self, lhs: Option<&Conditions<'_>>, rhs: Option<&Conditions<'_>>) -> f64 {
|
||||
match (lhs, rhs) {
|
||||
(None, _) | (_, None) => 0.0,
|
||||
|
|
|
|||
|
|
@ -29,8 +29,9 @@ pub enum Head {
|
|||
Cane(CaneHead),
|
||||
}
|
||||
|
||||
impl<'a, CW, R> MakeRef<'a, HeadRef<'a, CW, R>, Drawing<CW, R>> for Head {
|
||||
fn ref_(&self, drawing: &'a Drawing<CW, R>) -> HeadRef<'a, CW, R> {
|
||||
impl<'a, CW: 'a, Cek: 'a, R: 'a> MakeRef<'a, Drawing<CW, Cek, R>> for Head {
|
||||
type Output = HeadRef<'a, CW, Cek, R>;
|
||||
fn ref_(&self, drawing: &'a Drawing<CW, Cek, R>) -> HeadRef<'a, CW, Cek, R> {
|
||||
HeadRef::new(*self, drawing)
|
||||
}
|
||||
}
|
||||
|
|
@ -71,24 +72,24 @@ impl GetFace for CaneHead {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct HeadRef<'a, CW, R> {
|
||||
pub struct HeadRef<'a, CW, Cek, R> {
|
||||
head: Head,
|
||||
drawing: &'a Drawing<CW, R>,
|
||||
drawing: &'a Drawing<CW, Cek, R>,
|
||||
}
|
||||
|
||||
impl<'a, CW, R> HeadRef<'a, CW, R> {
|
||||
pub fn new(head: Head, drawing: &'a Drawing<CW, R>) -> Self {
|
||||
impl<'a, CW, Cek, R> HeadRef<'a, CW, Cek, R> {
|
||||
pub fn new(head: Head, drawing: &'a Drawing<CW, Cek, R>) -> Self {
|
||||
Self { drawing, head }
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW, R> GetFace for HeadRef<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetFace for HeadRef<'_, CW, Cek, R> {
|
||||
fn face(&self) -> DotIndex {
|
||||
self.head.face()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> MeasureLength for HeadRef<'_, CW, R> {
|
||||
impl<CW: Clone, Cek: Copy, R: AccessRules> MeasureLength for HeadRef<'_, CW, Cek, R> {
|
||||
fn length(&self) -> f64 {
|
||||
match self.head {
|
||||
Head::Bare(..) => 0.0,
|
||||
|
|
|
|||
|
|
@ -70,15 +70,15 @@ impl TryFrom<PrimitiveIndex> for LooseIndex {
|
|||
}
|
||||
|
||||
#[enum_dispatch(GetPrevNextLoose, GetDrawing, GetPetgraphIndex)]
|
||||
pub enum Loose<'a, CW: Copy, R: AccessRules> {
|
||||
Dot(LooseDot<'a, CW, R>),
|
||||
LoneSeg(LoneLooseSeg<'a, CW, R>),
|
||||
SeqSeg(SeqLooseSeg<'a, CW, R>),
|
||||
Bend(LooseBend<'a, CW, R>),
|
||||
pub enum Loose<'a, CW, Cek, R> {
|
||||
Dot(LooseDot<'a, CW, Cek, R>),
|
||||
LoneSeg(LoneLooseSeg<'a, CW, Cek, R>),
|
||||
SeqSeg(SeqLooseSeg<'a, CW, Cek, R>),
|
||||
Bend(LooseBend<'a, CW, Cek, R>),
|
||||
}
|
||||
|
||||
impl<'a, CW: Copy, R: AccessRules> Loose<'a, CW, R> {
|
||||
pub fn new(index: LooseIndex, drawing: &'a Drawing<CW, R>) -> Self {
|
||||
impl<'a, CW, Cek, R> Loose<'a, CW, Cek, R> {
|
||||
pub fn new(index: LooseIndex, drawing: &'a Drawing<CW, Cek, R>) -> Self {
|
||||
match index {
|
||||
LooseIndex::Dot(dot) => drawing.primitive(dot).into(),
|
||||
LooseIndex::LoneSeg(seg) => drawing.primitive(seg).into(),
|
||||
|
|
@ -88,7 +88,7 @@ impl<'a, CW: Copy, R: AccessRules> Loose<'a, CW, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetPrevNextLoose for LooseDot<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetPrevNextLoose for LooseDot<'_, CW, Cek, R> {
|
||||
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
||||
let bend = self.bend();
|
||||
|
||||
|
|
@ -104,13 +104,13 @@ impl<CW: Copy, R: AccessRules> GetPrevNextLoose for LooseDot<'_, CW, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetPrevNextLoose for LoneLooseSeg<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetPrevNextLoose for LoneLooseSeg<'_, CW, Cek, R> {
|
||||
fn next_loose(&self, _maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetPrevNextLoose for SeqLooseSeg<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetPrevNextLoose for SeqLooseSeg<'_, CW, Cek, R> {
|
||||
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
||||
let joints = self.joints();
|
||||
let Some(prev) = maybe_prev else {
|
||||
|
|
@ -128,7 +128,7 @@ impl<CW: Copy, R: AccessRules> GetPrevNextLoose for SeqLooseSeg<'_, CW, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetPrevNextLoose for LooseBend<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetPrevNextLoose for LooseBend<'_, CW, Cek, R> {
|
||||
fn next_loose(&self, maybe_prev: Option<LooseIndex>) -> Option<LooseIndex> {
|
||||
let joints = self.joints();
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@ use crate::{
|
|||
};
|
||||
|
||||
pub trait GetDrawing {
|
||||
type Rules: AccessRules;
|
||||
fn drawing(&self) -> &Drawing<impl Copy, Self::Rules>;
|
||||
type CompoundWeight;
|
||||
type CompoundEntryKind;
|
||||
type Rules;
|
||||
fn drawing(&self) -> &Drawing<Self::CompoundWeight, Self::CompoundEntryKind, Self::Rules>;
|
||||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
|
|
@ -106,7 +108,7 @@ impl<S: GetDrawing + GetBendIndex> GetCore for S {
|
|||
|
||||
macro_rules! impl_primitive {
|
||||
($primitive_struct:ident, $weight_struct:ident) => {
|
||||
impl<CW: Copy, R: AccessRules> GetWeight<$weight_struct> for $primitive_struct<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetWeight<$weight_struct> for $primitive_struct<'_, CW, Cek, R> {
|
||||
fn weight(&self) -> $weight_struct {
|
||||
if let PrimitiveWeight::$primitive_struct(weight) = self.tagged_weight() {
|
||||
weight
|
||||
|
|
@ -116,13 +118,13 @@ macro_rules! impl_primitive {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetLayer for $primitive_struct<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetLayer for $primitive_struct<'_, CW, Cek, R> {
|
||||
fn layer(&self) -> usize {
|
||||
self.weight().layer()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetMaybeNet for $primitive_struct<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetMaybeNet for $primitive_struct<'_, CW, Cek, R> {
|
||||
fn maybe_net(&self) -> Option<usize> {
|
||||
self.weight().maybe_net()
|
||||
}
|
||||
|
|
@ -150,17 +152,17 @@ macro_rules! impl_loose_primitive {
|
|||
MakePrimitiveShape,
|
||||
GetLimbs
|
||||
)]
|
||||
pub enum Primitive<'a, CW: Copy, R: AccessRules> {
|
||||
FixedDot(FixedDot<'a, CW, R>),
|
||||
LooseDot(LooseDot<'a, CW, R>),
|
||||
FixedSeg(FixedSeg<'a, CW, R>),
|
||||
LoneLooseSeg(LoneLooseSeg<'a, CW, R>),
|
||||
SeqLooseSeg(SeqLooseSeg<'a, CW, R>),
|
||||
FixedBend(FixedBend<'a, CW, R>),
|
||||
LooseBend(LooseBend<'a, CW, R>),
|
||||
pub enum Primitive<'a, CW, Cek, R> {
|
||||
FixedDot(FixedDot<'a, CW, Cek, R>),
|
||||
LooseDot(LooseDot<'a, CW, Cek, R>),
|
||||
FixedSeg(FixedSeg<'a, CW, Cek, R>),
|
||||
LoneLooseSeg(LoneLooseSeg<'a, CW, Cek, R>),
|
||||
SeqLooseSeg(SeqLooseSeg<'a, CW, Cek, R>),
|
||||
FixedBend(FixedBend<'a, CW, Cek, R>),
|
||||
LooseBend(LooseBend<'a, CW, Cek, R>),
|
||||
}
|
||||
|
||||
impl<'a, CW: Copy, R: AccessRules> GetConditions<'a> for &Primitive<'a, CW, R> {
|
||||
impl<'a, CW, Cek, R: AccessRules> GetConditions<'a> for &Primitive<'a, CW, Cek, R> {
|
||||
fn conditions(self) -> Option<Conditions<'a>> {
|
||||
match self {
|
||||
Primitive::FixedDot(x) => x.conditions(),
|
||||
|
|
@ -174,63 +176,65 @@ impl<'a, CW: Copy, R: AccessRules> GetConditions<'a> for &Primitive<'a, CW, R> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GenericPrimitive<'a, W, CW: Copy, R: AccessRules> {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GenericPrimitive<'a, W, CW, Cek, R> {
|
||||
pub index: GenericIndex<W>,
|
||||
drawing: &'a Drawing<CW, R>,
|
||||
drawing: &'a Drawing<CW, Cek, R>,
|
||||
}
|
||||
|
||||
impl<'a, W, CW: Copy, R: AccessRules> GenericPrimitive<'a, W, CW, R> {
|
||||
pub fn new(index: GenericIndex<W>, drawing: &'a Drawing<CW, R>) -> Self {
|
||||
impl<'a, W, CW, Cek, R> GenericPrimitive<'a, W, CW, Cek, R> {
|
||||
pub fn new(index: GenericIndex<W>, drawing: &'a Drawing<CW, Cek, R>) -> Self {
|
||||
Self { index, drawing }
|
||||
}
|
||||
|
||||
fn tagged_weight(&self) -> PrimitiveWeight {
|
||||
if let GenericNode::Primitive(weight) = *self
|
||||
if let GenericNode::Primitive(weight) = self
|
||||
.drawing
|
||||
.geometry()
|
||||
.graph()
|
||||
.node_weight(self.index.petgraph_index())
|
||||
.unwrap()
|
||||
{
|
||||
weight
|
||||
*weight
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<W, CW: Copy, R: AccessRules> GetInterior<PrimitiveIndex> for GenericPrimitive<'_, W, CW, R> {
|
||||
impl<W, CW, Cek, R> GetInterior<PrimitiveIndex> for GenericPrimitive<'_, W, CW, Cek, R> {
|
||||
fn interior(&self) -> Vec<PrimitiveIndex> {
|
||||
vec![self.tagged_weight().retag(self.index.petgraph_index())]
|
||||
}
|
||||
}
|
||||
|
||||
impl<W, CW: Copy, R: AccessRules> GetDrawing for GenericPrimitive<'_, W, CW, R> {
|
||||
impl<W, CW, Cek, R> GetDrawing for GenericPrimitive<'_, W, CW, Cek, R> {
|
||||
type CompoundWeight = CW;
|
||||
type CompoundEntryKind = Cek;
|
||||
type Rules = R;
|
||||
fn drawing(&self) -> &Drawing<impl Copy, R> {
|
||||
fn drawing(&self) -> &Drawing<CW, Cek, R> {
|
||||
self.drawing
|
||||
}
|
||||
}
|
||||
|
||||
impl<W, CW: Copy, R: AccessRules> GetPetgraphIndex for GenericPrimitive<'_, W, CW, R> {
|
||||
impl<W, CW, Cek, R> GetPetgraphIndex for GenericPrimitive<'_, W, CW, Cek, R> {
|
||||
fn petgraph_index(&self) -> NodeIndex<usize> {
|
||||
self.index.petgraph_index()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, W: GetWidth, CW: Copy, R: AccessRules> GetWidth for GenericPrimitive<'a, W, CW, R>
|
||||
impl<'a, W: GetWidth, CW, Cek, R> GetWidth for GenericPrimitive<'a, W, CW, Cek, R>
|
||||
where
|
||||
GenericPrimitive<'a, W, CW, R>: GetWeight<W>,
|
||||
GenericPrimitive<'a, W, CW, Cek, R>: GetWeight<W>,
|
||||
{
|
||||
fn width(&self) -> f64 {
|
||||
self.weight().width()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, W, CW: Copy, R: AccessRules> GetConditions<'a> for &GenericPrimitive<'a, W, CW, R>
|
||||
impl<'a, W, CW, Cek, R> GetConditions<'a> for &GenericPrimitive<'a, W, CW, Cek, R>
|
||||
where
|
||||
GenericPrimitive<'a, W, CW, R>: GetMaybeNet,
|
||||
GenericPrimitive<'a, W, CW, Cek, R>: GetMaybeNet,
|
||||
{
|
||||
fn conditions(self) -> Option<Conditions<'a>> {
|
||||
self.maybe_net().map(|net| Conditions {
|
||||
|
|
@ -241,16 +245,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub type FixedDot<'a, CW, R> = GenericPrimitive<'a, FixedDotWeight, CW, R>;
|
||||
pub type FixedDot<'a, CW, Cek, R> = GenericPrimitive<'a, FixedDotWeight, CW, Cek, R>;
|
||||
impl_fixed_primitive!(FixedDot, FixedDotWeight);
|
||||
|
||||
impl<CW: Copy, R: AccessRules> MakePrimitiveShape for FixedDot<'_, CW, R> {
|
||||
impl<CW, Cek, R> MakePrimitiveShape for FixedDot<'_, CW, Cek, R> {
|
||||
fn shape(&self) -> PrimitiveShape {
|
||||
self.drawing.geometry().dot_shape(self.index.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetLimbs for FixedDot<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetLimbs for FixedDot<'_, CW, Cek, R> {
|
||||
fn segs(&self) -> Vec<SegIndex> {
|
||||
self.drawing
|
||||
.geometry()
|
||||
|
|
@ -266,12 +270,12 @@ impl<CW: Copy, R: AccessRules> GetLimbs for FixedDot<'_, CW, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetFirstGear for FixedDot<'_, CW, R> {}
|
||||
impl<CW, Cek, R> GetFirstGear for FixedDot<'_, CW, Cek, R> {}
|
||||
|
||||
pub type LooseDot<'a, CW, R> = GenericPrimitive<'a, LooseDotWeight, CW, R>;
|
||||
pub type LooseDot<'a, CW, Cek, R> = GenericPrimitive<'a, LooseDotWeight, CW, Cek, R>;
|
||||
impl_loose_primitive!(LooseDot, LooseDotWeight);
|
||||
|
||||
impl<CW: Copy, R: AccessRules> LooseDot<'_, CW, R> {
|
||||
impl<CW, Cek, R> LooseDot<'_, CW, Cek, R> {
|
||||
pub fn seg(&self) -> Option<SeqLooseSegIndex> {
|
||||
self.drawing
|
||||
.geometry()
|
||||
|
|
@ -290,13 +294,13 @@ impl<CW: Copy, R: AccessRules> LooseDot<'_, CW, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> MakePrimitiveShape for LooseDot<'_, CW, R> {
|
||||
impl<CW, Cek, R> MakePrimitiveShape for LooseDot<'_, CW, Cek, R> {
|
||||
fn shape(&self) -> PrimitiveShape {
|
||||
self.drawing.geometry().dot_shape(self.index.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetLimbs for LooseDot<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetLimbs for LooseDot<'_, CW, Cek, R> {
|
||||
fn segs(&self) -> Vec<SegIndex> {
|
||||
if let Some(seg) = self.seg() {
|
||||
vec![seg.into()]
|
||||
|
|
@ -310,18 +314,18 @@ impl<CW: Copy, R: AccessRules> GetLimbs for LooseDot<'_, CW, R> {
|
|||
}
|
||||
}
|
||||
|
||||
pub type FixedSeg<'a, CW, R> = GenericPrimitive<'a, FixedSegWeight, CW, R>;
|
||||
pub type FixedSeg<'a, CW, Cek, R> = GenericPrimitive<'a, FixedSegWeight, CW, Cek, R>;
|
||||
impl_fixed_primitive!(FixedSeg, FixedSegWeight);
|
||||
|
||||
impl<CW: Copy, R: AccessRules> MakePrimitiveShape for FixedSeg<'_, CW, R> {
|
||||
impl<CW, Cek, R> MakePrimitiveShape for FixedSeg<'_, CW, Cek, R> {
|
||||
fn shape(&self) -> PrimitiveShape {
|
||||
self.drawing.geometry().seg_shape(self.index.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetLimbs for FixedSeg<'_, CW, R> {}
|
||||
impl<CW, Cek, R> GetLimbs for FixedSeg<'_, CW, Cek, R> {}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetJoints<FixedDotIndex, FixedDotIndex> for FixedSeg<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetJoints<FixedDotIndex, FixedDotIndex> for FixedSeg<'_, CW, Cek, R> {
|
||||
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||
let (from, to) = self.drawing.geometry().seg_joints(self.index.into());
|
||||
(
|
||||
|
|
@ -331,18 +335,18 @@ impl<CW: Copy, R: AccessRules> GetJoints<FixedDotIndex, FixedDotIndex> for Fixed
|
|||
}
|
||||
}
|
||||
|
||||
pub type LoneLooseSeg<'a, CW, R> = GenericPrimitive<'a, LoneLooseSegWeight, CW, R>;
|
||||
pub type LoneLooseSeg<'a, CW, Cek, R> = GenericPrimitive<'a, LoneLooseSegWeight, CW, Cek, R>;
|
||||
impl_loose_primitive!(LoneLooseSeg, LoneLooseSegWeight);
|
||||
|
||||
impl<CW: Copy, R: AccessRules> MakePrimitiveShape for LoneLooseSeg<'_, CW, R> {
|
||||
impl<CW, Cek, R> MakePrimitiveShape for LoneLooseSeg<'_, CW, Cek, R> {
|
||||
fn shape(&self) -> PrimitiveShape {
|
||||
self.drawing.geometry().seg_shape(self.index.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetLimbs for LoneLooseSeg<'_, CW, R> {}
|
||||
impl<CW, Cek, R> GetLimbs for LoneLooseSeg<'_, CW, Cek, R> {}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetJoints<FixedDotIndex, FixedDotIndex> for LoneLooseSeg<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetJoints<FixedDotIndex, FixedDotIndex> for LoneLooseSeg<'_, CW, Cek, R> {
|
||||
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||
let (from, to) = self.drawing.geometry().seg_joints(self.index.into());
|
||||
(
|
||||
|
|
@ -352,18 +356,18 @@ impl<CW: Copy, R: AccessRules> GetJoints<FixedDotIndex, FixedDotIndex> for LoneL
|
|||
}
|
||||
}
|
||||
|
||||
pub type SeqLooseSeg<'a, CW, R> = GenericPrimitive<'a, SeqLooseSegWeight, CW, R>;
|
||||
pub type SeqLooseSeg<'a, CW, Cek, R> = GenericPrimitive<'a, SeqLooseSegWeight, CW, Cek, R>;
|
||||
impl_loose_primitive!(SeqLooseSeg, SeqLooseSegWeight);
|
||||
|
||||
impl<CW: Copy, R: AccessRules> MakePrimitiveShape for SeqLooseSeg<'_, CW, R> {
|
||||
impl<CW, Cek, R> MakePrimitiveShape for SeqLooseSeg<'_, CW, Cek, R> {
|
||||
fn shape(&self) -> PrimitiveShape {
|
||||
self.drawing.geometry().seg_shape(self.index.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetLimbs for SeqLooseSeg<'_, CW, R> {}
|
||||
impl<CW, Cek, R> GetLimbs for SeqLooseSeg<'_, CW, Cek, R> {}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetJoints<DotIndex, LooseDotIndex> for SeqLooseSeg<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetJoints<DotIndex, LooseDotIndex> for SeqLooseSeg<'_, CW, Cek, R> {
|
||||
fn joints(&self) -> (DotIndex, LooseDotIndex) {
|
||||
let joints = self.drawing.geometry().seg_joints(self.index.into());
|
||||
if let DotWeight::Fixed(..) = self.drawing.geometry().dot_weight(joints.0) {
|
||||
|
|
@ -385,24 +389,24 @@ impl<CW: Copy, R: AccessRules> GetJoints<DotIndex, LooseDotIndex> for SeqLooseSe
|
|||
}
|
||||
}
|
||||
|
||||
pub type FixedBend<'a, CW, R> = GenericPrimitive<'a, FixedBendWeight, CW, R>;
|
||||
pub type FixedBend<'a, CW, Cek, R> = GenericPrimitive<'a, FixedBendWeight, CW, Cek, R>;
|
||||
impl_fixed_primitive!(FixedBend, FixedBendWeight);
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetBendIndex for FixedBend<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetBendIndex for FixedBend<'_, CW, Cek, R> {
|
||||
fn bend_index(&self) -> BendIndex {
|
||||
self.index.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> MakePrimitiveShape for FixedBend<'_, CW, R> {
|
||||
impl<CW, Cek, R> MakePrimitiveShape for FixedBend<'_, CW, Cek, R> {
|
||||
fn shape(&self) -> PrimitiveShape {
|
||||
self.drawing.geometry().bend_shape(self.index.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetLimbs for FixedBend<'_, CW, R> {}
|
||||
impl<CW, Cek, R> GetLimbs for FixedBend<'_, CW, Cek, R> {}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetJoints<FixedDotIndex, FixedDotIndex> for FixedBend<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetJoints<FixedDotIndex, FixedDotIndex> for FixedBend<'_, CW, Cek, R> {
|
||||
fn joints(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||
let (from, to) = self.drawing.geometry().bend_joints(self.index.into());
|
||||
(
|
||||
|
|
@ -412,39 +416,39 @@ impl<CW: Copy, R: AccessRules> GetJoints<FixedDotIndex, FixedDotIndex> for Fixed
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetFirstGear for FixedBend<'_, CW, R> {}
|
||||
//impl<'a, R: QueryRules> GetInnerOuter for FixedBend<'a, CW, R> {}
|
||||
impl<CW, Cek, R> GetFirstGear for FixedBend<'_, CW, Cek, R> {}
|
||||
//impl<'a, R: QueryRules> GetInnerOuter for FixedBend<'a, CW, Cek, R> {}
|
||||
|
||||
pub type LooseBend<'a, CW, R> = GenericPrimitive<'a, LooseBendWeight, CW, R>;
|
||||
pub type LooseBend<'a, CW, Cek, R> = GenericPrimitive<'a, LooseBendWeight, CW, Cek, R>;
|
||||
impl_loose_primitive!(LooseBend, LooseBendWeight);
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetBendIndex for LooseBend<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetBendIndex for LooseBend<'_, CW, Cek, R> {
|
||||
fn bend_index(&self) -> BendIndex {
|
||||
self.index.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, CW: Copy, R: AccessRules> From<LooseBend<'a, CW, R>> for BendIndex {
|
||||
fn from(bend: LooseBend<'a, CW, R>) -> BendIndex {
|
||||
impl<'a, CW: Clone, Cek: Copy, R: AccessRules> From<LooseBend<'a, CW, Cek, R>> for BendIndex {
|
||||
fn from(bend: LooseBend<'a, CW, Cek, R>) -> BendIndex {
|
||||
bend.index.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> MakePrimitiveShape for LooseBend<'_, CW, R> {
|
||||
impl<CW, Cek, R> MakePrimitiveShape for LooseBend<'_, CW, Cek, R> {
|
||||
fn shape(&self) -> PrimitiveShape {
|
||||
self.drawing.geometry().bend_shape(self.index.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetLimbs for LooseBend<'_, CW, R> {}
|
||||
impl<CW, Cek, R> GetLimbs for LooseBend<'_, CW, Cek, R> {}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetOffset for LooseBend<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetOffset for LooseBend<'_, CW, Cek, R> {
|
||||
fn offset(&self) -> f64 {
|
||||
self.weight().offset()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> GetJoints<LooseDotIndex, LooseDotIndex> for LooseBend<'_, CW, R> {
|
||||
impl<CW, Cek, R> GetJoints<LooseDotIndex, LooseDotIndex> for LooseBend<'_, CW, Cek, R> {
|
||||
fn joints(&self) -> (LooseDotIndex, LooseDotIndex) {
|
||||
let (from, to) = self.drawing.geometry().bend_joints(self.index.into());
|
||||
(
|
||||
|
|
@ -454,7 +458,7 @@ impl<CW: Copy, R: AccessRules> GetJoints<LooseDotIndex, LooseDotIndex> for Loose
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Copy, R: AccessRules> LooseBend<'_, CW, R> {
|
||||
impl<CW, Cek, R> LooseBend<'_, CW, Cek, R> {
|
||||
pub fn inner(&self) -> Option<LooseBendIndex> {
|
||||
self.drawing()
|
||||
.geometry()
|
||||
|
|
|
|||
|
|
@ -4,10 +4,24 @@
|
|||
|
||||
use crate::graph::{GenericIndex, GetPetgraphIndex};
|
||||
|
||||
pub trait ManageCompounds<CW: Copy, GI: GetPetgraphIndex + Copy> {
|
||||
pub trait ManageCompounds<CW: Clone> {
|
||||
type GeneralIndex: Copy;
|
||||
type EntryKind: Copy;
|
||||
|
||||
fn add_compound(&mut self, weight: CW) -> GenericIndex<CW>;
|
||||
fn remove_compound(&mut self, compound: GenericIndex<CW>);
|
||||
fn add_to_compound<W>(&mut self, node: GenericIndex<W>, compound: GenericIndex<CW>);
|
||||
fn compound_weight(&self, node: GenericIndex<CW>) -> CW;
|
||||
fn compounds<W>(&self, node: GenericIndex<W>) -> impl Iterator<Item = GenericIndex<CW>>;
|
||||
fn add_to_compound<I>(&mut self, node: I, kind: Self::EntryKind, compound: GenericIndex<CW>)
|
||||
where
|
||||
I: Copy + GetPetgraphIndex;
|
||||
|
||||
fn compound_weight(&self, node: GenericIndex<CW>) -> &CW;
|
||||
|
||||
fn compound_members(
|
||||
&self,
|
||||
compound: GenericIndex<CW>,
|
||||
) -> impl Iterator<Item = (Self::EntryKind, Self::GeneralIndex)> + '_;
|
||||
|
||||
fn compounds<I>(&self, node: I) -> impl Iterator<Item = (Self::EntryKind, GenericIndex<CW>)>
|
||||
where
|
||||
I: Copy + GetPetgraphIndex;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,23 +12,24 @@ pub trait ApplyGeometryEdit<
|
|||
DW: AccessDotWeight + GetLayer,
|
||||
SW: AccessSegWeight + GetLayer,
|
||||
BW: AccessBendWeight + GetLayer,
|
||||
CW: Copy,
|
||||
CW: Clone,
|
||||
Cek: Copy,
|
||||
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Eq + Ord + Copy,
|
||||
DI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
SI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
BI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
>
|
||||
{
|
||||
fn apply(&mut self, edit: &GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>);
|
||||
fn apply(&mut self, edit: &GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI> {
|
||||
pub struct GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI> {
|
||||
pub(super) dots: BTreeMap<DI, (Option<DW>, Option<DW>)>,
|
||||
pub(super) segs: BTreeMap<SI, (Option<((DI, DI), SW)>, Option<((DI, DI), SW)>)>,
|
||||
pub(super) bends: BTreeMap<BI, (Option<((DI, DI, DI), BW)>, Option<((DI, DI, DI), BW)>)>,
|
||||
pub(super) compounds:
|
||||
BTreeMap<GenericIndex<CW>, (Option<(Vec<PI>, CW)>, Option<(Vec<PI>, CW)>)>,
|
||||
BTreeMap<GenericIndex<CW>, (Option<(Vec<(Cek, PI)>, CW)>, Option<(Vec<(Cek, PI)>, CW)>)>,
|
||||
}
|
||||
|
||||
fn swap_tuple_inplace<D>(x: &mut (D, D)) {
|
||||
|
|
@ -39,12 +40,13 @@ impl<
|
|||
DW: AccessDotWeight + GetLayer,
|
||||
SW: AccessSegWeight + GetLayer,
|
||||
BW: AccessBendWeight + GetLayer,
|
||||
CW: Copy,
|
||||
CW: Clone,
|
||||
Cek: Copy,
|
||||
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Eq + Ord + Copy,
|
||||
DI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
SI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
BI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
> GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
> GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
|
@ -90,15 +92,16 @@ impl<
|
|||
DW: AccessDotWeight + GetLayer,
|
||||
SW: AccessSegWeight + GetLayer,
|
||||
BW: AccessBendWeight + GetLayer,
|
||||
CW: Copy,
|
||||
CW: Clone,
|
||||
Cek: Copy,
|
||||
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Eq + Ord + Copy,
|
||||
DI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
SI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
BI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
> ApplyGeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
for GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
> ApplyGeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
for GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
fn apply(&mut self, edit: &GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>) {
|
||||
fn apply(&mut self, edit: &GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>) {
|
||||
apply_btmap(&mut self.dots, &edit.dots);
|
||||
apply_btmap(&mut self.segs, &edit.segs);
|
||||
apply_btmap(&mut self.bends, &edit.bends);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ use petgraph::{
|
|||
Direction::{self, Incoming},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specctra_core::rules::AccessRules;
|
||||
|
||||
use crate::{
|
||||
drawing::{
|
||||
|
|
@ -60,12 +59,12 @@ pub trait SetOffset: GetOffset {
|
|||
fn set_offset(&mut self, offset: f64);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum GeometryLabel {
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum GeometryLabel<Cek> {
|
||||
Joined,
|
||||
Outer,
|
||||
Core,
|
||||
Compound,
|
||||
Compound(Cek),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
|
|
@ -84,8 +83,8 @@ pub trait AccessBendWeight: SetOffset + GetWidth + Copy {}
|
|||
impl<T: SetOffset + GetWidth + Copy> AccessBendWeight for T {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Geometry<PW, DW, SW, BW, CW, PI, DI, SI, BI> {
|
||||
graph: StableDiGraph<GenericNode<PW, CW>, GeometryLabel, usize>,
|
||||
pub struct Geometry<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI> {
|
||||
graph: StableDiGraph<GenericNode<PW, CW>, GeometryLabel<Cek>, usize>,
|
||||
primitive_weight_marker: PhantomData<PW>,
|
||||
dot_weight_marker: PhantomData<DW>,
|
||||
seg_weight_marker: PhantomData<SW>,
|
||||
|
|
@ -97,8 +96,8 @@ pub struct Geometry<PW, DW, SW, BW, CW, PI, DI, SI, BI> {
|
|||
bend_index_marker: PhantomData<BI>,
|
||||
}
|
||||
|
||||
impl<PW: Clone, DW, SW, BW, CW: Clone, PI, DI, SI, BI> Clone
|
||||
for Geometry<PW, DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
impl<PW: Clone, DW, SW, BW, CW: Clone, Cek: Clone, PI, DI, SI, BI> Clone
|
||||
for Geometry<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
|
|
@ -108,13 +107,15 @@ impl<PW: Clone, DW, SW, BW, CW: Clone, PI, DI, SI, BI> Clone
|
|||
}
|
||||
}
|
||||
|
||||
impl<PW, DW, SW, BW, CW, PI, DI, SI, BI> Default for Geometry<PW, DW, SW, BW, CW, PI, DI, SI, BI> {
|
||||
impl<PW, DW, SW, BW, CW, Cek: Clone, PI, DI, SI, BI> Default
|
||||
for Geometry<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<PW, DW, SW, BW, CW, PI, DI, SI, BI> Geometry<PW, DW, SW, BW, CW, PI, DI, SI, BI> {
|
||||
impl<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI> Geometry<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
graph: StableDiGraph::default(),
|
||||
|
|
@ -134,9 +135,20 @@ impl<PW, DW, SW, BW, CW, PI, DI, SI, BI> Geometry<PW, DW, SW, BW, CW, PI, DI, SI
|
|||
// field that actually contains data...
|
||||
|
||||
#[inline(always)]
|
||||
pub fn graph(&self) -> &StableDiGraph<GenericNode<PW, CW>, GeometryLabel, usize> {
|
||||
pub fn graph(&self) -> &StableDiGraph<GenericNode<PW, CW>, GeometryLabel<Cek>, usize> {
|
||||
&self.graph
|
||||
}
|
||||
|
||||
fn primitive_weight(&self, index: NodeIndex<usize>) -> PW
|
||||
where
|
||||
PW: Copy,
|
||||
{
|
||||
if let GenericNode::Primitive(weight) = self.graph.node_weight(index).unwrap() {
|
||||
*weight
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
|
|
@ -144,12 +156,13 @@ impl<
|
|||
DW: AccessDotWeight + Into<PW>,
|
||||
SW: AccessSegWeight + Into<PW>,
|
||||
BW: AccessBendWeight + Into<PW>,
|
||||
CW: Copy,
|
||||
CW,
|
||||
Cek,
|
||||
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Copy,
|
||||
DI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
SI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
BI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
> Geometry<PW, DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
> Geometry<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
pub fn add_dot<W: AccessDotWeight + Into<PW>>(&mut self, weight: W) -> GenericIndex<W> {
|
||||
GenericIndex::<W>::new(self.graph.add_node(GenericNode::Primitive(weight.into())))
|
||||
|
|
@ -307,7 +320,7 @@ impl<
|
|||
if let Some(old_inner_edge) = self
|
||||
.graph
|
||||
.edges_directed(bend.petgraph_index(), Incoming)
|
||||
.find(|edge| *edge.weight() == GeometryLabel::Outer)
|
||||
.find(|edge| matches!(edge.weight(), GeometryLabel::Outer))
|
||||
{
|
||||
self.graph.remove_edge(old_inner_edge.id());
|
||||
}
|
||||
|
|
@ -367,14 +380,6 @@ impl<
|
|||
self.core_weight(bend).width() / 2.0 + r
|
||||
}
|
||||
|
||||
fn primitive_weight(&self, index: NodeIndex<usize>) -> PW {
|
||||
if let GenericNode::Primitive(weight) = *self.graph.node_weight(index).unwrap() {
|
||||
weight
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dot_weight(&self, dot: DI) -> DW {
|
||||
self.primitive_weight(dot.petgraph_index())
|
||||
.try_into()
|
||||
|
|
@ -393,9 +398,9 @@ impl<
|
|||
.unwrap_or_else(|_| unreachable!())
|
||||
}
|
||||
|
||||
pub fn compound_weight(&self, compound: GenericIndex<CW>) -> CW {
|
||||
pub fn compound_weight(&self, compound: GenericIndex<CW>) -> &CW {
|
||||
if let GenericNode::Compound(weight) =
|
||||
*self.graph.node_weight(compound.petgraph_index()).unwrap()
|
||||
self.graph.node_weight(compound.petgraph_index()).unwrap()
|
||||
{
|
||||
weight
|
||||
} else {
|
||||
|
|
@ -423,6 +428,96 @@ impl<
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn joineds(&self, node: PI) -> impl Iterator<Item = PI> + '_ {
|
||||
self.graph
|
||||
.neighbors_undirected(node.petgraph_index())
|
||||
.filter(move |ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge_undirected(node.petgraph_index(), *ni)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap(),
|
||||
GeometryLabel::Joined
|
||||
)
|
||||
})
|
||||
.map(|ni| self.primitive_weight(ni).retag(ni))
|
||||
}
|
||||
|
||||
pub fn joined_segs(&self, dot: DI) -> impl Iterator<Item = SI> + '_ {
|
||||
self.joineds(dot.into()).filter_map(|ni| ni.try_into().ok())
|
||||
}
|
||||
|
||||
pub fn joined_bends(&self, dot: DI) -> impl Iterator<Item = BI> + '_ {
|
||||
self.joineds(dot.into()).filter_map(|ni| ni.try_into().ok())
|
||||
}
|
||||
|
||||
fn joints(&self, node: PI) -> (DI, DI) {
|
||||
(
|
||||
self.graph
|
||||
.neighbors_directed(node.petgraph_index(), Direction::Incoming)
|
||||
.find(move |ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge_undirected(node.petgraph_index(), *ni)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap(),
|
||||
GeometryLabel::Joined
|
||||
)
|
||||
})
|
||||
.map(|ni| self.primitive_weight(ni).retag(ni))
|
||||
.map(|pi| pi.try_into().unwrap_or_else(|_| unreachable!()))
|
||||
.unwrap(),
|
||||
self.graph
|
||||
.neighbors_directed(node.petgraph_index(), Direction::Outgoing)
|
||||
.find(move |ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge_undirected(node.petgraph_index(), *ni)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap(),
|
||||
GeometryLabel::Joined
|
||||
)
|
||||
})
|
||||
.map(|ni| self.primitive_weight(ni).retag(ni))
|
||||
.map(|pi| pi.try_into().unwrap_or_else(|_| unreachable!()))
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn seg_joints(&self, seg: SI) -> (DI, DI) {
|
||||
self.joints(seg.into())
|
||||
}
|
||||
|
||||
pub fn bend_joints(&self, bend: BI) -> (DI, DI) {
|
||||
self.joints(bend.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
PW: Copy + Retag<Index = PI>,
|
||||
DW,
|
||||
SW,
|
||||
BW,
|
||||
CW,
|
||||
Cek,
|
||||
PI: TryInto<DI> + TryInto<SI> + TryInto<BI>,
|
||||
DI,
|
||||
SI,
|
||||
BI: GetPetgraphIndex,
|
||||
> Geometry<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
pub fn first_rail(&self, node: NodeIndex<usize>) -> Option<BI> {
|
||||
self.graph
|
||||
.neighbors_directed(node, Incoming)
|
||||
|
|
@ -503,105 +598,14 @@ impl<
|
|||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
pub fn joineds(&self, node: PI) -> impl Iterator<Item = PI> + '_ {
|
||||
self.graph
|
||||
.neighbors_undirected(node.petgraph_index())
|
||||
.filter(move |ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge_undirected(node.petgraph_index(), *ni)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap(),
|
||||
GeometryLabel::Joined
|
||||
)
|
||||
})
|
||||
.map(|ni| self.primitive_weight(ni).retag(ni))
|
||||
}
|
||||
|
||||
pub fn joined_segs(&self, dot: DI) -> impl Iterator<Item = SI> + '_ {
|
||||
self.joineds(dot.into()).filter_map(|ni| ni.try_into().ok())
|
||||
}
|
||||
|
||||
pub fn joined_bends(&self, dot: DI) -> impl Iterator<Item = BI> + '_ {
|
||||
self.joineds(dot.into()).filter_map(|ni| ni.try_into().ok())
|
||||
}
|
||||
|
||||
fn joints(&self, node: PI) -> (DI, DI) {
|
||||
(
|
||||
self.graph
|
||||
.neighbors_directed(node.petgraph_index(), Direction::Incoming)
|
||||
.find(move |ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge_undirected(node.petgraph_index(), *ni)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap(),
|
||||
GeometryLabel::Joined
|
||||
)
|
||||
})
|
||||
.map(|ni| self.primitive_weight(ni).retag(ni))
|
||||
.map(|pi| pi.try_into().unwrap_or_else(|_| unreachable!()))
|
||||
.unwrap(),
|
||||
self.graph
|
||||
.neighbors_directed(node.petgraph_index(), Direction::Outgoing)
|
||||
.find(move |ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge_undirected(node.petgraph_index(), *ni)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap(),
|
||||
GeometryLabel::Joined
|
||||
)
|
||||
})
|
||||
.map(|ni| self.primitive_weight(ni).retag(ni))
|
||||
.map(|pi| pi.try_into().unwrap_or_else(|_| unreachable!()))
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn seg_joints(&self, seg: SI) -> (DI, DI) {
|
||||
self.joints(seg.into())
|
||||
}
|
||||
|
||||
pub fn bend_joints(&self, bend: BI) -> (DI, DI) {
|
||||
self.joints(bend.into())
|
||||
}
|
||||
|
||||
pub fn compound_members(&self, compound: GenericIndex<CW>) -> impl Iterator<Item = PI> + '_ {
|
||||
self.graph
|
||||
.neighbors_directed(compound.petgraph_index(), Incoming)
|
||||
.filter(move |ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge(*ni, compound.petgraph_index())
|
||||
.unwrap()
|
||||
)
|
||||
.unwrap(),
|
||||
GeometryLabel::Compound
|
||||
)
|
||||
})
|
||||
.map(|ni| self.primitive_weight(ni).retag(ni))
|
||||
}
|
||||
}
|
||||
|
||||
impl<PW, DW, SW, BW, CW: Copy, PI, DI, SI, BI> ManageCompounds<CW, GenericIndex<CW>>
|
||||
for Geometry<PW, DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW: Clone, Cek: Copy, PI: Copy, DI, SI, BI>
|
||||
ManageCompounds<CW> for Geometry<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
type GeneralIndex = PI;
|
||||
type EntryKind = Cek;
|
||||
|
||||
fn add_compound(&mut self, weight: CW) -> GenericIndex<CW> {
|
||||
GenericIndex::<CW>::new(self.graph.add_node(GenericNode::Compound(weight)))
|
||||
}
|
||||
|
|
@ -610,17 +614,20 @@ impl<PW, DW, SW, BW, CW: Copy, PI, DI, SI, BI> ManageCompounds<CW, GenericIndex<
|
|||
self.graph.remove_node(compound.petgraph_index());
|
||||
}
|
||||
|
||||
fn add_to_compound<W>(&mut self, primitive: GenericIndex<W>, compound: GenericIndex<CW>) {
|
||||
fn add_to_compound<I>(&mut self, primitive: I, entry_kind: Cek, compound: GenericIndex<CW>)
|
||||
where
|
||||
I: Copy + GetPetgraphIndex,
|
||||
{
|
||||
self.graph.update_edge(
|
||||
primitive.petgraph_index(),
|
||||
compound.petgraph_index(),
|
||||
GeometryLabel::Compound,
|
||||
GeometryLabel::Compound(entry_kind),
|
||||
);
|
||||
}
|
||||
|
||||
fn compound_weight(&self, compound: GenericIndex<CW>) -> CW {
|
||||
fn compound_weight(&self, compound: GenericIndex<CW>) -> &CW {
|
||||
if let GenericNode::Compound(weight) =
|
||||
*self.graph.node_weight(compound.petgraph_index()).unwrap()
|
||||
self.graph.node_weight(compound.petgraph_index()).unwrap()
|
||||
{
|
||||
weight
|
||||
} else {
|
||||
|
|
@ -628,17 +635,41 @@ impl<PW, DW, SW, BW, CW: Copy, PI, DI, SI, BI> ManageCompounds<CW, GenericIndex<
|
|||
}
|
||||
}
|
||||
|
||||
fn compounds<W>(&self, node: GenericIndex<W>) -> impl Iterator<Item = GenericIndex<CW>> {
|
||||
fn compound_members(
|
||||
&self,
|
||||
compound: GenericIndex<CW>,
|
||||
) -> impl Iterator<Item = (Cek, Self::GeneralIndex)> + '_ {
|
||||
self.graph
|
||||
.neighbors_directed(compound.petgraph_index(), Incoming)
|
||||
.filter_map(move |ni| {
|
||||
if let GeometryLabel::Compound(entry_kind) = *self
|
||||
.graph
|
||||
.edge_weight(self.graph.find_edge(ni, compound.petgraph_index()).unwrap())
|
||||
.unwrap()
|
||||
{
|
||||
Some((entry_kind, self.primitive_weight(ni).retag(ni)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn compounds<I>(&self, node: I) -> impl Iterator<Item = (Cek, GenericIndex<CW>)>
|
||||
where
|
||||
I: Copy + GetPetgraphIndex,
|
||||
{
|
||||
self.graph
|
||||
.neighbors(node.petgraph_index())
|
||||
.filter(move |ni| {
|
||||
matches!(
|
||||
self.graph
|
||||
.edge_weight(self.graph.find_edge(node.petgraph_index(), *ni).unwrap())
|
||||
.unwrap(),
|
||||
GeometryLabel::Compound
|
||||
)
|
||||
.filter_map(move |ni| {
|
||||
if let GeometryLabel::Compound(entry_kind) = *self
|
||||
.graph
|
||||
.edge_weight(self.graph.find_edge(node.petgraph_index(), ni).unwrap())
|
||||
.unwrap()
|
||||
{
|
||||
Some((entry_kind, GenericIndex::new(ni)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|ni| GenericIndex::new(ni))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@ use super::{
|
|||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RecordingGeometryWithRtree<PW, DW, SW, BW, CW, PI, DI, SI, BI> {
|
||||
geometry_with_rtree: GeometryWithRtree<PW, DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
pub struct RecordingGeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI> {
|
||||
geometry_with_rtree: GeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
}
|
||||
|
||||
impl<PW: Clone, DW, SW, BW, CW: Clone, PI: Clone, DI, SI, BI> Clone
|
||||
for RecordingGeometryWithRtree<PW, DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
impl<PW: Clone, DW, SW, BW, CW: Clone, Cek: Clone, PI: Clone, DI, SI, BI> Clone
|
||||
for RecordingGeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
|
|
@ -33,29 +33,48 @@ impl<PW: Clone, DW, SW, BW, CW: Clone, PI: Clone, DI, SI, BI> Clone
|
|||
}
|
||||
}
|
||||
|
||||
impl<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
RecordingGeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
pub fn geometry(&self) -> &Geometry<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI> {
|
||||
self.geometry_with_rtree.geometry()
|
||||
}
|
||||
|
||||
pub fn rtree(&self) -> &RTree<BboxedIndex<GenericNode<PI, GenericIndex<CW>>>> {
|
||||
self.geometry_with_rtree.rtree()
|
||||
}
|
||||
|
||||
pub fn layer_count(&self) -> usize {
|
||||
*self.geometry_with_rtree.layer_count()
|
||||
}
|
||||
|
||||
pub fn graph(&self) -> &StableDiGraph<GenericNode<PW, CW>, GeometryLabel<Cek>, usize> {
|
||||
self.geometry_with_rtree.graph()
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
PW: GetWidth + GetLayer + TryInto<DW> + TryInto<SW> + TryInto<BW> + Retag<Index = PI> + Copy,
|
||||
DW: AccessDotWeight + Into<PW> + GetLayer,
|
||||
SW: AccessSegWeight + Into<PW> + GetLayer,
|
||||
BW: AccessBendWeight + Into<PW> + GetLayer,
|
||||
CW: Copy,
|
||||
CW: Clone,
|
||||
Cek: Copy,
|
||||
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Eq + Ord + Copy,
|
||||
DI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
SI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
BI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
> RecordingGeometryWithRtree<PW, DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
> RecordingGeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
pub fn new(layer_count: usize) -> Self {
|
||||
Self {
|
||||
geometry_with_rtree: GeometryWithRtree::<PW, DW, SW, BW, CW, PI, DI, SI, BI>::new(
|
||||
layer_count,
|
||||
),
|
||||
geometry_with_rtree: GeometryWithRtree::new(layer_count),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_dot<W: AccessDotWeight + Into<PW> + GetLayer>(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
weight: W,
|
||||
) -> GenericIndex<W>
|
||||
where
|
||||
|
|
@ -76,7 +95,7 @@ impl<
|
|||
|
||||
pub fn add_seg<W: AccessSegWeight + Into<PW> + GetLayer>(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
from: DI,
|
||||
to: DI,
|
||||
weight: W,
|
||||
|
|
@ -102,7 +121,7 @@ impl<
|
|||
|
||||
pub fn add_bend<W: AccessBendWeight + Into<PW> + GetLayer>(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
from: DI,
|
||||
to: DI,
|
||||
core: DI,
|
||||
|
|
@ -129,10 +148,10 @@ impl<
|
|||
|
||||
pub fn add_compound(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
weight: CW,
|
||||
) -> GenericIndex<CW> {
|
||||
let compound = self.geometry_with_rtree.add_compound(weight);
|
||||
let compound = self.geometry_with_rtree.add_compound(weight.clone());
|
||||
recorder
|
||||
.compounds
|
||||
.insert(compound, (None, Some((vec![], weight))));
|
||||
|
|
@ -141,20 +160,21 @@ impl<
|
|||
|
||||
pub fn add_to_compound<W>(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
primitive: GenericIndex<W>,
|
||||
entry_kind: Cek,
|
||||
compound: GenericIndex<CW>,
|
||||
) {
|
||||
let geometry = self.geometry_with_rtree.geometry();
|
||||
let old_members = geometry.compound_members(compound).collect();
|
||||
let old_weight = geometry.compound_weight(compound);
|
||||
let old_weight = geometry.compound_weight(compound).clone();
|
||||
|
||||
self.geometry_with_rtree
|
||||
.add_to_compound(primitive, compound);
|
||||
.add_to_compound(primitive, entry_kind, compound);
|
||||
|
||||
let geometry = self.geometry_with_rtree.geometry();
|
||||
let new_members = geometry.compound_members(compound).collect();
|
||||
let new_weight = geometry.compound_weight(compound);
|
||||
let new_weight = geometry.compound_weight(compound).clone();
|
||||
|
||||
recorder
|
||||
.compounds
|
||||
|
|
@ -165,7 +185,7 @@ impl<
|
|||
|
||||
pub fn remove_dot(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
dot: DI,
|
||||
) -> Result<(), ()> {
|
||||
let weight = self.geometry_with_rtree.geometry().dot_weight(dot);
|
||||
|
|
@ -176,7 +196,7 @@ impl<
|
|||
|
||||
pub fn remove_seg(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
seg: SI,
|
||||
) {
|
||||
let geometry = self.geometry_with_rtree.geometry();
|
||||
|
|
@ -188,7 +208,7 @@ impl<
|
|||
|
||||
pub fn remove_bend(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
bend: BI,
|
||||
) {
|
||||
let geometry = self.geometry_with_rtree.geometry();
|
||||
|
|
@ -205,11 +225,11 @@ impl<
|
|||
|
||||
pub fn remove_compound(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
compound: GenericIndex<CW>,
|
||||
) {
|
||||
let geometry = self.geometry_with_rtree.geometry();
|
||||
let weight = geometry.compound_weight(compound);
|
||||
let weight = geometry.compound_weight(compound).clone();
|
||||
let members = geometry.compound_members(compound).collect();
|
||||
self.geometry_with_rtree.remove_compound(compound);
|
||||
edit_remove_from_map(&mut recorder.compounds, compound, (members, weight));
|
||||
|
|
@ -217,7 +237,7 @@ impl<
|
|||
|
||||
pub fn move_dot(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
dot: DI,
|
||||
to: Point,
|
||||
) {
|
||||
|
|
@ -234,11 +254,11 @@ impl<
|
|||
|
||||
fn modify_bend<F>(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
bend: BI,
|
||||
f: F,
|
||||
) where
|
||||
F: FnOnce(&mut GeometryWithRtree<PW, DW, SW, BW, CW, PI, DI, SI, BI>, BI),
|
||||
F: FnOnce(&mut GeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>, BI),
|
||||
{
|
||||
let geometry = self.geometry_with_rtree.geometry();
|
||||
let old_joints = geometry.bend_joints(bend);
|
||||
|
|
@ -264,7 +284,7 @@ impl<
|
|||
|
||||
pub fn shift_bend(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
bend: BI,
|
||||
offset: f64,
|
||||
) {
|
||||
|
|
@ -275,7 +295,7 @@ impl<
|
|||
|
||||
pub fn flip_bend(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
bend: BI,
|
||||
) {
|
||||
self.modify_bend(recorder, bend, |geometry_with_rtree, bend| {
|
||||
|
|
@ -285,7 +305,7 @@ impl<
|
|||
|
||||
pub fn reattach_bend(
|
||||
&mut self,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
recorder: &mut GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
bend: BI,
|
||||
maybe_new_inner: Option<BI>,
|
||||
) {
|
||||
|
|
@ -294,32 +314,16 @@ impl<
|
|||
});
|
||||
}
|
||||
|
||||
pub fn compound_weight(&self, compound: GenericIndex<CW>) -> CW {
|
||||
pub fn compound_weight(&self, compound: GenericIndex<CW>) -> &CW {
|
||||
self.geometry_with_rtree.compound_weight(compound)
|
||||
}
|
||||
|
||||
pub fn compounds<'a, W: 'a>(
|
||||
&'a self,
|
||||
node: GenericIndex<W>,
|
||||
) -> impl Iterator<Item = GenericIndex<CW>> + 'a {
|
||||
) -> impl Iterator<Item = (Cek, GenericIndex<CW>)> + 'a {
|
||||
self.geometry_with_rtree.compounds(node)
|
||||
}
|
||||
|
||||
pub fn geometry(&self) -> &Geometry<PW, DW, SW, BW, CW, PI, DI, SI, BI> {
|
||||
self.geometry_with_rtree.geometry()
|
||||
}
|
||||
|
||||
pub fn rtree(&self) -> &RTree<BboxedIndex<GenericNode<PI, GenericIndex<CW>>>> {
|
||||
self.geometry_with_rtree.rtree()
|
||||
}
|
||||
|
||||
pub fn layer_count(&self) -> usize {
|
||||
*self.geometry_with_rtree.layer_count()
|
||||
}
|
||||
|
||||
pub fn graph(&self) -> &StableDiGraph<GenericNode<PW, CW>, GeometryLabel, usize> {
|
||||
self.geometry_with_rtree.graph()
|
||||
}
|
||||
}
|
||||
|
||||
fn edit_remove_from_map<I: Eq + Ord, T>(
|
||||
|
|
@ -347,15 +351,16 @@ impl<
|
|||
DW: AccessDotWeight + Into<PW> + GetLayer,
|
||||
SW: AccessSegWeight + Into<PW> + GetLayer,
|
||||
BW: AccessBendWeight + Into<PW> + GetLayer,
|
||||
CW: Copy,
|
||||
CW: Clone,
|
||||
Cek: Copy,
|
||||
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + Eq + Ord + Copy,
|
||||
DI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
SI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
BI: GetPetgraphIndex + Into<PI> + Eq + Ord + Copy,
|
||||
> ApplyGeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
for RecordingGeometryWithRtree<PW, DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
> ApplyGeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
for RecordingGeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
fn apply(&mut self, edit: &GeometryEdit<DW, SW, BW, CW, PI, DI, SI, BI>) {
|
||||
fn apply(&mut self, edit: &GeometryEdit<DW, SW, BW, CW, Cek, PI, DI, SI, BI>) {
|
||||
for (compound, (maybe_old_data, ..)) in &edit.compounds {
|
||||
if maybe_old_data.is_some() {
|
||||
self.geometry_with_rtree.remove_compound(*compound);
|
||||
|
|
@ -403,11 +408,12 @@ impl<
|
|||
for (compound, (.., maybe_new_data)) in &edit.compounds {
|
||||
if let Some((members, weight)) = maybe_new_data {
|
||||
self.geometry_with_rtree
|
||||
.add_compound_at_index(*compound, *weight);
|
||||
.add_compound_at_index(*compound, weight.clone());
|
||||
|
||||
for member in members {
|
||||
for (entry_kind, member) in members {
|
||||
self.geometry_with_rtree.add_to_compound(
|
||||
GenericIndex::<PW>::new(member.petgraph_index()),
|
||||
*entry_kind,
|
||||
*compound,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,14 +39,14 @@ impl RTreeObject for Bbox {
|
|||
pub type BboxedIndex<I> = GeomWithData<Bbox, I>;
|
||||
|
||||
#[derive(Debug, Getters)]
|
||||
pub struct GeometryWithRtree<PW, DW, SW, BW, CW, PI, DI, SI, BI> {
|
||||
geometry: Geometry<PW, DW, SW, BW, CW, PI, DI, SI, BI>,
|
||||
pub struct GeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI> {
|
||||
geometry: Geometry<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>,
|
||||
rtree: RTree<BboxedIndex<GenericNode<PI, GenericIndex<CW>>>>,
|
||||
layer_count: usize,
|
||||
}
|
||||
|
||||
impl<PW: Clone, DW, SW, BW, CW: Clone, PI: Clone, DI, SI, BI> Clone
|
||||
for GeometryWithRtree<PW, DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
impl<PW: Clone, DW, SW, BW, CW: Clone, Cek: Clone, PI: Clone, DI, SI, BI> Clone
|
||||
for GeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
|
|
@ -57,6 +57,14 @@ impl<PW: Clone, DW, SW, BW, CW: Clone, PI: Clone, DI, SI, BI> Clone
|
|||
}
|
||||
}
|
||||
|
||||
impl<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
GeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
pub fn graph(&self) -> &StableDiGraph<GenericNode<PW, CW>, GeometryLabel<Cek>, usize> {
|
||||
self.geometry.graph()
|
||||
}
|
||||
}
|
||||
|
||||
#[debug_invariant(self.test_envelopes())]
|
||||
#[debug_invariant(self.geometry.graph().node_count() == self.rtree.size())]
|
||||
impl<
|
||||
|
|
@ -64,16 +72,17 @@ impl<
|
|||
DW: AccessDotWeight + Into<PW> + GetLayer,
|
||||
SW: AccessSegWeight + Into<PW> + GetLayer,
|
||||
BW: AccessBendWeight + Into<PW> + GetLayer,
|
||||
CW: Copy,
|
||||
CW: Clone,
|
||||
Cek: Copy,
|
||||
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + PartialEq + Copy,
|
||||
DI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
SI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
BI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
> GeometryWithRtree<PW, DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
> GeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
pub fn new(layer_count: usize) -> Self {
|
||||
Self {
|
||||
geometry: Geometry::<PW, DW, SW, BW, CW, PI, DI, SI, BI>::new(),
|
||||
geometry: Geometry::new(),
|
||||
rtree: RTree::new(),
|
||||
layer_count,
|
||||
}
|
||||
|
|
@ -169,9 +178,15 @@ impl<
|
|||
.add_compound_at_index(GenericIndex::<CW>::new(compound.petgraph_index()), weight);
|
||||
}
|
||||
|
||||
pub fn add_to_compound<W>(&mut self, primitive: GenericIndex<W>, compound: GenericIndex<CW>) {
|
||||
pub fn add_to_compound<W>(
|
||||
&mut self,
|
||||
primitive: GenericIndex<W>,
|
||||
entry_kind: Cek,
|
||||
compound: GenericIndex<CW>,
|
||||
) {
|
||||
self.rtree.remove(&self.make_compound_bbox(compound));
|
||||
self.geometry.add_to_compound(primitive, compound);
|
||||
self.geometry
|
||||
.add_to_compound(primitive, entry_kind, compound);
|
||||
self.rtree.insert(self.make_compound_bbox(compound));
|
||||
}
|
||||
|
||||
|
|
@ -277,12 +292,13 @@ impl<
|
|||
DW: AccessDotWeight + Into<PW> + GetLayer,
|
||||
SW: AccessSegWeight + Into<PW> + GetLayer,
|
||||
BW: AccessBendWeight + Into<PW> + GetLayer,
|
||||
CW: Copy,
|
||||
CW: Clone,
|
||||
Cek: Copy,
|
||||
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + PartialEq + Copy,
|
||||
DI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
SI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
BI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
> GeometryWithRtree<PW, DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
> GeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
fn init_dot_bbox(&mut self, dot: DI) {
|
||||
self.rtree.insert(self.make_dot_bbox(dot));
|
||||
|
|
@ -347,7 +363,9 @@ impl<
|
|||
) -> BboxedIndex<GenericNode<PI, GenericIndex<CW>>> {
|
||||
let mut aabb = AABB::<[f64; 3]>::new_empty();
|
||||
|
||||
for member in self.geometry.compound_members(compound) {
|
||||
// NOTE(fogti): perhaps allow `entry_kind` to specify if it
|
||||
// should be considered part of the bounding box or not
|
||||
for (_, member) in self.geometry.compound_members(compound) {
|
||||
aabb.merge(&self.make_bbox(member).geom().aabb);
|
||||
}
|
||||
|
||||
|
|
@ -378,10 +396,6 @@ impl<
|
|||
}
|
||||
}
|
||||
|
||||
pub fn graph(&self) -> &StableDiGraph<GenericNode<PW, CW>, GeometryLabel, usize> {
|
||||
self.geometry.graph()
|
||||
}
|
||||
|
||||
fn test_envelopes(&self) -> bool {
|
||||
!self.rtree.iter().any(|wrapper| {
|
||||
// TODO: Test envelopes of compounds too.
|
||||
|
|
@ -407,14 +421,17 @@ impl<
|
|||
DW: AccessDotWeight + Into<PW> + GetLayer,
|
||||
SW: AccessSegWeight + Into<PW> + GetLayer,
|
||||
BW: AccessBendWeight + Into<PW> + GetLayer,
|
||||
CW: Copy,
|
||||
CW: Clone,
|
||||
Cek: Copy,
|
||||
PI: GetPetgraphIndex + TryInto<DI> + TryInto<SI> + TryInto<BI> + PartialEq + Copy,
|
||||
DI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
SI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
BI: GetPetgraphIndex + Into<PI> + Copy,
|
||||
> ManageCompounds<CW, GenericIndex<CW>>
|
||||
for GeometryWithRtree<PW, DW, SW, BW, CW, PI, DI, SI, BI>
|
||||
> ManageCompounds<CW> for GeometryWithRtree<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
|
||||
{
|
||||
type GeneralIndex = PI;
|
||||
type EntryKind = Cek;
|
||||
|
||||
fn add_compound(&mut self, weight: CW) -> GenericIndex<CW> {
|
||||
let compound = self.geometry.add_compound(weight);
|
||||
self.rtree.insert(self.make_compound_bbox(compound));
|
||||
|
|
@ -426,15 +443,28 @@ impl<
|
|||
self.geometry.remove_compound(compound);
|
||||
}
|
||||
|
||||
fn add_to_compound<W>(&mut self, primitive: GenericIndex<W>, compound: GenericIndex<CW>) {
|
||||
self.geometry.add_to_compound(primitive, compound);
|
||||
fn add_to_compound<I>(&mut self, primitive: I, kind: Cek, compound: GenericIndex<CW>)
|
||||
where
|
||||
I: Copy + GetPetgraphIndex,
|
||||
{
|
||||
self.geometry.add_to_compound(primitive, kind, compound);
|
||||
}
|
||||
|
||||
fn compound_weight(&self, compound: GenericIndex<CW>) -> CW {
|
||||
fn compound_weight(&self, compound: GenericIndex<CW>) -> &CW {
|
||||
self.geometry.compound_weight(compound)
|
||||
}
|
||||
|
||||
fn compounds<W>(&self, node: GenericIndex<W>) -> impl Iterator<Item = GenericIndex<CW>> {
|
||||
fn compound_members(
|
||||
&self,
|
||||
compound: GenericIndex<CW>,
|
||||
) -> impl Iterator<Item = (Cek, Self::GeneralIndex)> {
|
||||
self.geometry.compound_members(compound)
|
||||
}
|
||||
|
||||
fn compounds<I>(&self, node: I) -> impl Iterator<Item = (Cek, GenericIndex<CW>)>
|
||||
where
|
||||
I: Copy + GetPetgraphIndex,
|
||||
{
|
||||
self.geometry.compounds(node)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ use enum_dispatch::enum_dispatch;
|
|||
use petgraph::stable_graph::NodeIndex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub trait MakeRef<'a, R: 'a, C> {
|
||||
fn ref_(&self, context: &'a C) -> R;
|
||||
pub trait MakeRef<'a, C> {
|
||||
type Output: 'a;
|
||||
fn ref_(&self, context: &'a C) -> Self::Output;
|
||||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
|
|
|
|||
|
|
@ -52,18 +52,20 @@ pub enum CompoundWeight {
|
|||
Via(ViaWeight),
|
||||
}
|
||||
|
||||
pub type CompoundEntryKind = ();
|
||||
|
||||
/// The alias to differ node types
|
||||
pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<CompoundWeight>>;
|
||||
pub type LayoutEdit = DrawingEdit<CompoundWeight>;
|
||||
pub type LayoutEdit = DrawingEdit<CompoundWeight, CompoundEntryKind>;
|
||||
|
||||
#[derive(Clone, Debug, Getters)]
|
||||
/// Structure for managing the Layout design
|
||||
pub struct Layout<R> {
|
||||
drawing: Drawing<CompoundWeight, R>,
|
||||
drawing: Drawing<CompoundWeight, CompoundEntryKind, R>,
|
||||
}
|
||||
|
||||
impl<R> Layout<R> {
|
||||
pub fn new(drawing: Drawing<CompoundWeight, R>) -> Self {
|
||||
pub fn new(drawing: Drawing<CompoundWeight, CompoundEntryKind, R>) -> Self {
|
||||
Self { drawing }
|
||||
}
|
||||
}
|
||||
|
|
@ -117,12 +119,11 @@ impl<R: AccessRules> Layout<R> {
|
|||
}),
|
||||
) {
|
||||
Ok(dot) => {
|
||||
self.drawing.add_to_compound(recorder, dot, compound);
|
||||
self.drawing.add_to_compound(recorder, dot, (), compound);
|
||||
dots.push(dot);
|
||||
}
|
||||
Err(err) => {
|
||||
// Remove inserted dots.
|
||||
|
||||
self.drawing.remove_compound(recorder, compound);
|
||||
|
||||
for dot in dots.iter().rev() {
|
||||
|
|
@ -232,6 +233,7 @@ impl<R: AccessRules> Layout<R> {
|
|||
self.drawing.add_to_compound(
|
||||
recorder,
|
||||
GenericIndex::<()>::new(i.petgraph_index()),
|
||||
(),
|
||||
poly_compound,
|
||||
);
|
||||
}
|
||||
|
|
@ -250,7 +252,8 @@ impl<R: AccessRules> Layout<R> {
|
|||
);
|
||||
|
||||
// maybe this should be a different edge kind
|
||||
self.drawing.add_to_compound(recorder, apex, poly_compound);
|
||||
self.drawing
|
||||
.add_to_compound(recorder, apex, (), poly_compound);
|
||||
|
||||
assert!(is_apex(&self.drawing, apex));
|
||||
|
||||
|
|
@ -265,13 +268,6 @@ impl<R: AccessRules> Layout<R> {
|
|||
self.drawing.remove_band(recorder, band)
|
||||
}
|
||||
|
||||
pub fn polys<W: 'static>(
|
||||
&self,
|
||||
node: GenericIndex<W>,
|
||||
) -> impl Iterator<Item = GenericIndex<CompoundWeight>> + '_ {
|
||||
self.drawing.compounds(node)
|
||||
}
|
||||
|
||||
pub fn poly_nodes(&self) -> impl Iterator<Item = GenericIndex<PolyWeight>> + '_ {
|
||||
self.drawing.rtree().iter().filter_map(|wrapper| {
|
||||
if let NodeIndex::Compound(compound) = wrapper.data {
|
||||
|
|
@ -308,7 +304,7 @@ impl<R: AccessRules> Layout<R> {
|
|||
pub fn poly_members(
|
||||
&self,
|
||||
poly: GenericIndex<PolyWeight>,
|
||||
) -> impl Iterator<Item = PrimitiveIndex> + '_ {
|
||||
) -> impl Iterator<Item = ((), PrimitiveIndex)> + '_ {
|
||||
self.drawing
|
||||
.geometry()
|
||||
.compound_members(GenericIndex::new(poly.petgraph_index()))
|
||||
|
|
@ -464,6 +460,7 @@ impl<R: AccessRules>
|
|||
SegWeight,
|
||||
BendWeight,
|
||||
CompoundWeight,
|
||||
CompoundEntryKind,
|
||||
PrimitiveIndex,
|
||||
DotIndex,
|
||||
SegIndex,
|
||||
|
|
|
|||
|
|
@ -13,13 +13,12 @@ use crate::{
|
|||
dot::FixedDotIndex,
|
||||
graph::{GetMaybeNet, PrimitiveIndex},
|
||||
primitive::GetLimbs,
|
||||
rules::AccessRules,
|
||||
seg::SegIndex,
|
||||
Drawing,
|
||||
},
|
||||
geometry::{GetLayer, GetSetPos},
|
||||
geometry::{compound::ManageCompounds, GetLayer, GetSetPos},
|
||||
graph::{GenericIndex, GetPetgraphIndex, MakeRef},
|
||||
layout::CompoundWeight,
|
||||
layout::{CompoundEntryKind, CompoundWeight},
|
||||
};
|
||||
|
||||
use super::Layout;
|
||||
|
|
@ -32,17 +31,18 @@ pub trait MakePolygon {
|
|||
#[derive(Debug)]
|
||||
pub struct PolyRef<'a, R> {
|
||||
pub index: GenericIndex<PolyWeight>,
|
||||
drawing: &'a Drawing<CompoundWeight, R>,
|
||||
drawing: &'a Drawing<CompoundWeight, CompoundEntryKind, R>,
|
||||
}
|
||||
|
||||
impl<'a, R: AccessRules> MakeRef<'a, PolyRef<'a, R>, Layout<R>> for GenericIndex<PolyWeight> {
|
||||
impl<'a, R: 'a> MakeRef<'a, Layout<R>> for GenericIndex<PolyWeight> {
|
||||
type Output = PolyRef<'a, R>;
|
||||
fn ref_(&self, layout: &'a Layout<R>) -> PolyRef<'a, R> {
|
||||
PolyRef::new(*self, layout.drawing())
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn is_apex<'a, R: AccessRules>(
|
||||
drawing: &'a Drawing<CompoundWeight, R>,
|
||||
pub(super) fn is_apex<R>(
|
||||
drawing: &Drawing<CompoundWeight, CompoundEntryKind, R>,
|
||||
dot: FixedDotIndex,
|
||||
) -> bool {
|
||||
!drawing
|
||||
|
|
@ -53,8 +53,11 @@ pub(super) fn is_apex<'a, R: AccessRules>(
|
|||
&& drawing.primitive(dot).bends().is_empty()
|
||||
}
|
||||
|
||||
impl<'a, R: AccessRules> PolyRef<'a, R> {
|
||||
pub fn new(index: GenericIndex<PolyWeight>, drawing: &'a Drawing<CompoundWeight, R>) -> Self {
|
||||
impl<'a, R> PolyRef<'a, R> {
|
||||
pub fn new(
|
||||
index: GenericIndex<PolyWeight>,
|
||||
drawing: &'a Drawing<CompoundWeight, CompoundEntryKind, R>,
|
||||
) -> Self {
|
||||
Self { index, drawing }
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +69,7 @@ impl<'a, R: AccessRules> PolyRef<'a, R> {
|
|||
self.drawing
|
||||
.geometry()
|
||||
.compound_members(self.index.into())
|
||||
.find_map(|primitive_node| {
|
||||
.find_map(|(_kind, primitive_node)| {
|
||||
if let PrimitiveIndex::FixedDot(dot) = primitive_node {
|
||||
if self.is_apex(dot) {
|
||||
return Some(dot);
|
||||
|
|
@ -79,7 +82,7 @@ impl<'a, R: AccessRules> PolyRef<'a, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: AccessRules> GetLayer for PolyRef<'_, R> {
|
||||
impl<R> GetLayer for PolyRef<'_, R> {
|
||||
fn layer(&self) -> usize {
|
||||
if let CompoundWeight::Poly(weight) = self.drawing.compound_weight(self.index.into()) {
|
||||
weight.layer()
|
||||
|
|
@ -89,20 +92,20 @@ impl<R: AccessRules> GetLayer for PolyRef<'_, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: AccessRules> GetMaybeNet for PolyRef<'_, R> {
|
||||
impl<R> GetMaybeNet for PolyRef<'_, R> {
|
||||
fn maybe_net(&self) -> Option<usize> {
|
||||
self.drawing.compound_weight(self.index.into()).maybe_net()
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: AccessRules> MakePolygon for PolyRef<'_, R> {
|
||||
impl<R> MakePolygon for PolyRef<'_, R> {
|
||||
fn shape(&self) -> Polygon {
|
||||
Polygon::new(
|
||||
LineString::from(
|
||||
self.drawing
|
||||
.geometry()
|
||||
.compound_members(self.index.into())
|
||||
.filter_map(|primitive_node| {
|
||||
.filter_map(|(_kind, primitive_node)| {
|
||||
let PrimitiveIndex::FixedDot(dot) = primitive_node else {
|
||||
return None;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,18 +15,21 @@ use crate::{
|
|||
},
|
||||
geometry::primitive::{DotShape, PrimitiveShape},
|
||||
graph::{GenericIndex, GetPetgraphIndex},
|
||||
layout::CompoundWeight,
|
||||
layout::{CompoundEntryKind, CompoundWeight},
|
||||
math::Circle,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Via<'a, R> {
|
||||
pub index: GenericIndex<ViaWeight>,
|
||||
drawing: &'a Drawing<CompoundWeight, R>,
|
||||
drawing: &'a Drawing<CompoundWeight, CompoundEntryKind, R>,
|
||||
}
|
||||
|
||||
impl<'a, R> Via<'a, R> {
|
||||
pub fn new(index: GenericIndex<ViaWeight>, drawing: &'a Drawing<CompoundWeight, R>) -> Self {
|
||||
pub fn new(
|
||||
index: GenericIndex<ViaWeight>,
|
||||
drawing: &'a Drawing<CompoundWeight, CompoundEntryKind, R>,
|
||||
) -> Self {
|
||||
Self { index, drawing }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue