mirror of https://codeberg.org/topola/topola.git
drawing: implement getting zones and teir members
This commit is contained in:
parent
8f9abae921
commit
1a624b83b1
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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| {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue