geometry: have a common `Shape` object for both primitives and compounds

This commit is contained in:
Mikolaj Wielgus 2024-04-18 15:41:01 +02:00
parent e5bae501ad
commit 43f1248a76
15 changed files with 171 additions and 137 deletions

View File

@ -6,13 +6,14 @@ use std::{
}; };
use topola::{ use topola::{
drawing::{graph::MakePrimitive, primitive::MakeShape, Drawing}, drawing::{graph::MakePrimitive, primitive::MakePrimitiveShape, Drawing},
dsn::{design::DsnDesign, rules::DsnRules}, dsn::{design::DsnDesign, rules::DsnRules},
geometry::{ geometry::{
compound::CompoundManagerTrait,
primitive::{BendShape, DotShape, PrimitiveShape, SegShape}, primitive::{BendShape, DotShape, PrimitiveShape, SegShape},
GenericNode, GenericNode,
}, },
layout::{zone::MakePolygon, Layout}, layout::{zone::MakePolyShape, Layout},
math::Circle, math::Circle,
overlay::Overlay, overlay::Overlay,
}; };
@ -168,7 +169,10 @@ impl eframe::App for App {
for zone in layout.layer_zones(1) { for zone in layout.layer_zones(1) {
painter.paint_polygon( painter.paint_polygon(
&zone.polygon(&layout.drawing()), &layout
.compound_weight(zone)
.shape(&layout.drawing(), zone)
.polygon,
egui::Color32::from_rgb(52, 52, 200), egui::Color32::from_rgb(52, 52, 200),
) )
} }
@ -190,7 +194,10 @@ impl eframe::App for App {
for zone in layout.layer_zones(0) { for zone in layout.layer_zones(0) {
painter.paint_polygon( painter.paint_polygon(
&zone.polygon(&layout.drawing()), &layout
.compound_weight(zone)
.shape(&layout.drawing(), zone)
.polygon,
egui::Color32::from_rgb(200, 52, 52), egui::Color32::from_rgb(200, 52, 52),
) )
} }

View File

@ -15,7 +15,7 @@ use petgraph::visit::{EdgeRef, IntoEdgeReferences};
use topola::draw::DrawException; use topola::draw::DrawException;
use topola::drawing::dot::FixedDotWeight; use topola::drawing::dot::FixedDotWeight;
use topola::drawing::graph::{MakePrimitive, PrimitiveIndex}; use topola::drawing::graph::{MakePrimitive, PrimitiveIndex};
use topola::drawing::primitive::MakeShape; use topola::drawing::primitive::MakePrimitiveShape;
use topola::drawing::rules::{Conditions, RulesTrait}; use topola::drawing::rules::{Conditions, RulesTrait};
use topola::drawing::seg::FixedSegWeight; use topola::drawing::seg::FixedSegWeight;
use topola::drawing::zone::MakePolygon; use topola::drawing::zone::MakePolygon;

View File

@ -21,7 +21,9 @@ use crate::drawing::{
bend::{FixedBendIndex, LooseBendIndex, LooseBendWeight}, bend::{FixedBendIndex, LooseBendIndex, LooseBendWeight},
dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
graph::{MakePrimitive, PrimitiveIndex, PrimitiveWeight}, graph::{MakePrimitive, PrimitiveIndex, PrimitiveWeight},
primitive::{GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetOtherJoint, MakeShape}, primitive::{
GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetOtherJoint, MakePrimitiveShape,
},
seg::{ seg::{
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex, FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
SeqLooseSegIndex, SeqLooseSegWeight, SeqLooseSegIndex, SeqLooseSegWeight,
@ -37,7 +39,6 @@ use crate::geometry::{
SegWeightTrait, SegWeightTrait,
}; };
use crate::graph::{GenericIndex, GetNodeIndex}; use crate::graph::{GenericIndex, GetNodeIndex};
use crate::layout::zone::{ZoneIndex, ZoneWeight};
use crate::math::NoTangents; use crate::math::NoTangents;
use super::bend::BendWeight; use super::bend::BendWeight;

View File

@ -6,7 +6,7 @@ use crate::{
bend::BendIndex, bend::BendIndex,
dot::{DotIndex, FixedDotIndex, LooseDotIndex}, dot::{DotIndex, FixedDotIndex, LooseDotIndex},
graph::MakePrimitive, graph::MakePrimitive,
primitive::{GetCore, GetInnerOuter, GetOtherJoint, GetWeight, MakeShape}, primitive::{GetCore, GetInnerOuter, GetOtherJoint, GetWeight, MakePrimitiveShape},
rules::GetConditions, rules::GetConditions,
Drawing, Drawing,
}, },

View File

@ -34,7 +34,7 @@ pub trait GetWeight<W> {
} }
#[enum_dispatch] #[enum_dispatch]
pub trait MakeShape { pub trait MakePrimitiveShape {
fn shape(&self) -> PrimitiveShape; fn shape(&self) -> PrimitiveShape;
} }
@ -160,7 +160,7 @@ macro_rules! impl_loose_primitive {
GetMaybeNet, GetMaybeNet,
GetWidth, GetWidth,
GetDrawing, GetDrawing,
MakeShape, MakePrimitiveShape,
GetLimbs, GetLimbs,
GetConditions GetConditions
)] )]
@ -279,7 +279,7 @@ impl<'a, CW: Copy, R: RulesTrait> FixedDot<'a, CW, R> {
} }
} }
impl<'a, CW: Copy, R: RulesTrait> MakeShape for FixedDot<'a, CW, R> { impl<'a, CW: Copy, R: RulesTrait> MakePrimitiveShape for FixedDot<'a, CW, R> {
fn shape(&self) -> PrimitiveShape { fn shape(&self) -> PrimitiveShape {
self.drawing.geometry().dot_shape(self.index.into()) self.drawing.geometry().dot_shape(self.index.into())
} }
@ -325,7 +325,7 @@ impl<'a, CW: Copy, R: RulesTrait> LooseDot<'a, CW, R> {
} }
} }
impl<'a, CW: Copy, R: RulesTrait> MakeShape for LooseDot<'a, CW, R> { impl<'a, CW: Copy, R: RulesTrait> MakePrimitiveShape for LooseDot<'a, CW, R> {
fn shape(&self) -> PrimitiveShape { fn shape(&self) -> PrimitiveShape {
self.drawing.geometry().dot_shape(self.index.into()) self.drawing.geometry().dot_shape(self.index.into())
} }
@ -348,7 +348,7 @@ impl<'a, CW: Copy, R: RulesTrait> GetLimbs for LooseDot<'a, CW, R> {
pub type FixedSeg<'a, CW, R> = GenericPrimitive<'a, FixedSegWeight, CW, R>; pub type FixedSeg<'a, CW, R> = GenericPrimitive<'a, FixedSegWeight, CW, R>;
impl_fixed_primitive!(FixedSeg, FixedSegWeight); impl_fixed_primitive!(FixedSeg, FixedSegWeight);
impl<'a, CW: Copy, R: RulesTrait> MakeShape for FixedSeg<'a, CW, R> { impl<'a, CW: Copy, R: RulesTrait> MakePrimitiveShape for FixedSeg<'a, CW, R> {
fn shape(&self) -> PrimitiveShape { fn shape(&self) -> PrimitiveShape {
self.drawing.geometry().seg_shape(self.index.into()) self.drawing.geometry().seg_shape(self.index.into())
} }
@ -374,7 +374,7 @@ impl<'a, CW: Copy, R: RulesTrait> GetOtherJoint<FixedDotIndex, FixedDotIndex>
pub type LoneLooseSeg<'a, CW, R> = GenericPrimitive<'a, LoneLooseSegWeight, CW, R>; pub type LoneLooseSeg<'a, CW, R> = GenericPrimitive<'a, LoneLooseSegWeight, CW, R>;
impl_loose_primitive!(LoneLooseSeg, LoneLooseSegWeight); impl_loose_primitive!(LoneLooseSeg, LoneLooseSegWeight);
impl<'a, CW: Copy, R: RulesTrait> MakeShape for LoneLooseSeg<'a, CW, R> { impl<'a, CW: Copy, R: RulesTrait> MakePrimitiveShape for LoneLooseSeg<'a, CW, R> {
fn shape(&self) -> PrimitiveShape { fn shape(&self) -> PrimitiveShape {
self.drawing.geometry().seg_shape(self.index.into()) self.drawing.geometry().seg_shape(self.index.into())
} }
@ -402,7 +402,7 @@ impl<'a, CW: Copy, R: RulesTrait> GetOtherJoint<FixedDotIndex, FixedDotIndex>
pub type SeqLooseSeg<'a, CW, R> = GenericPrimitive<'a, SeqLooseSegWeight, CW, R>; pub type SeqLooseSeg<'a, CW, R> = GenericPrimitive<'a, SeqLooseSegWeight, CW, R>;
impl_loose_primitive!(SeqLooseSeg, SeqLooseSegWeight); impl_loose_primitive!(SeqLooseSeg, SeqLooseSegWeight);
impl<'a, CW: Copy, R: RulesTrait> MakeShape for SeqLooseSeg<'a, CW, R> { impl<'a, CW: Copy, R: RulesTrait> MakePrimitiveShape for SeqLooseSeg<'a, CW, R> {
fn shape(&self) -> PrimitiveShape { fn shape(&self) -> PrimitiveShape {
self.drawing.geometry().seg_shape(self.index.into()) self.drawing.geometry().seg_shape(self.index.into())
} }
@ -446,7 +446,7 @@ impl<'a, CW: Copy, R: RulesTrait> GetBendIndex for FixedBend<'a, CW, R> {
} }
} }
impl<'a, CW: Copy, R: RulesTrait> MakeShape for FixedBend<'a, CW, R> { impl<'a, CW: Copy, R: RulesTrait> MakePrimitiveShape for FixedBend<'a, CW, R> {
fn shape(&self) -> PrimitiveShape { fn shape(&self) -> PrimitiveShape {
self.drawing.geometry().bend_shape(self.index.into()) self.drawing.geometry().bend_shape(self.index.into())
} }
@ -487,7 +487,7 @@ impl<'a, CW: Copy, R: RulesTrait> From<LooseBend<'a, CW, R>> for BendIndex {
} }
} }
impl<'a, CW: Copy, R: RulesTrait> MakeShape for LooseBend<'a, CW, R> { impl<'a, CW: Copy, R: RulesTrait> MakePrimitiveShape for LooseBend<'a, CW, R> {
fn shape(&self) -> PrimitiveShape { fn shape(&self) -> PrimitiveShape {
self.drawing.geometry().bend_shape(self.index.into()) self.drawing.geometry().bend_shape(self.index.into())
} }

View File

@ -12,10 +12,7 @@ use crate::{
}, },
geometry::compound::CompoundManagerTrait, geometry::compound::CompoundManagerTrait,
graph::{GenericIndex, GetNodeIndex}, graph::{GenericIndex, GetNodeIndex},
layout::{ layout::{zone::SolidZoneWeight, Layout},
zone::{SolidZoneWeight, ZoneIndex},
Layout,
},
math::Circle, math::Circle,
}; };
@ -367,7 +364,7 @@ impl DsnDesign {
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}, },
ZoneIndex::Solid(GenericIndex::new(zone.node_index())), zone,
) )
.unwrap(); .unwrap();
let dot_2_1 = layout let dot_2_1 = layout
@ -380,7 +377,7 @@ impl DsnDesign {
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}, },
ZoneIndex::Solid(GenericIndex::new(zone.node_index())), zone,
) )
.unwrap(); .unwrap();
let dot_2_2 = layout let dot_2_2 = layout
@ -393,7 +390,7 @@ impl DsnDesign {
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}, },
ZoneIndex::Solid(GenericIndex::new(zone.node_index())), zone,
) )
.unwrap(); .unwrap();
let dot_1_2 = layout let dot_1_2 = layout
@ -406,7 +403,7 @@ impl DsnDesign {
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}, },
ZoneIndex::Solid(GenericIndex::new(zone.node_index())), zone,
) )
.unwrap(); .unwrap();
// Sides. // Sides.
@ -419,7 +416,7 @@ impl DsnDesign {
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}, },
ZoneIndex::Solid(GenericIndex::new(zone.node_index())), zone,
) )
.unwrap(); .unwrap();
layout layout
@ -431,7 +428,7 @@ impl DsnDesign {
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}, },
ZoneIndex::Solid(GenericIndex::new(zone.node_index())), zone,
) )
.unwrap(); .unwrap();
layout layout
@ -443,7 +440,7 @@ impl DsnDesign {
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}, },
ZoneIndex::Solid(GenericIndex::new(zone.node_index())), zone,
) )
.unwrap(); .unwrap();
layout layout
@ -455,7 +452,7 @@ impl DsnDesign {
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}, },
ZoneIndex::Solid(GenericIndex::new(zone.node_index())), zone,
) )
.unwrap(); .unwrap();
} }
@ -567,7 +564,7 @@ impl DsnDesign {
}, },
// TODO: This manual retagging shouldn't be necessary, `.into()` should suffice. // TODO: This manual retagging shouldn't be necessary, `.into()` should suffice.
//GenericIndex::new(zone.node_index()).into(), //GenericIndex::new(zone.node_index()).into(),
ZoneIndex::Solid(GenericIndex::new(zone.node_index())), zone,
) )
.unwrap(); .unwrap();
@ -592,7 +589,7 @@ impl DsnDesign {
maybe_net: Some(net), maybe_net: Some(net),
}, },
// TODO: This manual retagging shouldn't be necessary, `.into()` should suffice. // TODO: This manual retagging shouldn't be necessary, `.into()` should suffice.
ZoneIndex::Solid(GenericIndex::new(zone.node_index())), zone,
) )
.unwrap(); .unwrap();
@ -607,7 +604,7 @@ impl DsnDesign {
maybe_net: Some(net), maybe_net: Some(net),
}, },
// TODO: This manual retagging shouldn't be necessary, `.into()` should suffice. // TODO: This manual retagging shouldn't be necessary, `.into()` should suffice.
ZoneIndex::Solid(GenericIndex::new(zone.node_index())), zone,
) )
.unwrap(); .unwrap();

View File

@ -1,6 +1,7 @@
#[macro_use] #[macro_use]
mod geometry; mod geometry;
pub mod compound; pub mod compound;
pub mod poly;
pub mod primitive; pub mod primitive;
pub mod shape; pub mod shape;
pub mod with_rtree; pub mod with_rtree;

15
src/geometry/poly.rs Normal file
View File

@ -0,0 +1,15 @@
use enum_dispatch::enum_dispatch;
use geo::{Contains, Point, Polygon};
use crate::geometry::shape::ShapeTrait;
#[derive(Debug, Clone, PartialEq)]
pub struct PolyShape {
pub polygon: Polygon,
}
impl ShapeTrait for PolyShape {
fn contains_point(&self, p: Point) -> bool {
self.polygon.contains(&p)
}
}

View File

@ -1,11 +0,0 @@
use enum_dispatch::enum_dispatch;
pub struct PolygonShape {
pub polygon: Polygon,
}
impl ShapeTrait for PolygonShape {
fn contains_point(&self, p: Point) -> bool {
self.polygon.contains(p)
}
}

View File

@ -1,9 +1,31 @@
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use geo::Point; use geo::Point;
use crate::geometry::primitive::PrimitiveShape; use crate::geometry::{
poly::PolyShape,
primitive::{BendShape, DotShape, PrimitiveShape, SegShape},
};
#[enum_dispatch] #[enum_dispatch]
pub trait ShapeTrait { pub trait ShapeTrait {
fn contains_point(&self, p: Point) -> bool; fn contains_point(&self, p: Point) -> bool;
} }
#[enum_dispatch(ShapeTrait)]
#[derive(Debug, Clone, PartialEq)]
pub enum Shape {
Dot(DotShape),
Seg(SegShape),
Bend(BendShape),
Poly(PolyShape),
}
impl From<PrimitiveShape> for Shape {
fn from(primitive: PrimitiveShape) -> Self {
match primitive {
PrimitiveShape::Dot(dot) => Shape::Dot(dot),
PrimitiveShape::Seg(seg) => Shape::Seg(seg),
PrimitiveShape::Bend(bend) => Shape::Bend(bend),
}
}
}

