mirror of https://codeberg.org/topola/topola.git
feat(drawing/drawing): Make it possible to have multiple outers for each gear
This commit is contained in:
parent
6317d8b08a
commit
83285dde6d
|
|
@ -2,12 +2,12 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::graph::MakeRef;
|
||||
use petgraph::visit::Walker;
|
||||
|
||||
use super::{
|
||||
band::{BandTermsegIndex, BandUid},
|
||||
bend::LooseBendIndex,
|
||||
gear::{GearIndex, GetNextGear},
|
||||
gear::WalkOutwards,
|
||||
graph::PrimitiveIndex,
|
||||
loose::{GetPrevNextLoose, LooseIndex},
|
||||
primitive::GetJoints,
|
||||
|
|
@ -26,9 +26,7 @@ pub trait Collect {
|
|||
|
||||
fn bend_bow(&self, bend: LooseBendIndex) -> Vec<PrimitiveIndex>;
|
||||
|
||||
fn bend_outer_bows(&self, bend: LooseBendIndex) -> Vec<PrimitiveIndex>;
|
||||
|
||||
fn wraparounded_bows(&self, around: GearIndex) -> Vec<PrimitiveIndex>;
|
||||
fn bend_outward_bows(&self, bend: LooseBendIndex) -> Vec<PrimitiveIndex>;
|
||||
}
|
||||
|
||||
impl<CW: Clone, Cel: Copy, R: AccessRules> Collect for Drawing<CW, Cel, R> {
|
||||
|
|
@ -62,35 +60,12 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Collect for Drawing<CW, Cel, R> {
|
|||
v
|
||||
}
|
||||
|
||||
fn bend_outer_bows(&self, bend: LooseBendIndex) -> Vec<PrimitiveIndex> {
|
||||
fn bend_outward_bows(&self, bend: LooseBendIndex) -> Vec<PrimitiveIndex> {
|
||||
let mut v = vec![];
|
||||
let mut gear = bend;
|
||||
|
||||
while let Some(outer) = self.primitive(gear).outer() {
|
||||
v.append(&mut self.bend_bow(outer));
|
||||
gear = outer;
|
||||
}
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
fn wraparounded_bows(&self, around: GearIndex) -> Vec<PrimitiveIndex> {
|
||||
let mut v = vec![];
|
||||
let mut gear = around;
|
||||
|
||||
while let Some(bend) = gear.ref_(self).next_gear() {
|
||||
let primitive = self.primitive(bend);
|
||||
|
||||
v.push(bend.into());
|
||||
|
||||
let joints = primitive.joints();
|
||||
v.push(joints.0.into());
|
||||
v.push(joints.1.into());
|
||||
|
||||
v.push(self.primitive(joints.0).seg().unwrap().into());
|
||||
v.push(self.primitive(joints.1).seg().unwrap().into());
|
||||
|
||||
gear = bend.into();
|
||||
let mut outwards = self.primitive(bend).outwards();
|
||||
while let Some(next) = outwards.walk_next(self) {
|
||||
v.append(&mut self.bend_bow(next));
|
||||
}
|
||||
|
||||
v
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
use contracts_try::{debug_ensures, debug_invariant};
|
||||
use derive_getters::Getters;
|
||||
use geo::{Point, Polygon};
|
||||
use petgraph::visit::Walker;
|
||||
|
||||
use core::fmt;
|
||||
use rstar::{RTree, AABB};
|
||||
|
|
@ -17,7 +18,7 @@ use crate::{
|
|||
cane::Cane,
|
||||
collect::Collect,
|
||||
dot::{DotIndex, DotWeight, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
||||
gear::{GearIndex, GetNextGear},
|
||||
gear::GearIndex,
|
||||
graph::{GetMaybeNet, IsInLayer, MakePrimitive, PrimitiveIndex, PrimitiveWeight},
|
||||
guide::Guide,
|
||||
loose::{GetPrevNextLoose, Loose, LooseIndex},
|
||||
|
|
@ -44,6 +45,8 @@ use crate::{
|
|||
math::RotationSense,
|
||||
};
|
||||
|
||||
use super::gear::{GetOuterGears, WalkOutwards};
|
||||
|
||||
#[derive(Clone, Copy, Error)]
|
||||
pub enum DrawingException {
|
||||
#[error(transparent)]
|
||||
|
|
@ -255,7 +258,7 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
|||
LooseIndex::Bend(bend) => {
|
||||
bends.push(bend);
|
||||
|
||||
if let Some(outer) = self.primitive(bend).outer() {
|
||||
for outer in self.primitive(bend).outers().collect::<Vec<_>>() {
|
||||
outers.push(outer);
|
||||
self.reattach_bend(recorder, outer, self.primitive(bend).inner());
|
||||
}
|
||||
|
|
@ -509,10 +512,11 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
|||
}
|
||||
}
|
||||
//
|
||||
if let Some(next_gear) = around.ref_(self).next_gear() {
|
||||
if let Some(next_gear_net) = next_gear.primitive(self).maybe_net() {
|
||||
let mut outwards = around.ref_(self).outwards();
|
||||
while let Some(gear) = outwards.walk_next(self) {
|
||||
if let Some(next_gear_net) = gear.primitive(self).maybe_net() {
|
||||
if net == next_gear_net {
|
||||
return Err(AlreadyConnected(net, next_gear.into()).into());
|
||||
return Err(AlreadyConnected(net, gear.into()).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -666,7 +670,7 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
|||
bend_weight: LooseBendWeight,
|
||||
sense: RotationSense,
|
||||
) -> Result<Cane, DrawingException> {
|
||||
let maybe_next_gear = around.ref_(self).next_gear();
|
||||
let outer_gears = around.ref_(self).outer_gears();
|
||||
let cane = self.add_cane_with_infringement_filtering(
|
||||
recorder,
|
||||
from,
|
||||
|
|
@ -678,11 +682,11 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
|||
&|_drawing, _infringer, _infringee| true,
|
||||
)?;
|
||||
|
||||
if let Some(next_gear) = maybe_next_gear {
|
||||
self.reattach_bend(recorder, next_gear, Some(cane.bend));
|
||||
for gear in outer_gears {
|
||||
self.reattach_bend(recorder, gear, Some(cane.bend));
|
||||
}
|
||||
|
||||
if let Some(outer) = self.primitive(cane.bend).outer() {
|
||||
for outer in self.primitive(cane.bend).outers().collect::<Vec<_>>() {
|
||||
self.update_this_and_outward_bows(recorder, outer)
|
||||
.inspect_err(|_| {
|
||||
let joint = self.primitive(cane.bend).other_joint(cane.dot);
|
||||
|
|
@ -700,81 +704,88 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
|||
recorder: &mut DrawingEdit<CW, Cel>,
|
||||
around: LooseBendIndex,
|
||||
) -> Result<(), DrawingException> {
|
||||
let mut maybe_rail = Some(around);
|
||||
self.update_bow(recorder, around)?;
|
||||
|
||||
while let Some(rail) = maybe_rail {
|
||||
let rail_primitive = self.primitive(rail);
|
||||
let joints = rail_primitive.joints();
|
||||
let width = rail_primitive.width();
|
||||
|
||||
let from_head = self.rear_head(joints.1);
|
||||
let to_head = self.rear_head(joints.0);
|
||||
|
||||
let (from, to, offset) = if let Some(inner) = rail_primitive.inner() {
|
||||
let inner = inner.into();
|
||||
let from = self.guide_for_head_around_bend_segment(
|
||||
&from_head,
|
||||
inner,
|
||||
RotationSense::Counterclockwise,
|
||||
width,
|
||||
)?;
|
||||
let to = self.guide_for_head_around_bend_segment(
|
||||
&to_head,
|
||||
inner,
|
||||
RotationSense::Clockwise,
|
||||
width,
|
||||
)?;
|
||||
let offset = self.guide_for_head_around_bend_offset(&from_head, inner, width);
|
||||
(from, to, offset)
|
||||
} else {
|
||||
let core = rail_primitive.core().into();
|
||||
let from = self.guide_for_head_around_dot_segment(
|
||||
&from_head,
|
||||
core,
|
||||
RotationSense::Counterclockwise,
|
||||
width,
|
||||
)?;
|
||||
let to = self.guide_for_head_around_dot_segment(
|
||||
&to_head,
|
||||
core,
|
||||
RotationSense::Clockwise,
|
||||
width,
|
||||
)?;
|
||||
let offset = self.guide_for_head_around_dot_offset(&from_head, core, width);
|
||||
(from, to, offset)
|
||||
};
|
||||
|
||||
let rail_outer_bows = self.bend_outer_bows(rail);
|
||||
|
||||
// Commenting out these two makes the crash go away.
|
||||
self.move_dot_with_infringement_filtering(
|
||||
recorder,
|
||||
joints.0.into(),
|
||||
from.end_point(),
|
||||
&|_drawing, _infringer, infringee| rail_outer_bows.contains(&infringee),
|
||||
)?;
|
||||
self.move_dot_with_infringement_filtering(
|
||||
recorder,
|
||||
joints.1.into(),
|
||||
to.end_point(),
|
||||
&|_drawing, _infringer, infringee| rail_outer_bows.contains(&infringee),
|
||||
)?;
|
||||
|
||||
self.shift_bend_with_infringement_filtering(
|
||||
recorder,
|
||||
rail.into(),
|
||||
offset,
|
||||
&|_drawing, _infringer, infringee| rail_outer_bows.contains(&infringee),
|
||||
)?;
|
||||
|
||||
// Update offsets in case the rule conditions changed.
|
||||
|
||||
maybe_rail = self.primitive(rail).outer();
|
||||
let mut outwards = self.primitive(around).outwards();
|
||||
while let Some(rail) = outwards.walk_next(self) {
|
||||
self.update_bow(recorder, rail)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_bow(
|
||||
&mut self,
|
||||
recorder: &mut DrawingEdit<CW, Cel>,
|
||||
rail: LooseBendIndex,
|
||||
) -> Result<(), DrawingException> {
|
||||
let rail_primitive = self.primitive(rail);
|
||||
let joints = rail_primitive.joints();
|
||||
let width = rail_primitive.width();
|
||||
|
||||
let from_head = self.rear_head(joints.1);
|
||||
let to_head = self.rear_head(joints.0);
|
||||
|
||||
let (from, to, offset) = if let Some(inner) = rail_primitive.inner() {
|
||||
let inner = inner.into();
|
||||
let from = self.guide_for_head_around_bend_segment(
|
||||
&from_head,
|
||||
inner,
|
||||
RotationSense::Counterclockwise,
|
||||
width,
|
||||
)?;
|
||||
let to = self.guide_for_head_around_bend_segment(
|
||||
&to_head,
|
||||
inner,
|
||||
RotationSense::Clockwise,
|
||||
width,
|
||||
)?;
|
||||
let offset = self.guide_for_head_around_bend_offset(&from_head, inner, width);
|
||||
(from, to, offset)
|
||||
} else {
|
||||
let core = rail_primitive.core().into();
|
||||
let from = self.guide_for_head_around_dot_segment(
|
||||
&from_head,
|
||||
core,
|
||||
RotationSense::Counterclockwise,
|
||||
width,
|
||||
)?;
|
||||
let to = self.guide_for_head_around_dot_segment(
|
||||
&to_head,
|
||||
core,
|
||||
RotationSense::Clockwise,
|
||||
width,
|
||||
)?;
|
||||
let offset = self.guide_for_head_around_dot_offset(&from_head, core, width);
|
||||
(from, to, offset)
|
||||
};
|
||||
|
||||
let rail_outer_bows = self.bend_outward_bows(rail);
|
||||
|
||||
// Commenting out these two makes the crash go away.
|
||||
self.move_dot_with_infringement_filtering(
|
||||
recorder,
|
||||
joints.0.into(),
|
||||
from.end_point(),
|
||||
&|_drawing, _infringer, infringee| rail_outer_bows.contains(&infringee),
|
||||
)?;
|
||||
self.move_dot_with_infringement_filtering(
|
||||
recorder,
|
||||
joints.1.into(),
|
||||
to.end_point(),
|
||||
&|_drawing, _infringer, infringee| rail_outer_bows.contains(&infringee),
|
||||
)?;
|
||||
|
||||
self.shift_bend_with_infringement_filtering(
|
||||
recorder,
|
||||
rail.into(),
|
||||
offset,
|
||||
&|_drawing, _infringer, infringee| rail_outer_bows.contains(&infringee),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count() + 4))]
|
||||
#[debug_ensures(ret.is_ok() -> self.recording_geometry_with_rtree.graph().edge_count() >= old(self.recording_geometry_with_rtree.graph().edge_count() + 5))]
|
||||
#[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count()))]
|
||||
|
|
@ -877,11 +888,11 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
|||
cane: &Cane,
|
||||
face: LooseDotIndex,
|
||||
) {
|
||||
let maybe_outer = self.primitive(cane.bend).outer();
|
||||
let outers = self.primitive(cane.bend).outers().collect::<Vec<_>>();
|
||||
|
||||
// Removing a loose bend affects its outer bends.
|
||||
if let Some(outer) = maybe_outer {
|
||||
self.reattach_bend(recorder, outer, self.primitive(cane.bend).inner());
|
||||
for outer in &outers {
|
||||
self.reattach_bend(recorder, *outer, self.primitive(cane.bend).inner());
|
||||
}
|
||||
|
||||
self.recording_geometry_with_rtree
|
||||
|
|
@ -897,7 +908,7 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
|||
self.recording_geometry_with_rtree
|
||||
.remove_dot(recorder, cane.dot.into());
|
||||
|
||||
if let Some(outer) = maybe_outer {
|
||||
for outer in outers {
|
||||
self.update_this_and_outward_bows(recorder, outer).unwrap(); // Must never fail.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,26 +2,23 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use petgraph::stable_graph::NodeIndex;
|
||||
use petgraph::{stable_graph::NodeIndex, visit::Walker};
|
||||
|
||||
use crate::{
|
||||
drawing::{
|
||||
bend::{BendIndex, FixedBendIndex, LooseBendIndex},
|
||||
dot::FixedDotIndex,
|
||||
graph::{MakePrimitive, PrimitiveIndex},
|
||||
primitive::{FixedBend, FixedDot, GetFirstGear, LooseBend, Primitive},
|
||||
primitive::{FixedBend, FixedDot, LooseBend, Primitive},
|
||||
rules::AccessRules,
|
||||
Drawing,
|
||||
},
|
||||
graph::{GetPetgraphIndex, MakeRef},
|
||||
};
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait GetNextGear: GetPetgraphIndex {
|
||||
fn next_gear(&self) -> Option<LooseBendIndex>;
|
||||
}
|
||||
|
||||
#[enum_dispatch(GetPetgraphIndex, MakePrimitive)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum GearIndex {
|
||||
|
|
@ -56,7 +53,7 @@ impl From<BendIndex> for GearIndex {
|
|||
}
|
||||
}
|
||||
|
||||
#[enum_dispatch(GetNextGear, GetDrawing, GetPetgraphIndex)]
|
||||
#[enum_dispatch(WalkOutwards, GetOuterGears, GetDrawing, GetPetgraphIndex)]
|
||||
pub enum GearRef<'a, CW, Cel, R> {
|
||||
FixedDot(FixedDot<'a, CW, Cel, R>),
|
||||
FixedBend(FixedBend<'a, CW, Cel, R>),
|
||||
|
|
@ -73,20 +70,40 @@ impl<'a, CW, Cel, R> GearRef<'a, CW, Cel, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW, Cel, R> GetNextGear for FixedDot<'_, CW, Cel, R> {
|
||||
fn next_gear(&self) -> Option<LooseBendIndex> {
|
||||
self.first_gear()
|
||||
#[enum_dispatch]
|
||||
pub trait GetOuterGears {
|
||||
// TODO: This duplicates `.outers()` methods in some other places, we need
|
||||
// to merge them with this.
|
||||
// TODO: Use iterator instead of vec.
|
||||
fn outer_gears(&self) -> Vec<LooseBendIndex>;
|
||||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait WalkOutwards {
|
||||
fn outwards(&self) -> DrawingOutwardWalker;
|
||||
}
|
||||
|
||||
/// I found it easier to just duplicate `OutwardWalker<BI>` for `Drawing<...>`.
|
||||
pub struct DrawingOutwardWalker {
|
||||
frontier: VecDeque<LooseBendIndex>,
|
||||
}
|
||||
|
||||
impl DrawingOutwardWalker {
|
||||
pub fn new(initial_frontier: impl Iterator<Item = LooseBendIndex>) -> Self {
|
||||
let mut frontier = VecDeque::new();
|
||||
frontier.extend(initial_frontier);
|
||||
|
||||
Self { frontier }
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW, Cel, R> GetNextGear for LooseBend<'_, CW, Cel, R> {
|
||||
fn next_gear(&self) -> Option<LooseBendIndex> {
|
||||
self.outer()
|
||||
}
|
||||
}
|
||||
impl<CW: Clone, Cel: Copy, R: AccessRules> Walker<&Drawing<CW, Cel, R>> for DrawingOutwardWalker {
|
||||
type Item = LooseBendIndex;
|
||||
|
||||
impl<CW, Cel, R> GetNextGear for FixedBend<'_, CW, Cel, R> {
|
||||
fn next_gear(&self) -> Option<LooseBendIndex> {
|
||||
self.first_gear()
|
||||
fn walk_next(&mut self, drawing: &Drawing<CW, Cel, R>) -> Option<Self::Item> {
|
||||
let front = self.frontier.pop_front()?;
|
||||
self.frontier.extend(drawing.primitive(front).outers());
|
||||
|
||||
Some(front)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ use crate::{
|
|||
graph::{GenericIndex, GetPetgraphIndex},
|
||||
};
|
||||
|
||||
use super::gear::{DrawingOutwardWalker, GetOuterGears, WalkOutwards};
|
||||
|
||||
pub trait GetDrawing {
|
||||
type CompoundWeight;
|
||||
type CompoundEntryLabel;
|
||||
|
|
@ -86,12 +88,14 @@ pub trait GetJoints {
|
|||
fn joints(&self) -> (Self::F, Self::T);
|
||||
}
|
||||
|
||||
pub trait GetFirstGear: GetDrawing + GetPetgraphIndex {
|
||||
fn first_gear(&self) -> Option<LooseBendIndex> {
|
||||
pub trait GetLowestGears: GetDrawing + GetPetgraphIndex {
|
||||
// TODO: Make it return an iterator instead of a vec.
|
||||
fn lowest_gears(&self) -> Vec<LooseBendIndex> {
|
||||
self.drawing()
|
||||
.geometry()
|
||||
.first_rail(self.petgraph_index())
|
||||
.all_rails(self.petgraph_index())
|
||||
.map(|ni| LooseBendIndex::new(ni.petgraph_index()))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -279,7 +283,19 @@ impl<CW, Cel, R> GetLimbs for FixedDot<'_, CW, Cel, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW, Cel, R> GetFirstGear for FixedDot<'_, CW, Cel, R> {}
|
||||
impl<CW, Cel, R> GetLowestGears for FixedDot<'_, CW, Cel, R> {}
|
||||
|
||||
impl<CW, Cel, R> GetOuterGears for FixedDot<'_, CW, Cel, R> {
|
||||
fn outer_gears(&self) -> Vec<LooseBendIndex> {
|
||||
self.lowest_gears()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW, Cel, R> WalkOutwards for FixedDot<'_, CW, Cel, R> {
|
||||
fn outwards(&self) -> DrawingOutwardWalker {
|
||||
DrawingOutwardWalker::new(self.lowest_gears().into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
pub type LooseDot<'a, CW, Cel, R> = GenericPrimitive<'a, LooseDotWeight, CW, Cel, R>;
|
||||
impl_loose_primitive!(LooseDot, LooseDotWeight);
|
||||
|
|
@ -433,8 +449,19 @@ impl<CW, Cel, R> GetJoints for FixedBend<'_, CW, Cel, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW, Cel, R> GetFirstGear for FixedBend<'_, CW, Cel, R> {}
|
||||
//impl<'a, R: QueryRules> GetInnerOuter for FixedBend<'a, CW, Cel, R> {}
|
||||
impl<CW, Cel, R> GetLowestGears for FixedBend<'_, CW, Cel, R> {}
|
||||
|
||||
impl<CW, Cel, R> GetOuterGears for FixedBend<'_, CW, Cel, R> {
|
||||
fn outer_gears(&self) -> Vec<LooseBendIndex> {
|
||||
self.lowest_gears()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW, Cel, R> WalkOutwards for FixedBend<'_, CW, Cel, R> {
|
||||
fn outwards(&self) -> DrawingOutwardWalker {
|
||||
DrawingOutwardWalker::new(self.lowest_gears().into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
pub type LooseBend<'a, CW, Cel, R> = GenericPrimitive<'a, LooseBendWeight, CW, Cel, R>;
|
||||
impl_loose_primitive!(LooseBend, LooseBendWeight);
|
||||
|
|
@ -477,6 +504,18 @@ impl<CW, Cel, R> GetJoints for LooseBend<'_, CW, Cel, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW, Cel, R> GetOuterGears for LooseBend<'_, CW, Cel, R> {
|
||||
fn outer_gears(&self) -> Vec<LooseBendIndex> {
|
||||
self.outers().collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW, Cel, R> WalkOutwards for LooseBend<'_, CW, Cel, R> {
|
||||
fn outwards(&self) -> DrawingOutwardWalker {
|
||||
DrawingOutwardWalker::new(self.outers())
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW, Cel, R> LooseBend<'_, CW, Cel, R> {
|
||||
pub fn inner(&self) -> Option<LooseBendIndex> {
|
||||
self.drawing()
|
||||
|
|
@ -485,11 +524,10 @@ impl<CW, Cel, R> LooseBend<'_, CW, Cel, R> {
|
|||
.map(|ni| LooseBendIndex::new(ni.petgraph_index()))
|
||||
}
|
||||
|
||||
pub fn outer(&self) -> Option<LooseBendIndex> {
|
||||
pub fn outers(&self) -> impl Iterator<Item = LooseBendIndex> + '_ {
|
||||
self.drawing()
|
||||
.geometry()
|
||||
.outers(self.bend_index())
|
||||
.next()
|
||||
.map(|node| LooseBendIndex::new(node.petgraph_index()))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -573,15 +573,6 @@ impl<
|
|||
BI: GetPetgraphIndex,
|
||||
> Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI>
|
||||
{
|
||||
pub fn first_rail(&self, node: NodeIndex<usize>) -> Option<BI> {
|
||||
self.all_rails(node).find(|bend| {
|
||||
!self
|
||||
.graph
|
||||
.edges_directed(bend.petgraph_index(), Incoming)
|
||||
.any(|edge| matches!(edge.weight(), GeometryLabel::Outer))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn all_rails(&self, node: NodeIndex<usize>) -> impl Iterator<Item = BI> + '_ {
|
||||
self.graph
|
||||
.edges_directed(node, Incoming)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ use petgraph::{
|
|||
graph::UnGraph,
|
||||
stable_graph::NodeIndex,
|
||||
visit::{
|
||||
Data, EdgeRef, GraphBase, IntoEdgeReferences, IntoEdges, IntoNeighbors, IntoNodeIdentifiers,
|
||||
Data, EdgeRef, GraphBase, IntoEdgeReferences, IntoEdges, IntoNeighbors,
|
||||
IntoNodeIdentifiers, Walker,
|
||||
},
|
||||
};
|
||||
use spade::InsertionError;
|
||||
|
|
@ -21,7 +22,7 @@ use crate::{
|
|||
drawing::{
|
||||
bend::{FixedBendIndex, LooseBendIndex},
|
||||
dot::FixedDotIndex,
|
||||
gear::{GearIndex, GetNextGear},
|
||||
gear::{GearIndex, GetOuterGears, WalkOutwards},
|
||||
graph::{MakePrimitive, PrimitiveIndex},
|
||||
primitive::Primitive,
|
||||
rules::AccessRules,
|
||||
|
|
@ -183,8 +184,7 @@ impl Navmesh {
|
|||
} else {
|
||||
map.insert(trianvertex, vec![]);
|
||||
|
||||
let mut gear =
|
||||
Into::<GearIndex>::into(Into::<BinavnodeNodeIndex>::into(trianvertex));
|
||||
let gear = Into::<GearIndex>::into(Into::<BinavnodeNodeIndex>::into(trianvertex));
|
||||
|
||||
if options.squeeze_through_under_bends {
|
||||
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
||||
|
|
@ -195,30 +195,34 @@ impl Navmesh {
|
|||
);
|
||||
|
||||
if options.wrap_around_bands {
|
||||
while let Some(bend) = gear.ref_(layout.drawing()).next_gear() {
|
||||
let mut outwards = gear.ref_(layout.drawing()).outwards();
|
||||
while let Some(outward) = outwards.walk_next(layout.drawing()) {
|
||||
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
||||
&mut graph,
|
||||
&mut map,
|
||||
trianvertex,
|
||||
bend.into(),
|
||||
outward.into(),
|
||||
);
|
||||
gear = bend.into();
|
||||
}
|
||||
}
|
||||
} else if let Some(first_bend) = gear.ref_(layout.drawing()).next_gear() {
|
||||
let mut bend = first_bend;
|
||||
|
||||
while let Some(next_bend) = gear.ref_(layout.drawing()).next_gear() {
|
||||
bend = next_bend;
|
||||
gear = bend.into();
|
||||
} else if !gear.ref_(layout.drawing()).outer_gears().is_empty() {
|
||||
let mut outwards = gear.ref_(layout.drawing()).outwards();
|
||||
while let Some(outward) = outwards.walk_next(layout.drawing()) {
|
||||
if layout
|
||||
.drawing()
|
||||
.primitive(outward)
|
||||
.outers()
|
||||
.collect::<Vec<_>>()
|
||||
.is_empty()
|
||||
{
|
||||
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
||||
&mut graph,
|
||||
&mut map,
|
||||
trianvertex,
|
||||
outward.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
||||
&mut graph,
|
||||
&mut map,
|
||||
trianvertex,
|
||||
bend.into(),
|
||||
);
|
||||
} else {
|
||||
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
||||
&mut graph,
|
||||
|
|
|
|||
Loading…
Reference in New Issue