fix(layout/poly): merge all the iterations over nodes in 'add_poly_with_nodes_intern'

This commit is contained in:
Ellen Emilia Anna Zscheile 2025-04-23 00:27:43 +02:00
parent 187f06a9ac
commit e74f5e009a
1 changed files with 48 additions and 43 deletions

View File

@ -6,7 +6,10 @@
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use geo::{algorithm::ConvexHull, IsConvex, LineString, Point, Polygon}; use geo::{
algorithm::{Centroid, ConvexHull},
IsConvex, LineString, Point, Polygon,
};
use crate::{ use crate::{
drawing::{ drawing::{
@ -17,7 +20,7 @@ use crate::{
seg::SegIndex, seg::SegIndex,
Drawing, Drawing,
}, },
geometry::{compound::ManageCompounds, shape::AccessShape, GetLayer, GetSetPos}, geometry::{compound::ManageCompounds, GetLayer, GetSetPos},
graph::{GenericIndex, GetPetgraphIndex, MakeRef}, graph::{GenericIndex, GetPetgraphIndex, MakeRef},
layout::{CompoundEntryKind, CompoundWeight, Layout, LayoutEdit}, layout::{CompoundEntryKind, CompoundWeight, Layout, LayoutEdit},
math::Circle, math::Circle,
@ -49,32 +52,6 @@ pub(super) fn add_poly_with_nodes_intern<R: AccessRules>(
layer: usize, layer: usize,
maybe_net: Option<usize>, maybe_net: Option<usize>,
) -> FixedDotIndex { ) -> FixedDotIndex {
let poly_compound = poly.into();
for i in nodes {
layout.drawing.add_to_compound(
recorder,
GenericIndex::<()>::new(i.petgraph_index()),
CompoundEntryKind::Normal,
poly_compound,
);
}
let shape = poly.ref_(layout).shape();
let apex = layout.add_fixed_dot_infringably(
recorder,
FixedDotWeight(GeneralDotWeight {
circle: Circle {
pos: shape.center(),
r: 100.0,
},
layer,
maybe_net,
}),
);
if !shape.exterior().is_convex() {
// create a temporary RTree to speed up lookups from O(n²) to O(n log n)
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
struct Rto { struct Rto {
pt: Point, pt: Point,
@ -94,19 +71,47 @@ pub(super) fn add_poly_with_nodes_intern<R: AccessRules>(
} }
} }
let poly_compound = poly.into();
let mut shape = Vec::with_capacity((nodes.len() + 1) / 2);
// create a temporary RTree to speed up lookups from O(n²) to O(n log n)
let mut temp_rtree = rstar::RTree::<Rto>::new(); let mut temp_rtree = rstar::RTree::<Rto>::new();
for &idx in nodes { for &idx in nodes {
layout.drawing.add_to_compound(
recorder,
GenericIndex::<()>::new(idx.petgraph_index()),
CompoundEntryKind::Normal,
poly_compound,
);
let PrimitiveIndex::FixedDot(dot) = idx else { let PrimitiveIndex::FixedDot(dot) = idx else {
continue; continue;
}; };
// we don't have an apex yet
let pt = layout.drawing.geometry().dot_weight(dot.into()).pos(); let pt = layout.drawing.geometry().dot_weight(dot.into()).pos();
shape.push(pt.0);
temp_rtree.insert(Rto { pt, idx }); temp_rtree.insert(Rto { pt, idx });
} }
let shape = Polygon::new(LineString(shape), Vec::new()).into_inner().0;
let apex = layout.add_fixed_dot_infringably(
recorder,
FixedDotWeight(GeneralDotWeight {
circle: Circle {
pos: shape.centroid().unwrap(),
r: 100.0,
},
layer,
maybe_net,
}),
);
if !shape.is_convex() {
// compute the convex hull // compute the convex hull
let convex_hull_exterior = shape.exterior().convex_hull().into_inner().0; let convex_hull_exterior = shape.convex_hull().into_inner().0;
for pt in convex_hull_exterior { for pt in convex_hull_exterior {
// note that the convex hull should be a strict subset of the points // note that the convex hull should be a strict subset of the points
// on the exterior of `shape` // on the exterior of `shape`
@ -191,7 +196,7 @@ impl<R> GetMaybeNet for PolyRef<'_, R> {
impl<R> MakePolygon for PolyRef<'_, R> { impl<R> MakePolygon for PolyRef<'_, R> {
fn shape(&self) -> Polygon { fn shape(&self) -> Polygon {
Polygon::new( Polygon::new(
LineString::from( LineString(
self.drawing self.drawing
.geometry() .geometry()
.compound_members(self.index.into()) .compound_members(self.index.into())
@ -203,10 +208,10 @@ impl<R> MakePolygon for PolyRef<'_, R> {
if is_apex(self.drawing, dot) { if is_apex(self.drawing, dot) {
None None
} else { } else {
Some(self.drawing.geometry().dot_weight(dot.into()).pos()) Some(self.drawing.geometry().dot_weight(dot.into()).pos().0)
} }
}) })
.collect::<Vec<Point>>(), .collect(),
), ),
vec![], vec![],
) )