View File

@ -17,15 +17,15 @@ use crate::{
Drawing, Infringement, LayoutException, Drawing, Infringement, LayoutException,
}, },
geometry::{ geometry::{
compound::CompoundManagerTrait, BendWeightTrait, DotWeightTrait, GenericNode, Geometry, compound::CompoundManagerTrait, poly::PolyShape, BendWeightTrait, DotWeightTrait,
GeometryLabel, GetWidth, SegWeightTrait, GenericNode, Geometry, GeometryLabel, GetWidth, SegWeightTrait,
}, },
graph::{GenericIndex, GetNodeIndex}, graph::{GenericIndex, GetNodeIndex},
layout::{ layout::{
connectivity::{ connectivity::{
BandIndex, BandWeight, ConnectivityLabel, ConnectivityWeight, ContinentIndex, BandIndex, BandWeight, ConnectivityLabel, ConnectivityWeight, ContinentIndex,
}, },
zone::{PourZoneIndex, SolidZoneIndex, ZoneIndex, ZoneWeight}, zone::{PourZoneIndex, SolidZoneIndex, ZoneWeight},
}, },
}; };
@ -92,13 +92,12 @@ impl<R: RulesTrait> Layout<R> {
pub fn add_zone_fixed_dot( pub fn add_zone_fixed_dot(
&mut self, &mut self,
weight: FixedDotWeight, weight: FixedDotWeight,
zone: ZoneIndex, zone: GenericIndex<ZoneWeight>,
) -> Result<FixedDotIndex, Infringement> { ) -> Result<FixedDotIndex, Infringement> {
let maybe_dot = self.drawing.add_fixed_dot(weight); let maybe_dot = self.drawing.add_fixed_dot(weight);
if let Ok(dot) = maybe_dot { if let Ok(dot) = maybe_dot {
self.drawing self.drawing.add_to_compound(dot, zone);
.add_to_compound(dot, GenericIndex::new(zone.node_index()));
} }
maybe_dot maybe_dot
@ -118,13 +117,12 @@ impl<R: RulesTrait> Layout<R> {
from: FixedDotIndex, from: FixedDotIndex,
to: FixedDotIndex, to: FixedDotIndex,
weight: FixedSegWeight, weight: FixedSegWeight,
zone: ZoneIndex, zone: GenericIndex<ZoneWeight>,
) -> Result<FixedSegIndex, Infringement> { ) -> Result<FixedSegIndex, Infringement> {
let maybe_seg = self.add_fixed_seg(from, to, weight); let maybe_seg = self.add_fixed_seg(from, to, weight);
if let Ok(seg) = maybe_seg { if let Ok(seg) = maybe_seg {
self.drawing self.drawing.add_to_compound(seg, zone);
.add_to_compound(seg, GenericIndex::new(zone.node_index()));
} }
maybe_seg maybe_seg
@ -170,22 +168,17 @@ impl<R: RulesTrait> Layout<R> {
ContinentIndex::new(0.into()) ContinentIndex::new(0.into())
} }
pub fn zones(&self) -> impl Iterator<Item = ZoneIndex> + '_ { pub fn zones(&self) -> impl Iterator<Item = GenericIndex<ZoneWeight>> + '_ {
self.drawing.rtree().iter().filter_map(|wrapper| { self.drawing.rtree().iter().filter_map(|wrapper| {
if let NodeIndex::Compound(zone) = wrapper.data { if let NodeIndex::Compound(zone) = wrapper.data {
Some(match self.drawing.geometry().compound_weight(zone) { Some(zone)
ZoneWeight::Solid(..) => {
ZoneIndex::Solid(SolidZoneIndex::new(zone.node_index()))
}
ZoneWeight::Pour(..) => ZoneIndex::Pour(PourZoneIndex::new(zone.node_index())),
})
} else { } else {
None None
} }
}) })
} }
pub fn layer_zones(&self, layer: u64) -> impl Iterator<Item = ZoneIndex> + '_ { pub fn layer_zones(&self, layer: u64) -> impl Iterator<Item = GenericIndex<ZoneWeight>> + '_ {
self.drawing self.drawing
.rtree() .rtree()
.locate_in_envelope_intersecting(&AABB::from_corners( .locate_in_envelope_intersecting(&AABB::from_corners(
@ -194,21 +187,17 @@ impl<R: RulesTrait> Layout<R> {
)) ))
.filter_map(|wrapper| { .filter_map(|wrapper| {
if let NodeIndex::Compound(zone) = wrapper.data { if let NodeIndex::Compound(zone) = wrapper.data {
Some(match self.drawing.geometry().compound_weight(zone) { Some(zone)
ZoneWeight::Solid(..) => {
ZoneIndex::Solid(SolidZoneIndex::new(zone.node_index()))
}
ZoneWeight::Pour(..) => {
ZoneIndex::Pour(PourZoneIndex::new(zone.node_index()))
}
})
} else { } else {
None None
} }
}) })
} }
pub fn zone_members(&self, zone: ZoneIndex) -> impl Iterator<Item = PrimitiveIndex> + '_ { pub fn zone_members(
&self,
zone: GenericIndex<ZoneWeight>,
) -> impl Iterator<Item = PrimitiveIndex> + '_ {
self.drawing self.drawing
.geometry() .geometry()
.compound_members(GenericIndex::new(zone.node_index())) .compound_members(GenericIndex::new(zone.node_index()))

View File

@ -11,23 +11,20 @@ use crate::{
rules::RulesTrait, rules::RulesTrait,
Drawing, Drawing,
}, },
geometry::GetPos, geometry::{poly::PolyShape, GetPos},
graph::{GenericIndex, GetNodeIndex}, graph::{GenericIndex, GetNodeIndex},
}; };
#[enum_dispatch] #[enum_dispatch]
pub trait MakePolygon { pub trait MakePolyShape {
fn polygon<R: RulesTrait>(&self, drawing: &Drawing<impl Copy, R>) -> Polygon; fn shape<R: RulesTrait>(
&self,
drawing: &Drawing<ZoneWeight, R>,
index: GenericIndex<ZoneWeight>,
) -> PolyShape;
} }
#[enum_dispatch(GetNodeIndex, MakePolygon)] #[enum_dispatch(GetLayer, MakePolyShape)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ZoneIndex {
Solid(SolidZoneIndex),
Pour(PourZoneIndex),
}
#[enum_dispatch(GetLayer)]
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum ZoneWeight { pub enum ZoneWeight {
Solid(SolidZoneWeight), Solid(SolidZoneWeight),
@ -52,29 +49,35 @@ impl<'a> GetMaybeNet for SolidZoneWeight {
} }
} }
pub type SolidZoneIndex = GenericIndex<SolidZoneWeight>; impl MakePolyShape for SolidZoneWeight {
fn shape<R: RulesTrait>(
impl MakePolygon for SolidZoneIndex { &self,
fn polygon<R: RulesTrait>(&self, drawing: &Drawing<impl Copy, R>) -> Polygon { drawing: &Drawing<ZoneWeight, R>,
Polygon::new( index: GenericIndex<ZoneWeight>,
LineString::from( ) -> PolyShape {
drawing PolyShape {
.geometry() polygon: Polygon::new(
.compound_members(GenericIndex::new(self.node_index())) LineString::from(
.filter_map(|primitive_node| { drawing
if let Ok(dot) = DotIndex::try_from(primitive_node) { .geometry()
Some(drawing.geometry().dot_weight(dot).pos()) .compound_members(index)
} else { .filter_map(|primitive_node| {
None if let Ok(dot) = DotIndex::try_from(primitive_node) {
} Some(drawing.geometry().dot_weight(dot).pos())
}) } else {
.collect::<Vec<Point>>(), None
}
})
.collect::<Vec<Point>>(),
),
vec![],
), ),
vec![], }
)
} }
} }
pub type SolidZoneIndex = GenericIndex<SolidZoneWeight>;
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct PourZoneWeight { pub struct PourZoneWeight {
pub layer: u64, pub layer: u64,
@ -93,25 +96,31 @@ impl<'a> GetMaybeNet for PourZoneWeight {
} }
} }
pub type PourZoneIndex = GenericIndex<PourZoneWeight>; impl MakePolyShape for PourZoneWeight {
fn shape<R: RulesTrait>(
impl MakePolygon for PourZoneIndex { &self,
fn polygon<R: RulesTrait>(&self, drawing: &Drawing<impl Copy, R>) -> Polygon { drawing: &Drawing<ZoneWeight, R>,
Polygon::new( index: GenericIndex<ZoneWeight>,
LineString::from( ) -> PolyShape {
drawing PolyShape {
.geometry() polygon: Polygon::new(
.compound_members(GenericIndex::new(self.node_index())) LineString::from(
.filter_map(|primitive_node| { drawing
if let Ok(dot) = DotIndex::try_from(primitive_node) { .geometry()
Some(drawing.geometry().dot_weight(dot).pos()) .compound_members(index)
} else { .filter_map(|primitive_node| {
None if let Ok(dot) = DotIndex::try_from(primitive_node) {
} Some(drawing.geometry().dot_weight(dot).pos())
}) } else {
.collect::<Vec<Point>>(), None
}
})
.collect::<Vec<Point>>(),
),
vec![],
), ),
vec![], }
)
} }
} }
pub type PourZoneIndex = GenericIndex<PourZoneWeight>;

