mirror of https://codeberg.org/topola/topola.git
feat(router/navmesh): Add constraint edges for fixed segs
This commit is contained in:
parent
742c5e770f
commit
274ad166c1
|
|
@ -24,7 +24,7 @@ use crate::{
|
||||||
dot::FixedDotIndex,
|
dot::FixedDotIndex,
|
||||||
gear::{GearIndex, GetNextGear},
|
gear::{GearIndex, GetNextGear},
|
||||||
graph::{GetMaybeNet, MakePrimitive, PrimitiveIndex},
|
graph::{GetMaybeNet, MakePrimitive, PrimitiveIndex},
|
||||||
primitive::{MakePrimitiveShape, Primitive},
|
primitive::{GetJoints, MakePrimitiveShape, Primitive},
|
||||||
rules::AccessRules,
|
rules::AccessRules,
|
||||||
Drawing,
|
Drawing,
|
||||||
},
|
},
|
||||||
|
|
@ -192,6 +192,20 @@ impl Navmesh {
|
||||||
pos: primitive.shape().center(),
|
pos: primitive.shape().center(),
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
PrimitiveIndex::FixedSeg(seg) => {
|
||||||
|
let (from_dot, to_dot) = layout.drawing().primitive(seg).joints();
|
||||||
|
|
||||||
|
triangulation.add_constraint_edge(
|
||||||
|
TrianvertexWeight {
|
||||||
|
node: from_dot.into(),
|
||||||
|
pos: from_dot.primitive(layout.drawing()).shape().center(),
|
||||||
|
},
|
||||||
|
TrianvertexWeight {
|
||||||
|
node: to_dot.into(),
|
||||||
|
pos: to_dot.primitive(layout.drawing()).shape().center(),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
}
|
||||||
PrimitiveIndex::FixedBend(bend) => {
|
PrimitiveIndex::FixedBend(bend) => {
|
||||||
triangulation.add_vertex(TrianvertexWeight {
|
triangulation.add_vertex(TrianvertexWeight {
|
||||||
node: bend.into(),
|
node: bend.into(),
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,9 @@ use std::{cmp::Ordering, marker::PhantomData};
|
||||||
use geo::algorithm::line_measures::{Distance, Euclidean};
|
use geo::algorithm::line_measures::{Distance, Euclidean};
|
||||||
use geo::{point, Point};
|
use geo::{point, Point};
|
||||||
use petgraph::visit;
|
use petgraph::visit;
|
||||||
use spade::{handles::FixedVertexHandle, DelaunayTriangulation, HasPosition, InsertionError};
|
use spade::{
|
||||||
|
handles::FixedVertexHandle, ConstrainedDelaunayTriangulation, HasPosition, InsertionError,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::graph::GetPetgraphIndex;
|
use crate::graph::GetPetgraphIndex;
|
||||||
|
|
||||||
|
|
@ -15,9 +17,12 @@ pub trait GetTrianvertexNodeIndex<I> {
|
||||||
fn node_index(&self) -> I;
|
fn node_index(&self) -> I;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
// No `Debug` derive because `spade::ConstrainedDelaunayTriangulation` does
|
||||||
|
// not implement `Debug`, though it could (and `spade::DelaunayTriangulation`
|
||||||
|
// actually does).
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Triangulation<I, VW: GetTrianvertexNodeIndex<I> + HasPosition, EW: Default> {
|
pub struct Triangulation<I, VW: GetTrianvertexNodeIndex<I> + HasPosition, EW: Default> {
|
||||||
triangulation: DelaunayTriangulation<VW, EW>,
|
cdt: ConstrainedDelaunayTriangulation<VW, EW>,
|
||||||
trianvertex_to_handle: Box<[Option<FixedVertexHandle>]>,
|
trianvertex_to_handle: Box<[Option<FixedVertexHandle>]>,
|
||||||
index_marker: PhantomData<I>,
|
index_marker: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
@ -27,7 +32,7 @@ impl<I: GetPetgraphIndex, VW: GetTrianvertexNodeIndex<I> + HasPosition, EW: Defa
|
||||||
{
|
{
|
||||||
pub fn new(node_bound: usize) -> Self {
|
pub fn new(node_bound: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
triangulation: <DelaunayTriangulation<VW, EW> as spade::Triangulation>::new(),
|
cdt: <ConstrainedDelaunayTriangulation<VW, EW> as spade::Triangulation>::new(),
|
||||||
trianvertex_to_handle: vec![None; node_bound].into_boxed_slice(),
|
trianvertex_to_handle: vec![None; node_bound].into_boxed_slice(),
|
||||||
index_marker: PhantomData,
|
index_marker: PhantomData,
|
||||||
}
|
}
|
||||||
|
|
@ -35,27 +40,29 @@ impl<I: GetPetgraphIndex, VW: GetTrianvertexNodeIndex<I> + HasPosition, EW: Defa
|
||||||
|
|
||||||
pub fn add_vertex(&mut self, weight: VW) -> Result<(), InsertionError> {
|
pub fn add_vertex(&mut self, weight: VW) -> Result<(), InsertionError> {
|
||||||
let index = weight.node_index().petgraph_index().index();
|
let index = weight.node_index().petgraph_index().index();
|
||||||
self.trianvertex_to_handle[index] = Some(spade::Triangulation::insert(
|
self.trianvertex_to_handle[index] =
|
||||||
&mut self.triangulation,
|
Some(spade::Triangulation::insert(&mut self.cdt, weight)?);
|
||||||
weight,
|
|
||||||
)?);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_constraint_edge(&mut self, from: VW, to: VW) -> Result<bool, InsertionError> {
|
||||||
|
self.cdt.add_constraint_edge(from, to)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn weight(&self, vertex: I) -> &VW {
|
pub fn weight(&self, vertex: I) -> &VW {
|
||||||
spade::Triangulation::s(&self.triangulation)
|
spade::Triangulation::s(&self.cdt)
|
||||||
.vertex_data(self.trianvertex_to_handle[vertex.petgraph_index().index()].unwrap())
|
.vertex_data(self.trianvertex_to_handle[vertex.petgraph_index().index()].unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn weight_mut(&mut self, vertex: I) -> &mut VW {
|
pub fn weight_mut(&mut self, vertex: I) -> &mut VW {
|
||||||
spade::Triangulation::vertex_data_mut(
|
spade::Triangulation::vertex_data_mut(
|
||||||
&mut self.triangulation,
|
&mut self.cdt,
|
||||||
self.trianvertex_to_handle[vertex.petgraph_index().index()].unwrap(),
|
self.trianvertex_to_handle[vertex.petgraph_index().index()].unwrap(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vertex(&self, handle: FixedVertexHandle) -> I {
|
fn vertex(&self, handle: FixedVertexHandle) -> I {
|
||||||
spade::Triangulation::vertex(&self.triangulation, handle)
|
spade::Triangulation::vertex(&self.cdt, handle)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.node_index()
|
.node_index()
|
||||||
}
|
}
|
||||||
|
|
@ -68,8 +75,7 @@ impl<I: GetPetgraphIndex, VW: GetTrianvertexNodeIndex<I> + HasPosition, EW: Defa
|
||||||
where
|
where
|
||||||
<VW as HasPosition>::Scalar: geo::CoordNum,
|
<VW as HasPosition>::Scalar: geo::CoordNum,
|
||||||
{
|
{
|
||||||
let position =
|
let position = spade::Triangulation::vertex(&self.cdt, self.handle(vertex)).position();
|
||||||
spade::Triangulation::vertex(&self.triangulation, self.handle(vertex)).position();
|
|
||||||
point! {x: position.x, y: position.y}
|
point! {x: position.x, y: position.y}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -152,7 +158,7 @@ impl<
|
||||||
|
|
||||||
fn neighbors(self, vertex: Self::NodeId) -> Self::Neighbors {
|
fn neighbors(self, vertex: Self::NodeId) -> Self::Neighbors {
|
||||||
Box::new(
|
Box::new(
|
||||||
spade::Triangulation::vertex(&self.triangulation, self.handle(vertex))
|
spade::Triangulation::vertex(&self.cdt, self.handle(vertex))
|
||||||
.out_edges()
|
.out_edges()
|
||||||
.map(|handle| self.vertex(handle.to().fix())),
|
.map(|handle| self.vertex(handle.to().fix())),
|
||||||
)
|
)
|
||||||
|
|
@ -170,8 +176,7 @@ impl<
|
||||||
type EdgeReferences = Box<dyn Iterator<Item = TriangulationEdgeReference<I, EW>> + 'a>;
|
type EdgeReferences = Box<dyn Iterator<Item = TriangulationEdgeReference<I, EW>> + 'a>;
|
||||||
|
|
||||||
fn edge_references(self) -> Self::EdgeReferences {
|
fn edge_references(self) -> Self::EdgeReferences {
|
||||||
Box::new(
|
Box::new(spade::Triangulation::directed_edges(&self.cdt).map(|edge| {
|
||||||
spade::Triangulation::directed_edges(&self.triangulation).map(|edge| {
|
|
||||||
let from = self.vertex(edge.from().fix());
|
let from = self.vertex(edge.from().fix());
|
||||||
let to = self.vertex(edge.to().fix());
|
let to = self.vertex(edge.to().fix());
|
||||||
|
|
||||||
|
|
@ -183,8 +188,7 @@ impl<
|
||||||
weight: *edge.data(),
|
weight: *edge.data(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}),
|
}))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,7 +203,7 @@ impl<
|
||||||
|
|
||||||
fn edges(self, node: Self::NodeId) -> Self::Edges {
|
fn edges(self, node: Self::NodeId) -> Self::Edges {
|
||||||
Box::new(
|
Box::new(
|
||||||
spade::Triangulation::vertex(&self.triangulation, self.handle(node))
|
spade::Triangulation::vertex(&self.cdt, self.handle(node))
|
||||||
.out_edges()
|
.out_edges()
|
||||||
.map(|edge| {
|
.map(|edge| {
|
||||||
let from = self.vertex(edge.from().fix());
|
let from = self.vertex(edge.from().fix());
|
||||||
|
|
@ -229,8 +233,8 @@ impl<
|
||||||
|
|
||||||
fn node_identifiers(self) -> Self::NodeIdentifiers {
|
fn node_identifiers(self) -> Self::NodeIdentifiers {
|
||||||
Box::new(
|
Box::new(
|
||||||
spade::Triangulation::fixed_vertices(&self.triangulation).map(|vertex| {
|
spade::Triangulation::fixed_vertices(&self.cdt).map(|vertex| {
|
||||||
spade::Triangulation::s(&self.triangulation)
|
spade::Triangulation::s(&self.cdt)
|
||||||
.vertex_data(vertex)
|
.vertex_data(vertex)
|
||||||
.node_index()
|
.node_index()
|
||||||
}),
|
}),
|
||||||
|
|
@ -280,8 +284,8 @@ impl<
|
||||||
|
|
||||||
fn node_references(self) -> Self::NodeReferences {
|
fn node_references(self) -> Self::NodeReferences {
|
||||||
Box::new(
|
Box::new(
|
||||||
spade::Triangulation::fixed_vertices(&self.triangulation).map(|vertex| {
|
spade::Triangulation::fixed_vertices(&self.cdt).map(|vertex| {
|
||||||
let weight = spade::Triangulation::s(&self.triangulation).vertex_data(vertex);
|
let weight = spade::Triangulation::s(&self.cdt).vertex_data(vertex);
|
||||||
TriangulationVertexReference {
|
TriangulationVertexReference {
|
||||||
index: weight.node_index(),
|
index: weight.node_index(),
|
||||||
weight,
|
weight,
|
||||||
|
|
@ -307,7 +311,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_index(&self, index: usize) -> I {
|
fn from_index(&self, index: usize) -> I {
|
||||||
spade::Triangulation::s(&self.triangulation)
|
spade::Triangulation::s(&self.cdt)
|
||||||
.vertex_data(self.trianvertex_to_handle[index].unwrap())
|
.vertex_data(self.trianvertex_to_handle[index].unwrap())
|
||||||
.node_index()
|
.node_index()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue