drawing: implement getting zones and teir members

This commit is contained in:
Mikolaj Wielgus 2024-04-04 13:54:47 +00:00
parent 8f9abae921
commit 1a624b83b1
4 changed files with 55 additions and 6 deletions

View File

@ -25,7 +25,7 @@ use crate::drawing::{
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex, FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
SeqLooseSegIndex, SeqLooseSegWeight, SeqLooseSegIndex, SeqLooseSegWeight,
}, },
zone::{ZoneIndex, ZoneWeight}, zone::{PourZoneIndex, SolidZoneIndex, ZoneIndex, ZoneWeight},
}; };
use crate::geometry::Node; use crate::geometry::Node;
use crate::geometry::{ use crate::geometry::{
@ -661,6 +661,54 @@ impl<R: RulesTrait> Drawing<R> {
}) })
} }
pub fn zones(&self) -> impl Iterator<Item = ZoneIndex> + '_ {
self.geometry_with_rtree
.rtree()
.iter()
.filter_map(|wrapper| {
if let Node::Grouping(zone) = wrapper.data {
Some(match self.geometry().grouping_weight(zone) {
ZoneWeight::Solid(..) => {
ZoneIndex::Solid(SolidZoneIndex::new(zone.node_index()))
}
ZoneWeight::Pour(..) => {
ZoneIndex::Pour(PourZoneIndex::new(zone.node_index()))
}
})
} else {
None
}
})
}
pub fn layer_zones(&self, layer: u64) -> impl Iterator<Item = ZoneIndex> + '_ {
self.geometry_with_rtree
.rtree()
.locate_in_envelope_intersecting(&AABB::from_corners(
[-f64::INFINITY, -f64::INFINITY, layer as f64],
[f64::INFINITY, f64::INFINITY, layer as f64],
))
.filter_map(|wrapper| {
if let Node::Grouping(zone) = wrapper.data {
Some(match self.geometry().grouping_weight(zone) {
ZoneWeight::Solid(..) => {
ZoneIndex::Solid(SolidZoneIndex::new(zone.node_index()))
}
ZoneWeight::Pour(..) => {
ZoneIndex::Pour(PourZoneIndex::new(zone.node_index()))
}
})
} else {
None
}
})
}
pub fn zone_members(&self, zone: ZoneIndex) -> impl Iterator<Item = PrimitiveIndex> + '_ {
self.geometry()
.grouping_members(GenericIndex::new(zone.node_index()))
}
pub fn node_count(&self) -> usize { pub fn node_count(&self) -> usize {
self.geometry_with_rtree.graph().node_count() self.geometry_with_rtree.graph().node_count()
} }

View File

@ -15,6 +15,7 @@ use crate::{
graph::{GenericIndex, GetNodeIndex}, graph::{GenericIndex, GetNodeIndex},
}; };
#[enum_dispatch]
pub trait MakePolygon { pub trait MakePolygon {
fn polygon<R: RulesTrait>(&self, drawing: &Drawing<R>) -> Polygon; fn polygon<R: RulesTrait>(&self, drawing: &Drawing<R>) -> Polygon;
} }
@ -59,7 +60,7 @@ impl MakePolygon for SolidZoneIndex {
LineString::from( LineString::from(
drawing drawing
.geometry() .geometry()
.members(GenericIndex::<ZoneWeight>::new(self.node_index())) .grouping_members(GenericIndex::<ZoneWeight>::new(self.node_index()))
.filter_map(|primitive_node| { .filter_map(|primitive_node| {
if let Ok(dot) = DotIndex::try_from(primitive_node) { if let Ok(dot) = DotIndex::try_from(primitive_node) {
Some(drawing.geometry().dot_weight(dot).pos()) Some(drawing.geometry().dot_weight(dot).pos())
@ -100,7 +101,7 @@ impl MakePolygon for PourZoneIndex {
LineString::from( LineString::from(
drawing drawing
.geometry() .geometry()
.members(GenericIndex::<ZoneWeight>::new(self.node_index())) .grouping_members(GenericIndex::<ZoneWeight>::new(self.node_index()))
.filter_map(|primitive_node| { .filter_map(|primitive_node| {
if let Ok(dot) = DotIndex::try_from(primitive_node) { if let Ok(dot) = DotIndex::try_from(primitive_node) {
Some(drawing.geometry().dot_weight(dot).pos()) Some(drawing.geometry().dot_weight(dot).pos())

View File

@ -309,7 +309,7 @@ impl<
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
} }
fn grouping_weight(&self, grouping: GenericIndex<GW>) -> GW { pub fn grouping_weight(&self, grouping: GenericIndex<GW>) -> GW {
if let Node::Grouping(weight) = *self.graph.node_weight(grouping.node_index()).unwrap() { if let Node::Grouping(weight) = *self.graph.node_weight(grouping.node_index()).unwrap() {
weight weight
} else { } else {
@ -466,7 +466,7 @@ impl<
self.joineds(dot.into()).filter_map(|ni| ni.try_into().ok()) self.joineds(dot.into()).filter_map(|ni| ni.try_into().ok())
} }
pub fn members(&self, grouping: GenericIndex<GW>) -> impl Iterator<Item = PI> + '_ { pub fn grouping_members(&self, grouping: GenericIndex<GW>) -> impl Iterator<Item = PI> + '_ {
self.graph self.graph
.neighbors(grouping.node_index()) .neighbors(grouping.node_index())
.filter(move |ni| { .filter(move |ni| {

View File

@ -324,7 +324,7 @@ impl<
) -> BboxedIndex<Node<PI, GenericIndex<GW>>> { ) -> BboxedIndex<Node<PI, GenericIndex<GW>>> {
let mut aabb = AABB::<[f64; 3]>::new_empty(); let mut aabb = AABB::<[f64; 3]>::new_empty();
for member in self.geometry.members(grouping) { for member in self.geometry.grouping_members(grouping) {
aabb.merge(&self.make_bbox(member).geom().aabb); aabb.merge(&self.make_bbox(member).geom().aabb);
} }