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:
Ellen Emilia Anna Zscheile 2025-04-22 13:34:45 +02:00
parent 594bb51a57
commit 861869ab7c
21 changed files with 580 additions and 463 deletions

View File

@ -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),

View File

@ -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,

View File

@ -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) => {

View File

@ -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();

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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()
}

View File

@ -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))
}
}

View File

@ -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,

View File

@ -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,

View File

@ -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();

View File

@ -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()

View File

@ -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;
}

View File

@ -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);

View File

@ -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))
}
}

View File

@ -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,
);
}

View File

@ -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)
}
}

View File

@ -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]

View File

@ -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,

View File

@ -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;
};

View File

@ -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 }
}
}