View File

@ -6,12 +6,18 @@ use rstar::AABB;
use crate::{ use crate::{
drawing::{ drawing::{
graph::{GetLayer, MakePrimitive, PrimitiveIndex}, graph::{GetLayer, MakePrimitive, PrimitiveIndex},
primitive::MakeShape, primitive::MakePrimitiveShape,
rules::RulesTrait, rules::RulesTrait,
}, },
geometry::shape::ShapeTrait, geometry::{
compound::CompoundManagerTrait,
shape::{Shape, ShapeTrait},
},
graph::GenericIndex, graph::GenericIndex,
layout::{zone::ZoneWeight, Layout, NodeIndex}, layout::{
zone::{MakePolyShape, ZoneWeight},
Layout, NodeIndex,
},
}; };
pub struct Overlay { pub struct Overlay {
@ -61,20 +67,18 @@ impl Overlay {
node: NodeIndex, node: NodeIndex,
p: Point, p: Point,
) -> bool { ) -> bool {
match node { let shape: Shape = match node {
NodeIndex::Primitive(primitive) => { NodeIndex::Primitive(primitive) => primitive.primitive(layout.drawing()).shape().into(),
if primitive NodeIndex::Compound(compound) => layout
.primitive(layout.drawing()) .compound_weight(compound)
.shape() .shape(layout.drawing(), compound)
.contains_point(p) .into(),
{ };
self.toggle_selection(node);
return true;
}
}
NodeIndex::Compound(compound) => (), // TODO.
}
if shape.contains_point(p) {
self.toggle_selection(node);
return true;
}
false false
} }

View File

@ -13,7 +13,7 @@ use crate::{
bend::{FixedBendIndex, LooseBendIndex}, bend::{FixedBendIndex, LooseBendIndex},
dot::FixedDotIndex, dot::FixedDotIndex,
graph::{MakePrimitive, PrimitiveIndex}, graph::{MakePrimitive, PrimitiveIndex},
primitive::{GetCore, MakeShape, Primitive}, primitive::{GetCore, MakePrimitiveShape, Primitive},
Drawing, Drawing,
}, },
geometry::primitive::PrimitiveShapeTrait, geometry::primitive::PrimitiveShapeTrait,

View File

@ -7,7 +7,7 @@ use thiserror::Error;
use crate::drawing::{ use crate::drawing::{
dot::FixedDotIndex, dot::FixedDotIndex,
graph::{MakePrimitive, PrimitiveIndex}, graph::{MakePrimitive, PrimitiveIndex},
primitive::MakeShape, primitive::MakePrimitiveShape,
rules::RulesTrait, rules::RulesTrait,
}; };
use crate::geometry::primitive::PrimitiveShapeTrait; use crate::geometry::primitive::PrimitiveShapeTrait;