diff --git a/topola-egui/src/display.rs b/topola-egui/src/display.rs index 8f27f62..37bee76 100644 --- a/topola-egui/src/display.rs +++ b/topola-egui/src/display.rs @@ -156,9 +156,9 @@ impl Display { polygon, workspace.appearance_panel.layer_color( ctx, - board.layer_desc(polygon.layer), + board.layer_desc(polygon.spec.layer), pin_selected, - (polygon.pin.is_none() && net_selected) || component_selected, + (polygon.spec.pin.is_none() && net_selected) || component_selected, ), ); } @@ -233,7 +233,7 @@ impl Display { color: egui::Color32, ) { let points: Vec = polygon - .vertices + .spec.vertices .iter() .map(|v| egui::pos2(v.x as f32, v.y as f32)) .collect(); diff --git a/topola/src/board/contains.rs b/topola/src/board/contains.rs index 50cbecf..c48c28e 100644 --- a/topola/src/board/contains.rs +++ b/topola/src/board/contains.rs @@ -97,7 +97,7 @@ impl Board { pub fn nets_contain_polygon(&self, selection: &NetSelection, id: PolygonId) -> bool { let polygon = self.layout.polygon(id); - let Some(net_name) = polygon.net.and_then(|net| self.net_name(net)) else { + let Some(net_name) = polygon.spec.net.and_then(|net| self.net_name(net)) else { return false; }; diff --git a/topola/src/board/interactors/drag_select.rs b/topola/src/board/interactors/drag_select.rs index b4b3c4d..96e8569 100644 --- a/topola/src/board/interactors/drag_select.rs +++ b/topola/src/board/interactors/drag_select.rs @@ -76,7 +76,7 @@ impl Interactor for DragSelectInteractor { && board .layout() .locate_polygons_prefer_layer_intersecting_rect(rect) - .all(|polygon_id| board.layout().polygon(polygon_id).pin.is_some()) + .all(|polygon_id| board.layout().polygon(polygon_id).spec.pin.is_some()) } SelectionContainMode::Window => { board @@ -94,7 +94,7 @@ impl Interactor for DragSelectInteractor { && board .layout() .locate_polygons_prefer_layer_inside_rect(rect) - .all(|polygon_id| board.layout().polygon(polygon_id).pin.is_some()) + .all(|polygon_id| board.layout().polygon(polygon_id).spec.pin.is_some()) } }; diff --git a/topola/src/board/select.rs b/topola/src/board/select.rs index 58076ba..6b37a84 100644 --- a/topola/src/board/select.rs +++ b/topola/src/board/select.rs @@ -62,7 +62,7 @@ impl Board { } for polygon_id in self.layout.layer_polygons(layer_id) { - if self.layout.polygon(polygon_id).pin != Some(pin_id) { + if self.layout.polygon(polygon_id).spec.pin != Some(pin_id) { continue; } @@ -105,7 +105,7 @@ impl Board { let polygon = self.layout.polygon(id); Some(ComponentSelector { - component: self.component_name(polygon.component?)?.to_string(), + component: self.component_name(polygon.spec.component?)?.to_string(), }) } @@ -137,7 +137,7 @@ impl Board { let polygon = self.layout.polygon(id); Some(NetSelector { - net: self.net_name(polygon.net?)?.to_string(), + net: self.net_name(polygon.spec.net?)?.to_string(), }) } @@ -172,8 +172,8 @@ impl Board { let polygon = self.layout.polygon(id); Some(PinSelector { - pin: self.pin_name(polygon.pin?)?.to_string(), - layer: self.layer_name(polygon.layer)?, + pin: self.pin_name(polygon.spec.pin?)?.to_string(), + layer: self.layer_name(polygon.spec.layer)?, }) } } diff --git a/topola/src/board/transforms/delete.rs b/topola/src/board/transforms/delete.rs index 1195616..e86fd77 100644 --- a/topola/src/board/transforms/delete.rs +++ b/topola/src/board/transforms/delete.rs @@ -35,7 +35,7 @@ impl Board { for polygon_id in self .resolve_net_polygons(selection.clone()) - .filter(|&polygon_id| self.layout.polygon(polygon_id).pin.is_none()) + .filter(|&polygon_id| self.layout.polygon(polygon_id).spec.pin.is_none()) .collect::>() .clone() { diff --git a/topola/src/layout/compounds/pin.rs b/topola/src/layout/compounds/pin.rs index 631f771..d683e6f 100644 --- a/topola/src/layout/compounds/pin.rs +++ b/topola/src/layout/compounds/pin.rs @@ -101,7 +101,7 @@ impl Layout { count += 1; } for &polygon_id in &pin.polygons { - sum = sum + self.polygon(polygon_id).center(); + sum = sum + self.polygon(polygon_id).centroid; count += 1; } diff --git a/topola/src/layout/delete.rs b/topola/src/layout/delete.rs index 6f0dd14..99507e5 100644 --- a/topola/src/layout/delete.rs +++ b/topola/src/layout/delete.rs @@ -98,8 +98,8 @@ impl Layout { pub fn delete_polygon(&mut self, polygon_id: PolygonId) { let polygon = self.polygon(polygon_id); let bbox = polygon.bbox(); - let component = polygon.component; - let pin = polygon.pin; + let component = polygon.spec.component; + let pin = polygon.spec.pin; if let Some(component_id) = component { self.components.modify(component_id.index(), |component| { diff --git a/topola/src/layout/infringement.rs b/topola/src/layout/infringement.rs index cd883ca..aee2a9d 100644 --- a/topola/src/layout/infringement.rs +++ b/topola/src/layout/infringement.rs @@ -431,7 +431,7 @@ impl Layout { PrimitiveId::Joint(joint_id) => self.joint(joint_id).spec.component, PrimitiveId::Segment(segment_id) => self.segment(segment_id).spec.component, PrimitiveId::Via(via_id) => self.via(via_id).spec.component, - PrimitiveId::Polygon(polygon_id) => self.polygon(polygon_id).component, + PrimitiveId::Polygon(polygon_id) => self.polygon(polygon_id).spec.component, } } @@ -449,7 +449,7 @@ impl Layout { PrimitiveId::Joint(joint_id) => self.joint(joint_id).spec.net, PrimitiveId::Segment(segment_id) => self.segment(segment_id).net, PrimitiveId::Via(via_id) => self.via(via_id).net, - PrimitiveId::Polygon(polygon_id) => self.polygon(polygon_id).net, + PrimitiveId::Polygon(polygon_id) => self.polygon(polygon_id).spec.net, } } diff --git a/topola/src/layout/insert.rs b/topola/src/layout/insert.rs index 9a199d5..18f28ba 100644 --- a/topola/src/layout/insert.rs +++ b/topola/src/layout/insert.rs @@ -147,8 +147,8 @@ impl Layout { pub fn insert_polygon(&mut self, polygon: Polygon) -> PolygonId { let bbox = polygon.bbox(); - let component_id = polygon.component; - let pin_id = polygon.pin; + let component_id = polygon.spec.component; + let pin_id = polygon.spec.pin; let polygon_id = PolygonId::new(self.polygons.push(polygon)); self.polygons_rtree diff --git a/topola/src/layout/locate.rs b/topola/src/layout/locate.rs index 682e008..c84caaa 100644 --- a/topola/src/layout/locate.rs +++ b/topola/src/layout/locate.rs @@ -462,7 +462,7 @@ impl Layout { .map(|geom_with_data| geom_with_data.data) .filter(move |&polygon_id| { let polygon = self.polygon(polygon_id); - rect.xy().intersects_polygon(&polygon.vertices) + rect.xy().intersects_polygon(&polygon.spec.vertices) }) } @@ -478,7 +478,7 @@ impl Layout { .map(|geom_with_data| geom_with_data.data) .filter(move |&polygon_id| { let polygon = self.polygon(polygon_id); - rect.intersects_polygon(&polygon.vertices) + rect.intersects_polygon(&polygon.spec.vertices) }) } @@ -505,7 +505,7 @@ impl Layout { .map(|geom_with_data| geom_with_data.data) .filter(move |&polygon_id| { let polygon = self.polygon(polygon_id); - rect.xy().contains_polygon(&polygon.vertices) + rect.xy().contains_polygon(&polygon.spec.vertices) }) } @@ -521,7 +521,7 @@ impl Layout { .map(|geom_with_data| geom_with_data.data) .filter(move |&polygon_id| { let polygon = self.polygon(polygon_id); - rect.contains_polygon(&polygon.vertices) + rect.contains_polygon(&polygon.spec.vertices) }) } @@ -550,7 +550,7 @@ impl Layout { } for polygon_id in self.locate_polygons_prefer_layer_intersecting_rect(rect) { - if let Some(net) = self.polygon(polygon_id).net { + if let Some(net) = self.polygon(polygon_id).spec.net { nets.insert(net); } } @@ -580,7 +580,7 @@ impl Layout { } for polygon_id in self.locate_polygons_intersecting_rect(rect) { - if let Some(net) = self.polygon(polygon_id).net { + if let Some(net) = self.polygon(polygon_id).spec.net { nets.insert(net); } } @@ -613,7 +613,7 @@ impl Layout { } for polygon_id in self.locate_polygons_prefer_layer_inside_rect(rect) { - if let Some(net) = self.polygon(polygon_id).net { + if let Some(net) = self.polygon(polygon_id).spec.net { nets.insert(net); } } @@ -643,7 +643,7 @@ impl Layout { } for polygon_id in self.locate_polygons_inside_rect(rect) { - if let Some(net) = self.polygon(polygon_id).net { + if let Some(net) = self.polygon(polygon_id).spec.net { nets.insert(net); } } diff --git a/topola/src/layout/mod.rs b/topola/src/layout/mod.rs index fa2640c..6085a85 100644 --- a/topola/src/layout/mod.rs +++ b/topola/src/layout/mod.rs @@ -158,7 +158,7 @@ impl Layout { .as_ref() .locate_in_envelope_intersecting(&envelope) .map(|geom_with_data| geom_with_data.data) - .filter(move |&id| self.polygon(id).layer == layer) + .filter(move |&id| self.polygon(id).spec.layer == layer) } fn whole_layer_aabb(layer: LayerId) -> AABB<[i64; 3]> { diff --git a/topola/src/layout/primitives/mod.rs b/topola/src/layout/primitives/mod.rs index ad1e0c6..cfbb0f6 100644 --- a/topola/src/layout/primitives/mod.rs +++ b/topola/src/layout/primitives/mod.rs @@ -34,7 +34,7 @@ impl Layout { PrimitiveId::Joint(joint_id) => self.joint(joint_id).spec.pin, PrimitiveId::Segment(segment_id) => self.segment(segment_id).spec.pin, PrimitiveId::Via(via_id) => self.via(via_id).spec.pin, - PrimitiveId::Polygon(polygon_id) => self.polygon(polygon_id).pin, + PrimitiveId::Polygon(polygon_id) => self.polygon(polygon_id).spec.pin, } } diff --git a/topola/src/layout/primitives/polygon.rs b/topola/src/layout/primitives/polygon.rs index 11a46d0..e293513 100644 --- a/topola/src/layout/primitives/polygon.rs +++ b/topola/src/layout/primitives/polygon.rs @@ -34,7 +34,7 @@ impl PolygonId { } #[derive(Clone, Debug)] -pub struct Polygon { +pub struct PolygonSpec { pub vertices: Vec>, pub layer: LayerId, pub net: Option, @@ -42,20 +42,26 @@ pub struct Polygon { pub pin: Option, } +#[derive(Clone, Debug)] +pub struct Polygon { + pub spec: PolygonSpec, + pub centroid: Vector2, +} + impl Polygon { pub fn bbox(&self) -> Rect3 { - let layer = self.layer.index() as i64; + let layer = self.spec.layer.index() as i64; let mut min = Vector2::new(i64::MAX, i64::MAX); let mut max = Vector2::new(i64::MIN, i64::MIN); - for vertex in &self.vertices { + for vertex in &self.spec.vertices { min.x = std::cmp::min(min.x, vertex.x); min.y = std::cmp::min(min.y, vertex.y); max.x = std::cmp::max(max.x, vertex.x); max.y = std::cmp::max(max.y, vertex.y); } - if self.vertices.is_empty() { + if self.spec.vertices.is_empty() { return Rect3::new(Vector3::new(0, 0, layer), Vector3::new(0, 0, layer)); } @@ -65,12 +71,7 @@ impl Polygon { ) } - pub fn center(&self) -> Vector2 { - crate::profile_function!(); - Vector2::::polygon_centroid(&self.vertices) - } - pub fn contains_point2(&self, point: Vector2) -> bool { - point.inside_polygon(&self.vertices) + point.inside_polygon(&self.spec.vertices) } } diff --git a/topola/src/layout/repulsion.rs b/topola/src/layout/repulsion.rs index 45e6865..05b0820 100644 --- a/topola/src/layout/repulsion.rs +++ b/topola/src/layout/repulsion.rs @@ -160,7 +160,7 @@ impl Layout { Self::repulsion_from_rect_overlap( self.joint_polygon_rect_overlap(infringer, infringee), self.joint(infringer).center(), - self.polygon(infringee).center(), + self.polygon(infringee).centroid, orientation, ) } @@ -238,7 +238,7 @@ impl Layout { Self::repulsion_from_rect_overlap( self.segment_polygon_rect_overlap(infringer, infringee), self.segment(infringer).center(), - self.polygon(infringee).center(), + self.polygon(infringee).centroid, orientation, ) } @@ -316,7 +316,7 @@ impl Layout { Self::repulsion_from_rect_overlap( self.via_polygon_rect_overlap(infringer, infringee), self.via(infringer).position, - self.polygon(infringee).center(), + self.polygon(infringee).centroid, orientation, ) } @@ -351,7 +351,7 @@ impl Layout { ) -> Vector2 { Self::repulsion_from_rect_overlap( self.polygon_joint_rect_overlap(infringer, infringee), - self.polygon(infringer).center(), + self.polygon(infringer).centroid, self.joint(infringee).center(), orientation, ) @@ -365,7 +365,7 @@ impl Layout { ) -> Vector2 { Self::repulsion_from_rect_overlap( self.polygon_segment_rect_overlap(infringer, infringee), - self.polygon(infringer).center(), + self.polygon(infringer).centroid, self.segment(infringee).center(), orientation, ) @@ -379,7 +379,7 @@ impl Layout { ) -> Vector2 { Self::repulsion_from_rect_overlap( self.polygon_via_rect_overlap(infringer, infringee), - self.polygon(infringer).center(), + self.polygon(infringer).centroid, self.via(infringee).position, orientation, ) @@ -393,8 +393,8 @@ impl Layout { ) -> Vector2 { Self::repulsion_from_rect_overlap( self.polygon_polygon_rect_overlap(infringer, infringee), - self.polygon(infringer).center(), - self.polygon(infringee).center(), + self.polygon(infringer).centroid, + self.polygon(infringee).centroid, orientation, ) } diff --git a/topola/src/layout/transforms/move_by.rs b/topola/src/layout/transforms/move_by.rs index 02ed98e..8d39379 100644 --- a/topola/src/layout/transforms/move_by.rs +++ b/topola/src/layout/transforms/move_by.rs @@ -32,9 +32,10 @@ impl Layout { for &polygon_id in &component.polygons { self.modify_polygon(polygon_id, |polygon| { polygon - .vertices + .spec.vertices .iter_mut() - .for_each(|vertex| *vertex += translation) + .for_each(|vertex| *vertex += translation); + polygon.centroid += translation; }); } } diff --git a/topola/src/navmesher.rs b/topola/src/navmesher.rs index d77a384..67f0302 100644 --- a/topola/src/navmesher.rs +++ b/topola/src/navmesher.rs @@ -236,7 +236,7 @@ impl NavmesherBoard { this.polygon_multiobstacles.insert( i, this.navmesher - .insert_multiobstacle(polygon.layer, polygon.vertices.clone()), + .insert_multiobstacle(polygon.spec.layer, polygon.spec.vertices.clone()), ); }*/ @@ -293,7 +293,7 @@ impl NavmesherBoard { self.polygon_multiobstacles.insert( polygon_id.index(), self.navmesher - .insert_multiobstacle(polygon.layer, polygon.vertices), + .insert_multiobstacle(polygon.spec.layer, polygon.spec.vertices), ); polygon_id diff --git a/topola/src/ratsnest.rs b/topola/src/ratsnest.rs index 1d87a4b..ad9b040 100644 --- a/topola/src/ratsnest.rs +++ b/topola/src/ratsnest.rs @@ -86,19 +86,19 @@ impl Ratsnest { } for (i, polygon) in board.layout().polygons().container().iter() { - let Some(net) = polygon.net else { + let Some(net) = polygon.spec.net else { continue; }; let _ = triangulations - .entry((net, polygon.layer)) + .entry((net, polygon.spec.layer)) .or_insert_with(DelaunayTriangulation::new) .insert(DelaunayVertex { - layer: polygon.layer, - center: polygon.center(), + layer: polygon.spec.layer, + center: polygon.centroid, position: spade::Point2::new( - polygon.center().x as f64, - polygon.center().y as f64, + polygon.centroid.x as f64, + polygon.centroid.y as f64, ), primitive_id: PrimitiveId::Polygon(PolygonId::new(i)), }); diff --git a/topola/src/specctra.rs b/topola/src/specctra.rs index 6cd1407..cdf0c0d 100644 --- a/topola/src/specctra.rs +++ b/topola/src/specctra.rs @@ -12,7 +12,7 @@ use specctra::{ use crate::{ board::{Board, LayerDesc, LayerSide, LayerType}, - layout::primitives::{JointSpec, Polygon, Segment, SegmentSpec}, + layout::primitives::{JointSpec, Polygon, PolygonSpec, Segment, SegmentSpec}, layout::{ LayerId, compounds::{ComponentId, NetId, PinId, PinSpec}, @@ -383,17 +383,22 @@ impl Board { flip: bool, coordinate_scale: f64, ) { - board.insert_polygon(Polygon { - vertices: vec![ - Self::pos(place, pin_pos, x1, y1, flip, coordinate_scale), - Self::pos(place, pin_pos, x2, y1, flip, coordinate_scale), - Self::pos(place, pin_pos, x2, y2, flip, coordinate_scale), - Self::pos(place, pin_pos, x1, y2, flip, coordinate_scale), - ], - layer, - net, - component, - pin, + board.insert_polygon({ + let spec = PolygonSpec { + vertices: vec![ + Self::pos(place, pin_pos, x1, y1, flip, coordinate_scale), + Self::pos(place, pin_pos, x2, y1, flip, coordinate_scale), + Self::pos(place, pin_pos, x2, y2, flip, coordinate_scale), + Self::pos(place, pin_pos, x1, y2, flip, coordinate_scale), + ], + layer, + net, + component, + pin, + }; + let centroid = Vector2::::polygon_centroid(&spec.vertices); + + Polygon { spec, centroid } }); } @@ -477,12 +482,17 @@ impl Board { .iter() .map(|coord| Self::pos(place, pin_pos, coord.x, coord.y, flip, coordinate_scale)) .collect(); - board.insert_polygon(Polygon { - vertices, - layer, - net, - component, - pin, + board.insert_polygon({ + let spec = PolygonSpec { + vertices, + layer, + net, + component, + pin, + }; + let centroid = Vector2::::polygon_centroid(&spec.vertices); + + Polygon { spec, centroid } }); }