mirror of https://codeberg.org/topola/topola.git
geometry: create bboxes for groupings
This commit is contained in:
parent
3a812d5621
commit
31189a9f5e
|
|
@ -27,7 +27,7 @@ use crate::drawing::{
|
||||||
SeqLooseSegIndex, SeqLooseSegWeight,
|
SeqLooseSegIndex, SeqLooseSegWeight,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::geometry::Compound;
|
use crate::geometry::Node;
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
shape::{Shape, ShapeTrait},
|
shape::{Shape, ShapeTrait},
|
||||||
with_rtree::GeometryWithRtree,
|
with_rtree::GeometryWithRtree,
|
||||||
|
|
@ -637,7 +637,7 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
.rtree()
|
.rtree()
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|wrapper| {
|
.filter_map(|wrapper| {
|
||||||
if let Compound::Primitive(primitive_node) = wrapper.data {
|
if let Node::Primitive(primitive_node) = wrapper.data {
|
||||||
Some(primitive_node)
|
Some(primitive_node)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -653,7 +653,7 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
[f64::INFINITY, f64::INFINITY, layer as f64],
|
[f64::INFINITY, f64::INFINITY, layer as f64],
|
||||||
))
|
))
|
||||||
.filter_map(|wrapper| {
|
.filter_map(|wrapper| {
|
||||||
if let Compound::Primitive(primitive_node) = wrapper.data {
|
if let Node::Primitive(primitive_node) = wrapper.data {
|
||||||
Some(primitive_node)
|
Some(primitive_node)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -748,7 +748,7 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
.rtree()
|
.rtree()
|
||||||
.locate_in_envelope_intersecting(&limiting_shape.full_height_envelope_3d(0.0, 2))
|
.locate_in_envelope_intersecting(&limiting_shape.full_height_envelope_3d(0.0, 2))
|
||||||
.filter_map(|wrapper| {
|
.filter_map(|wrapper| {
|
||||||
if let Compound::Primitive(primitive_node) = wrapper.data {
|
if let Node::Primitive(primitive_node) = wrapper.data {
|
||||||
Some(primitive_node)
|
Some(primitive_node)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -783,7 +783,7 @@ impl<R: RulesTrait> Drawing<R> {
|
||||||
.rtree()
|
.rtree()
|
||||||
.locate_in_envelope_intersecting(&shape.full_height_envelope_3d(0.0, 2))
|
.locate_in_envelope_intersecting(&shape.full_height_envelope_3d(0.0, 2))
|
||||||
.filter_map(|wrapper| {
|
.filter_map(|wrapper| {
|
||||||
if let Compound::Primitive(primitive_node) = wrapper.data {
|
if let Node::Primitive(primitive_node) = wrapper.data {
|
||||||
Some(primitive_node)
|
Some(primitive_node)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
Drawing,
|
Drawing,
|
||||||
},
|
},
|
||||||
geometry::Compound,
|
geometry::Node,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
|
|
@ -184,7 +184,7 @@ impl<'a, W, R: RulesTrait> GenericPrimitive<'a, W, R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tagged_weight(&self) -> PrimitiveWeight {
|
fn tagged_weight(&self) -> PrimitiveWeight {
|
||||||
if let Compound::Primitive(weight) = *self
|
if let Node::Primitive(weight) = *self
|
||||||
.drawing
|
.drawing
|
||||||
.geometry()
|
.geometry()
|
||||||
.graph()
|
.graph()
|
||||||
|
|
@ -258,15 +258,9 @@ impl<'a, R: RulesTrait> FixedDot<'a, R> {
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(ni.node_index())
|
.node_weight(ni.node_index())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if matches!(
|
if matches!(weight, Node::Primitive(PrimitiveWeight::LoneLooseSeg(..))) {
|
||||||
weight,
|
|
||||||
Compound::Primitive(PrimitiveWeight::LoneLooseSeg(..))
|
|
||||||
) {
|
|
||||||
Some(LoneLooseSegIndex::new(ni.node_index()).into())
|
Some(LoneLooseSegIndex::new(ni.node_index()).into())
|
||||||
} else if matches!(
|
} else if matches!(weight, Node::Primitive(PrimitiveWeight::SeqLooseSeg(..))) {
|
||||||
weight,
|
|
||||||
Compound::Primitive(PrimitiveWeight::SeqLooseSeg(..))
|
|
||||||
) {
|
|
||||||
Some(SeqLooseSegIndex::new(ni.node_index()).into())
|
Some(SeqLooseSegIndex::new(ni.node_index()).into())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,9 @@ pub enum GeometryLabel {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum Compound<PW, XW> {
|
pub enum Node<PW, GW> {
|
||||||
Primitive(PW),
|
Primitive(PW),
|
||||||
Grouping(XW),
|
Grouping(GW),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DotWeightTrait<GW>: GetPos + SetPos + GetWidth + Into<GW> + Copy {}
|
pub trait DotWeightTrait<GW>: GetPos + SetPos + GetWidth + Into<GW> + Copy {}
|
||||||
|
|
@ -77,7 +77,7 @@ pub struct Geometry<
|
||||||
SI: GetNodeIndex + Into<PI> + Copy,
|
SI: GetNodeIndex + Into<PI> + Copy,
|
||||||
BI: GetNodeIndex + Into<PI> + Copy,
|
BI: GetNodeIndex + Into<PI> + Copy,
|
||||||
> {
|
> {
|
||||||
graph: StableDiGraph<Compound<PW, GW>, GeometryLabel, usize>,
|
graph: StableDiGraph<Node<PW, GW>, GeometryLabel, usize>,
|
||||||
weight_marker: PhantomData<PW>,
|
weight_marker: PhantomData<PW>,
|
||||||
dot_weight_marker: PhantomData<DW>,
|
dot_weight_marker: PhantomData<DW>,
|
||||||
seg_weight_marker: PhantomData<SW>,
|
seg_weight_marker: PhantomData<SW>,
|
||||||
|
|
@ -117,7 +117,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_dot<W: DotWeightTrait<PW>>(&mut self, weight: W) -> GenericIndex<W> {
|
pub fn add_dot<W: DotWeightTrait<PW>>(&mut self, weight: W) -> GenericIndex<W> {
|
||||||
GenericIndex::<W>::new(self.graph.add_node(Compound::Primitive(weight.into())))
|
GenericIndex::<W>::new(self.graph.add_node(Node::Primitive(weight.into())))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_seg<W: SegWeightTrait<PW>>(
|
pub fn add_seg<W: SegWeightTrait<PW>>(
|
||||||
|
|
@ -126,7 +126,7 @@ impl<
|
||||||
to: DI,
|
to: DI,
|
||||||
weight: W,
|
weight: W,
|
||||||
) -> GenericIndex<W> {
|
) -> GenericIndex<W> {
|
||||||
let seg = GenericIndex::<W>::new(self.graph.add_node(Compound::Primitive(weight.into())));
|
let seg = GenericIndex::<W>::new(self.graph.add_node(Node::Primitive(weight.into())));
|
||||||
|
|
||||||
self.graph
|
self.graph
|
||||||
.update_edge(from.node_index(), seg.node_index(), GeometryLabel::Joined);
|
.update_edge(from.node_index(), seg.node_index(), GeometryLabel::Joined);
|
||||||
|
|
@ -143,7 +143,7 @@ impl<
|
||||||
core: DI,
|
core: DI,
|
||||||
weight: W,
|
weight: W,
|
||||||
) -> GenericIndex<W> {
|
) -> GenericIndex<W> {
|
||||||
let bend = GenericIndex::<W>::new(self.graph.add_node(Compound::Primitive(weight.into())));
|
let bend = GenericIndex::<W>::new(self.graph.add_node(Node::Primitive(weight.into())));
|
||||||
|
|
||||||
self.graph
|
self.graph
|
||||||
.update_edge(from.node_index(), bend.node_index(), GeometryLabel::Joined);
|
.update_edge(from.node_index(), bend.node_index(), GeometryLabel::Joined);
|
||||||
|
|
@ -156,7 +156,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_grouping(&mut self, weight: GW) -> GenericIndex<GW> {
|
pub fn add_grouping(&mut self, weight: GW) -> GenericIndex<GW> {
|
||||||
GenericIndex::<GW>::new(self.graph.add_node(Compound::Grouping(weight)))
|
GenericIndex::<GW>::new(self.graph.add_node(Node::Grouping(weight)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_to_grouping<W>(
|
pub fn assign_to_grouping<W>(
|
||||||
|
|
@ -182,14 +182,13 @@ impl<
|
||||||
pub fn move_dot(&mut self, dot: DI, to: Point) {
|
pub fn move_dot(&mut self, dot: DI, to: Point) {
|
||||||
let mut weight = self.dot_weight(dot);
|
let mut weight = self.dot_weight(dot);
|
||||||
weight.set_pos(to);
|
weight.set_pos(to);
|
||||||
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Compound::Primitive(weight.into());
|
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Node::Primitive(weight.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shift_bend(&mut self, bend: BI, offset: f64) {
|
pub fn shift_bend(&mut self, bend: BI, offset: f64) {
|
||||||
let mut weight = self.bend_weight(bend);
|
let mut weight = self.bend_weight(bend);
|
||||||
weight.set_offset(offset);
|
weight.set_offset(offset);
|
||||||
*self.graph.node_weight_mut(bend.node_index()).unwrap() =
|
*self.graph.node_weight_mut(bend.node_index()).unwrap() = Node::Primitive(weight.into());
|
||||||
Compound::Primitive(weight.into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn flip_bend(&mut self, bend: BI) {
|
pub fn flip_bend(&mut self, bend: BI) {
|
||||||
|
|
@ -285,7 +284,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primitive_weight(&self, index: NodeIndex<usize>) -> PW {
|
fn primitive_weight(&self, index: NodeIndex<usize>) -> PW {
|
||||||
if let Compound::Primitive(weight) = *self.graph.node_weight(index).unwrap() {
|
if let Node::Primitive(weight) = *self.graph.node_weight(index).unwrap() {
|
||||||
weight
|
weight
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
|
@ -310,6 +309,14 @@ impl<
|
||||||
.unwrap_or_else(|_| unreachable!())
|
.unwrap_or_else(|_| unreachable!())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn grouping_weight(&self, grouping: GenericIndex<GW>) -> GW {
|
||||||
|
if let Node::Grouping(weight) = *self.graph.node_weight(grouping.node_index()).unwrap() {
|
||||||
|
weight
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn core_weight(&self, bend: BI) -> DW {
|
fn core_weight(&self, bend: BI) -> DW {
|
||||||
self.graph
|
self.graph
|
||||||
.neighbors(bend.node_index())
|
.neighbors(bend.node_index())
|
||||||
|
|
@ -393,7 +400,7 @@ impl<
|
||||||
|
|
||||||
pub fn outer(&self, bend: BI) -> Option<BI> {
|
pub fn outer(&self, bend: BI) -> Option<BI> {
|
||||||
self.graph
|
self.graph
|
||||||
.neighbors_directed(bend.node_index(), Outgoing)
|
.neighbors(bend.node_index())
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
matches!(
|
matches!(
|
||||||
self.graph
|
self.graph
|
||||||
|
|
@ -459,7 +466,26 @@ 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 graph(&self) -> &StableDiGraph<Compound<PW, GW>, GeometryLabel, usize> {
|
pub fn members(&self, grouping: GenericIndex<GW>) -> impl Iterator<Item = PI> + '_ {
|
||||||
|
self.graph
|
||||||
|
.neighbors(grouping.node_index())
|
||||||
|
.filter(move |ni| {
|
||||||
|
matches!(
|
||||||
|
self.graph
|
||||||
|
.edge_weight(self.graph.find_edge(grouping.node_index(), *ni).unwrap())
|
||||||
|
.unwrap(),
|
||||||
|
GeometryLabel::Grouping
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.map(|ni| {
|
||||||
|
self.primitive_weight(ni)
|
||||||
|
.retag(ni)
|
||||||
|
.try_into()
|
||||||
|
.unwrap_or_else(|_| unreachable!())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn graph(&self) -> &StableDiGraph<Node<PW, GW>, GeometryLabel, usize> {
|
||||||
&self.graph
|
&self.graph
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,21 +3,20 @@ use std::marker::PhantomData;
|
||||||
use contracts::debug_invariant;
|
use contracts::debug_invariant;
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
use petgraph::stable_graph::StableDiGraph;
|
use petgraph::stable_graph::StableDiGraph;
|
||||||
use rstar::{primitives::GeomWithData, RTree, RTreeObject, AABB};
|
use rstar::{primitives::GeomWithData, Envelope, RTree, RTreeObject, AABB};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::graph::{GetLayer, Retag},
|
drawing::graph::{GetLayer, Retag},
|
||||||
geometry::{
|
geometry::{
|
||||||
shape::{Shape, ShapeTrait},
|
shape::{Shape, ShapeTrait},
|
||||||
BendWeightTrait, Compound, DotWeightTrait, Geometry, GeometryLabel, GetWidth,
|
BendWeightTrait, DotWeightTrait, Geometry, GeometryLabel, GetWidth, Node, SegWeightTrait,
|
||||||
SegWeightTrait,
|
|
||||||
},
|
},
|
||||||
graph::{GenericIndex, GetNodeIndex},
|
graph::{GenericIndex, GetNodeIndex},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct Bbox {
|
pub struct Bbox {
|
||||||
aabb: AABB<[f64; 3]>,
|
pub aabb: AABB<[f64; 3]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bbox {
|
impl Bbox {
|
||||||
|
|
@ -48,7 +47,7 @@ pub struct GeometryWithRtree<
|
||||||
BI: GetNodeIndex + Into<PI> + Copy,
|
BI: GetNodeIndex + Into<PI> + Copy,
|
||||||
> {
|
> {
|
||||||
geometry: Geometry<PW, DW, SW, BW, GW, PI, DI, SI, BI>,
|
geometry: Geometry<PW, DW, SW, BW, GW, PI, DI, SI, BI>,
|
||||||
rtree: RTree<BboxedIndex<Compound<PI, GenericIndex<GW>>>>,
|
rtree: RTree<BboxedIndex<Node<PI, GenericIndex<GW>>>>,
|
||||||
layer_count: u64,
|
layer_count: u64,
|
||||||
weight_marker: PhantomData<PW>,
|
weight_marker: PhantomData<PW>,
|
||||||
dot_weight_marker: PhantomData<DW>,
|
dot_weight_marker: PhantomData<DW>,
|
||||||
|
|
@ -101,7 +100,7 @@ impl<
|
||||||
.dot_shape(dot.into().try_into().unwrap_or_else(|_| unreachable!()))
|
.dot_shape(dot.into().try_into().unwrap_or_else(|_| unreachable!()))
|
||||||
.envelope_3d(0.0, weight.layer()),
|
.envelope_3d(0.0, weight.layer()),
|
||||||
),
|
),
|
||||||
Compound::Primitive(dot.into()),
|
Node::Primitive(dot.into()),
|
||||||
));
|
));
|
||||||
dot
|
dot
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +121,7 @@ impl<
|
||||||
.seg_shape(seg.into().try_into().unwrap_or_else(|_| unreachable!()))
|
.seg_shape(seg.into().try_into().unwrap_or_else(|_| unreachable!()))
|
||||||
.envelope_3d(0.0, weight.layer()),
|
.envelope_3d(0.0, weight.layer()),
|
||||||
),
|
),
|
||||||
Compound::Primitive(seg.into()),
|
Node::Primitive(seg.into()),
|
||||||
));
|
));
|
||||||
seg
|
seg
|
||||||
}
|
}
|
||||||
|
|
@ -144,17 +143,14 @@ impl<
|
||||||
.bend_shape(bend.into().try_into().unwrap_or_else(|_| unreachable!()))
|
.bend_shape(bend.into().try_into().unwrap_or_else(|_| unreachable!()))
|
||||||
.envelope_3d(0.0, weight.layer()),
|
.envelope_3d(0.0, weight.layer()),
|
||||||
),
|
),
|
||||||
Compound::Primitive(bend.into()),
|
Node::Primitive(bend.into()),
|
||||||
));
|
));
|
||||||
bend
|
bend
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_grouping(&mut self, weight: GW) -> GenericIndex<GW> {
|
pub fn add_grouping(&mut self, weight: GW) -> GenericIndex<GW> {
|
||||||
let grouping = self.geometry.add_grouping(weight);
|
let grouping = self.geometry.add_grouping(weight);
|
||||||
self.rtree.insert(BboxedIndex::new(
|
self.rtree.insert(self.make_grouping_bbox(grouping));
|
||||||
Bbox::new(AABB::<[f64; 3]>::from_point([0.0, 0.0, -1.0].into())),
|
|
||||||
Compound::Grouping(grouping),
|
|
||||||
));
|
|
||||||
grouping
|
grouping
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +159,9 @@ impl<
|
||||||
primitive: GenericIndex<W>,
|
primitive: GenericIndex<W>,
|
||||||
grouping: GenericIndex<GW>,
|
grouping: GenericIndex<GW>,
|
||||||
) {
|
) {
|
||||||
self.geometry.assign_to_grouping(primitive, grouping)
|
self.rtree.remove(&self.make_grouping_bbox(grouping));
|
||||||
|
self.geometry.assign_to_grouping(primitive, grouping);
|
||||||
|
self.rtree.insert(self.make_grouping_bbox(grouping));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_dot(&mut self, dot: DI) -> Result<(), ()> {
|
pub fn remove_dot(&mut self, dot: DI) -> Result<(), ()> {
|
||||||
|
|
@ -275,67 +273,82 @@ impl<
|
||||||
BI: GetNodeIndex + Into<PI> + Copy,
|
BI: GetNodeIndex + Into<PI> + Copy,
|
||||||
> GeometryWithRtree<PW, DW, SW, BW, GW, PI, DI, SI, BI>
|
> GeometryWithRtree<PW, DW, SW, BW, GW, PI, DI, SI, BI>
|
||||||
{
|
{
|
||||||
fn make_dot_bbox(&self, dot: DI) -> BboxedIndex<Compound<PI, GenericIndex<GW>>> {
|
fn make_bbox(&self, primitive: PI) -> BboxedIndex<Node<PI, GenericIndex<GW>>> {
|
||||||
|
if let Ok(dot) = <PI as TryInto<DI>>::try_into(primitive) {
|
||||||
|
self.make_dot_bbox(dot)
|
||||||
|
} else if let Ok(seg) = <PI as TryInto<SI>>::try_into(primitive) {
|
||||||
|
self.make_seg_bbox(seg)
|
||||||
|
} else if let Ok(bend) = <PI as TryInto<BI>>::try_into(primitive) {
|
||||||
|
self.make_bend_bbox(bend)
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_dot_bbox(&self, dot: DI) -> BboxedIndex<Node<PI, GenericIndex<GW>>> {
|
||||||
BboxedIndex::new(
|
BboxedIndex::new(
|
||||||
Bbox::new(
|
Bbox::new(
|
||||||
self.geometry
|
self.geometry
|
||||||
.dot_shape(dot)
|
.dot_shape(dot)
|
||||||
.envelope_3d(0.0, self.layer(dot.into())),
|
.envelope_3d(0.0, self.layer(dot.into())),
|
||||||
),
|
),
|
||||||
Compound::Primitive(dot.into()),
|
Node::Primitive(dot.into()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_seg_bbox(&self, seg: SI) -> BboxedIndex<Compound<PI, GenericIndex<GW>>> {
|
fn make_seg_bbox(&self, seg: SI) -> BboxedIndex<Node<PI, GenericIndex<GW>>> {
|
||||||
BboxedIndex::new(
|
BboxedIndex::new(
|
||||||
Bbox::new(
|
Bbox::new(
|
||||||
self.geometry
|
self.geometry
|
||||||
.seg_shape(seg)
|
.seg_shape(seg)
|
||||||
.envelope_3d(0.0, self.layer(seg.into())),
|
.envelope_3d(0.0, self.layer(seg.into())),
|
||||||
),
|
),
|
||||||
Compound::Primitive(seg.into()),
|
Node::Primitive(seg.into()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_bend_bbox(&self, bend: BI) -> BboxedIndex<Compound<PI, GenericIndex<GW>>> {
|
fn make_bend_bbox(&self, bend: BI) -> BboxedIndex<Node<PI, GenericIndex<GW>>> {
|
||||||
BboxedIndex::new(
|
BboxedIndex::new(
|
||||||
Bbox::new(
|
Bbox::new(
|
||||||
self.geometry
|
self.geometry
|
||||||
.bend_shape(bend)
|
.bend_shape(bend)
|
||||||
.envelope_3d(0.0, self.layer(bend.into())),
|
.envelope_3d(0.0, self.layer(bend.into())),
|
||||||
),
|
),
|
||||||
Compound::Primitive(bend.into()),
|
Node::Primitive(bend.into()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_grouping_bbox(
|
fn make_grouping_bbox(
|
||||||
&self,
|
&self,
|
||||||
grouping: GenericIndex<GW>,
|
grouping: GenericIndex<GW>,
|
||||||
) -> BboxedIndex<Compound<PI, GenericIndex<GW>>> {
|
) -> BboxedIndex<Node<PI, GenericIndex<GW>>> {
|
||||||
BboxedIndex::new(
|
let mut aabb = AABB::<[f64; 3]>::new_empty();
|
||||||
Bbox::new(AABB::<[f64; 3]>::from_point([0.0, 0.0, -1.0].into())),
|
|
||||||
Compound::Grouping(grouping),
|
for member in self.geometry.members(grouping) {
|
||||||
)
|
aabb.merge(&self.make_bbox(member).geom().aabb);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shape(&self, index: PI) -> Shape {
|
BboxedIndex::new(Bbox::new(aabb), Node::Grouping(grouping))
|
||||||
if let Ok(dot) = <PI as TryInto<DI>>::try_into(index) {
|
}
|
||||||
|
|
||||||
|
fn shape(&self, primitive: PI) -> Shape {
|
||||||
|
if let Ok(dot) = <PI as TryInto<DI>>::try_into(primitive) {
|
||||||
self.geometry.dot_shape(dot)
|
self.geometry.dot_shape(dot)
|
||||||
} else if let Ok(seg) = <PI as TryInto<SI>>::try_into(index) {
|
} else if let Ok(seg) = <PI as TryInto<SI>>::try_into(primitive) {
|
||||||
self.geometry.seg_shape(seg)
|
self.geometry.seg_shape(seg)
|
||||||
} else if let Ok(bend) = <PI as TryInto<BI>>::try_into(index) {
|
} else if let Ok(bend) = <PI as TryInto<BI>>::try_into(primitive) {
|
||||||
self.geometry.bend_shape(bend)
|
self.geometry.bend_shape(bend)
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layer(&self, index: PI) -> u64 {
|
fn layer(&self, primitive: PI) -> u64 {
|
||||||
if let Ok(dot) = <PI as TryInto<DI>>::try_into(index) {
|
if let Ok(dot) = <PI as TryInto<DI>>::try_into(primitive) {
|
||||||
self.geometry.dot_weight(dot).layer()
|
self.geometry.dot_weight(dot).layer()
|
||||||
} else if let Ok(seg) = <PI as TryInto<SI>>::try_into(index) {
|
} else if let Ok(seg) = <PI as TryInto<SI>>::try_into(primitive) {
|
||||||
self.geometry.seg_weight(seg).layer()
|
self.geometry.seg_weight(seg).layer()
|
||||||
} else if let Ok(bend) = <PI as TryInto<BI>>::try_into(index) {
|
} else if let Ok(bend) = <PI as TryInto<BI>>::try_into(primitive) {
|
||||||
self.geometry.bend_weight(bend).layer()
|
self.geometry.bend_weight(bend).layer()
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
|
|
@ -346,25 +359,25 @@ impl<
|
||||||
&self.geometry
|
&self.geometry
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rtree(&self) -> &RTree<BboxedIndex<Compound<PI, GenericIndex<GW>>>> {
|
pub fn rtree(&self) -> &RTree<BboxedIndex<Node<PI, GenericIndex<GW>>>> {
|
||||||
&self.rtree
|
&self.rtree
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn graph(&self) -> &StableDiGraph<Compound<PW, GW>, GeometryLabel, usize> {
|
pub fn graph(&self) -> &StableDiGraph<Node<PW, GW>, GeometryLabel, usize> {
|
||||||
self.geometry.graph()
|
self.geometry.graph()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_envelopes(&self) -> bool {
|
fn test_envelopes(&self) -> bool {
|
||||||
!self.rtree.iter().any(|wrapper| {
|
!self.rtree.iter().any(|wrapper| {
|
||||||
// TODO: Test envelopes of groupings too.
|
// TODO: Test envelopes of groupings too.
|
||||||
let Compound::Primitive(primitive_node) = wrapper.data else {
|
let Node::Primitive(primitive_node) = wrapper.data else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let shape = self.shape(primitive_node);
|
let shape = self.shape(primitive_node);
|
||||||
let layer = self.layer(primitive_node);
|
let layer = self.layer(primitive_node);
|
||||||
let wrapper = BboxedIndex::new(
|
let wrapper = BboxedIndex::new(
|
||||||
Bbox::new(shape.envelope_3d(0.0, layer)),
|
Bbox::new(shape.envelope_3d(0.0, layer)),
|
||||||
Compound::Primitive(primitive_node),
|
Node::Primitive(primitive_node),
|
||||||
);
|
);
|
||||||
!self
|
!self
|
||||||
.rtree
|
.rtree
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue