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
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
use crate::graph::MakeRef;
|
use petgraph::visit::Walker;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
band::{BandTermsegIndex, BandUid},
|
band::{BandTermsegIndex, BandUid},
|
||||||
bend::LooseBendIndex,
|
bend::LooseBendIndex,
|
||||||
gear::{GearIndex, GetNextGear},
|
gear::WalkOutwards,
|
||||||
graph::PrimitiveIndex,
|
graph::PrimitiveIndex,
|
||||||
loose::{GetPrevNextLoose, LooseIndex},
|
loose::{GetPrevNextLoose, LooseIndex},
|
||||||
primitive::GetJoints,
|
primitive::GetJoints,
|
||||||
|
|
@ -26,9 +26,7 @@ pub trait Collect {
|
||||||
|
|
||||||
fn bend_bow(&self, bend: LooseBendIndex) -> Vec<PrimitiveIndex>;
|
fn bend_bow(&self, bend: LooseBendIndex) -> Vec<PrimitiveIndex>;
|
||||||
|
|
||||||
fn bend_outer_bows(&self, bend: LooseBendIndex) -> Vec<PrimitiveIndex>;
|
fn bend_outward_bows(&self, bend: LooseBendIndex) -> Vec<PrimitiveIndex>;
|
||||||
|
|
||||||
fn wraparounded_bows(&self, around: GearIndex) -> Vec<PrimitiveIndex>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CW: Clone, Cel: Copy, R: AccessRules> Collect for Drawing<CW, Cel, R> {
|
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
|
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 v = vec![];
|
||||||
let mut gear = bend;
|
|
||||||
|
|
||||||
while let Some(outer) = self.primitive(gear).outer() {
|
let mut outwards = self.primitive(bend).outwards();
|
||||||
v.append(&mut self.bend_bow(outer));
|
while let Some(next) = outwards.walk_next(self) {
|
||||||
gear = outer;
|
v.append(&mut self.bend_bow(next));
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v
|
v
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
use contracts_try::{debug_ensures, debug_invariant};
|
use contracts_try::{debug_ensures, debug_invariant};
|
||||||
use derive_getters::Getters;
|
use derive_getters::Getters;
|
||||||
use geo::{Point, Polygon};
|
use geo::{Point, Polygon};
|
||||||
|
use petgraph::visit::Walker;
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use rstar::{RTree, AABB};
|
use rstar::{RTree, AABB};
|
||||||
|
|
@ -17,7 +18,7 @@ use crate::{
|
||||||
cane::Cane,
|
cane::Cane,
|
||||||
collect::Collect,
|
collect::Collect,
|
||||||
dot::{DotIndex, DotWeight, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
dot::{DotIndex, DotWeight, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
||||||
gear::{GearIndex, GetNextGear},
|
gear::GearIndex,
|
||||||
graph::{GetMaybeNet, IsInLayer, MakePrimitive, PrimitiveIndex, PrimitiveWeight},
|
graph::{GetMaybeNet, IsInLayer, MakePrimitive, PrimitiveIndex, PrimitiveWeight},
|
||||||
guide::Guide,
|
guide::Guide,
|
||||||
loose::{GetPrevNextLoose, Loose, LooseIndex},
|
loose::{GetPrevNextLoose, Loose, LooseIndex},
|
||||||
|
|
@ -44,6 +45,8 @@ use crate::{
|
||||||
math::RotationSense,
|
math::RotationSense,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::gear::{GetOuterGears, WalkOutwards};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Error)]
|
#[derive(Clone, Copy, Error)]
|
||||||
pub enum DrawingException {
|
pub enum DrawingException {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
|
@ -255,7 +258,7 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
||||||
LooseIndex::Bend(bend) => {
|
LooseIndex::Bend(bend) => {
|
||||||
bends.push(bend);
|
bends.push(bend);
|
||||||
|
|
||||||
if let Some(outer) = self.primitive(bend).outer() {
|
for outer in self.primitive(bend).outers().collect::<Vec<_>>() {
|
||||||
outers.push(outer);
|
outers.push(outer);
|
||||||
self.reattach_bend(recorder, outer, self.primitive(bend).inner());
|
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() {
|
let mut outwards = around.ref_(self).outwards();
|
||||||
if let Some(next_gear_net) = next_gear.primitive(self).maybe_net() {
|
while let Some(gear) = outwards.walk_next(self) {
|
||||||
|
if let Some(next_gear_net) = gear.primitive(self).maybe_net() {
|
||||||
if net == next_gear_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,
|
bend_weight: LooseBendWeight,
|
||||||
sense: RotationSense,
|
sense: RotationSense,
|
||||||
) -> Result<Cane, DrawingException> {
|
) -> 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(
|
let cane = self.add_cane_with_infringement_filtering(
|
||||||
recorder,
|
recorder,
|
||||||
from,
|
from,
|
||||||
|
|
@ -678,11 +682,11 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
||||||
&|_drawing, _infringer, _infringee| true,
|
&|_drawing, _infringer, _infringee| true,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if let Some(next_gear) = maybe_next_gear {
|
for gear in outer_gears {
|
||||||
self.reattach_bend(recorder, next_gear, Some(cane.bend));
|
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)
|
self.update_this_and_outward_bows(recorder, outer)
|
||||||
.inspect_err(|_| {
|
.inspect_err(|_| {
|
||||||
let joint = self.primitive(cane.bend).other_joint(cane.dot);
|
let joint = self.primitive(cane.bend).other_joint(cane.dot);
|
||||||
|
|
@ -700,9 +704,21 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
||||||
recorder: &mut DrawingEdit<CW, Cel>,
|
recorder: &mut DrawingEdit<CW, Cel>,
|
||||||
around: LooseBendIndex,
|
around: LooseBendIndex,
|
||||||
) -> Result<(), DrawingException> {
|
) -> Result<(), DrawingException> {
|
||||||
let mut maybe_rail = Some(around);
|
self.update_bow(recorder, around)?;
|
||||||
|
|
||||||
while let Some(rail) = maybe_rail {
|
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 rail_primitive = self.primitive(rail);
|
||||||
let joints = rail_primitive.joints();
|
let joints = rail_primitive.joints();
|
||||||
let width = rail_primitive.width();
|
let width = rail_primitive.width();
|
||||||
|
|
@ -744,7 +760,7 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
||||||
(from, to, offset)
|
(from, to, offset)
|
||||||
};
|
};
|
||||||
|
|
||||||
let rail_outer_bows = self.bend_outer_bows(rail);
|
let rail_outer_bows = self.bend_outward_bows(rail);
|
||||||
|
|
||||||
// Commenting out these two makes the crash go away.
|
// Commenting out these two makes the crash go away.
|
||||||
self.move_dot_with_infringement_filtering(
|
self.move_dot_with_infringement_filtering(
|
||||||
|
|
@ -767,11 +783,6 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
||||||
&|_drawing, _infringer, infringee| rail_outer_bows.contains(&infringee),
|
&|_drawing, _infringer, infringee| rail_outer_bows.contains(&infringee),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Update offsets in case the rule conditions changed.
|
|
||||||
|
|
||||||
maybe_rail = self.primitive(rail).outer();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -877,11 +888,11 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
||||||
cane: &Cane,
|
cane: &Cane,
|
||||||
face: LooseDotIndex,
|
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.
|
// Removing a loose bend affects its outer bends.
|
||||||
if let Some(outer) = maybe_outer {
|
for outer in &outers {
|
||||||
self.reattach_bend(recorder, outer, self.primitive(cane.bend).inner());
|
self.reattach_bend(recorder, *outer, self.primitive(cane.bend).inner());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.recording_geometry_with_rtree
|
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
|
self.recording_geometry_with_rtree
|
||||||
.remove_dot(recorder, cane.dot.into());
|
.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.
|
self.update_this_and_outward_bows(recorder, outer).unwrap(); // Must never fail.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,26 +2,23 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
use petgraph::stable_graph::NodeIndex;
|
use petgraph::{stable_graph::NodeIndex, visit::Walker};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{
|
drawing::{
|
||||||
bend::{BendIndex, FixedBendIndex, LooseBendIndex},
|
bend::{BendIndex, FixedBendIndex, LooseBendIndex},
|
||||||
dot::FixedDotIndex,
|
dot::FixedDotIndex,
|
||||||
graph::{MakePrimitive, PrimitiveIndex},
|
graph::{MakePrimitive, PrimitiveIndex},
|
||||||
primitive::{FixedBend, FixedDot, GetFirstGear, LooseBend, Primitive},
|
primitive::{FixedBend, FixedDot, LooseBend, Primitive},
|
||||||
rules::AccessRules,
|
rules::AccessRules,
|
||||||
Drawing,
|
Drawing,
|
||||||
},
|
},
|
||||||
graph::{GetPetgraphIndex, MakeRef},
|
graph::{GetPetgraphIndex, MakeRef},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[enum_dispatch]
|
|
||||||
pub trait GetNextGear: GetPetgraphIndex {
|
|
||||||
fn next_gear(&self) -> Option<LooseBendIndex>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[enum_dispatch(GetPetgraphIndex, MakePrimitive)]
|
#[enum_dispatch(GetPetgraphIndex, MakePrimitive)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum GearIndex {
|
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> {
|
pub enum GearRef<'a, CW, Cel, R> {
|
||||||
FixedDot(FixedDot<'a, CW, Cel, R>),
|
FixedDot(FixedDot<'a, CW, Cel, R>),
|
||||||
FixedBend(FixedBend<'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> {
|
#[enum_dispatch]
|
||||||
fn next_gear(&self) -> Option<LooseBendIndex> {
|
pub trait GetOuterGears {
|
||||||
self.first_gear()
|
// 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> {
|
impl<CW: Clone, Cel: Copy, R: AccessRules> Walker<&Drawing<CW, Cel, R>> for DrawingOutwardWalker {
|
||||||
fn next_gear(&self) -> Option<LooseBendIndex> {
|
type Item = LooseBendIndex;
|
||||||
self.outer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<CW, Cel, R> GetNextGear for FixedBend<'_, CW, Cel, R> {
|
fn walk_next(&mut self, drawing: &Drawing<CW, Cel, R>) -> Option<Self::Item> {
|
||||||
fn next_gear(&self) -> Option<LooseBendIndex> {
|
let front = self.frontier.pop_front()?;
|
||||||
self.first_gear()
|
self.frontier.extend(drawing.primitive(front).outers());
|
||||||
|
|
||||||
|
Some(front)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ use crate::{
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::gear::{DrawingOutwardWalker, GetOuterGears, WalkOutwards};
|
||||||
|
|
||||||
pub trait GetDrawing {
|
pub trait GetDrawing {
|
||||||
type CompoundWeight;
|
type CompoundWeight;
|
||||||
type CompoundEntryLabel;
|
type CompoundEntryLabel;
|
||||||
|
|
@ -86,12 +88,14 @@ pub trait GetJoints {
|
||||||
fn joints(&self) -> (Self::F, Self::T);
|
fn joints(&self) -> (Self::F, Self::T);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GetFirstGear: GetDrawing + GetPetgraphIndex {
|
pub trait GetLowestGears: GetDrawing + GetPetgraphIndex {
|
||||||
fn first_gear(&self) -> Option<LooseBendIndex> {
|
// TODO: Make it return an iterator instead of a vec.
|
||||||
|
fn lowest_gears(&self) -> Vec<LooseBendIndex> {
|
||||||
self.drawing()
|
self.drawing()
|
||||||
.geometry()
|
.geometry()
|
||||||
.first_rail(self.petgraph_index())
|
.all_rails(self.petgraph_index())
|
||||||
.map(|ni| LooseBendIndex::new(ni.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>;
|
pub type LooseDot<'a, CW, Cel, R> = GenericPrimitive<'a, LooseDotWeight, CW, Cel, R>;
|
||||||
impl_loose_primitive!(LooseDot, LooseDotWeight);
|
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<CW, Cel, R> GetLowestGears for FixedBend<'_, CW, Cel, R> {}
|
||||||
//impl<'a, R: QueryRules> GetInnerOuter for FixedBend<'a, 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>;
|
pub type LooseBend<'a, CW, Cel, R> = GenericPrimitive<'a, LooseBendWeight, CW, Cel, R>;
|
||||||
impl_loose_primitive!(LooseBend, LooseBendWeight);
|
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> {
|
impl<CW, Cel, R> LooseBend<'_, CW, Cel, R> {
|
||||||
pub fn inner(&self) -> Option<LooseBendIndex> {
|
pub fn inner(&self) -> Option<LooseBendIndex> {
|
||||||
self.drawing()
|
self.drawing()
|
||||||
|
|
@ -485,11 +524,10 @@ impl<CW, Cel, R> LooseBend<'_, CW, Cel, R> {
|
||||||
.map(|ni| LooseBendIndex::new(ni.petgraph_index()))
|
.map(|ni| LooseBendIndex::new(ni.petgraph_index()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outer(&self) -> Option<LooseBendIndex> {
|
pub fn outers(&self) -> impl Iterator<Item = LooseBendIndex> + '_ {
|
||||||
self.drawing()
|
self.drawing()
|
||||||
.geometry()
|
.geometry()
|
||||||
.outers(self.bend_index())
|
.outers(self.bend_index())
|
||||||
.next()
|
|
||||||
.map(|node| LooseBendIndex::new(node.petgraph_index()))
|
.map(|node| LooseBendIndex::new(node.petgraph_index()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -573,15 +573,6 @@ impl<
|
||||||
BI: GetPetgraphIndex,
|
BI: GetPetgraphIndex,
|
||||||
> Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI>
|
> 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> + '_ {
|
pub fn all_rails(&self, node: NodeIndex<usize>) -> impl Iterator<Item = BI> + '_ {
|
||||||
self.graph
|
self.graph
|
||||||
.edges_directed(node, Incoming)
|
.edges_directed(node, Incoming)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ use petgraph::{
|
||||||
graph::UnGraph,
|
graph::UnGraph,
|
||||||
stable_graph::NodeIndex,
|
stable_graph::NodeIndex,
|
||||||
visit::{
|
visit::{
|
||||||
Data, EdgeRef, GraphBase, IntoEdgeReferences, IntoEdges, IntoNeighbors, IntoNodeIdentifiers,
|
Data, EdgeRef, GraphBase, IntoEdgeReferences, IntoEdges, IntoNeighbors,
|
||||||
|
IntoNodeIdentifiers, Walker,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use spade::InsertionError;
|
use spade::InsertionError;
|
||||||
|
|
@ -21,7 +22,7 @@ use crate::{
|
||||||
drawing::{
|
drawing::{
|
||||||
bend::{FixedBendIndex, LooseBendIndex},
|
bend::{FixedBendIndex, LooseBendIndex},
|
||||||
dot::FixedDotIndex,
|
dot::FixedDotIndex,
|
||||||
gear::{GearIndex, GetNextGear},
|
gear::{GearIndex, GetOuterGears, WalkOutwards},
|
||||||
graph::{MakePrimitive, PrimitiveIndex},
|
graph::{MakePrimitive, PrimitiveIndex},
|
||||||
primitive::Primitive,
|
primitive::Primitive,
|
||||||
rules::AccessRules,
|
rules::AccessRules,
|
||||||
|
|
@ -183,8 +184,7 @@ impl Navmesh {
|
||||||
} else {
|
} else {
|
||||||
map.insert(trianvertex, vec![]);
|
map.insert(trianvertex, vec![]);
|
||||||
|
|
||||||
let mut gear =
|
let gear = Into::<GearIndex>::into(Into::<BinavnodeNodeIndex>::into(trianvertex));
|
||||||
Into::<GearIndex>::into(Into::<BinavnodeNodeIndex>::into(trianvertex));
|
|
||||||
|
|
||||||
if options.squeeze_through_under_bends {
|
if options.squeeze_through_under_bends {
|
||||||
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
||||||
|
|
@ -195,30 +195,34 @@ impl Navmesh {
|
||||||
);
|
);
|
||||||
|
|
||||||
if options.wrap_around_bands {
|
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(
|
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
||||||
&mut graph,
|
&mut graph,
|
||||||
&mut map,
|
&mut map,
|
||||||
trianvertex,
|
trianvertex,
|
||||||
bend.into(),
|
outward.into(),
|
||||||
);
|
);
|
||||||
gear = bend.into();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Some(first_bend) = gear.ref_(layout.drawing()).next_gear() {
|
} else if !gear.ref_(layout.drawing()).outer_gears().is_empty() {
|
||||||
let mut bend = first_bend;
|
let mut outwards = gear.ref_(layout.drawing()).outwards();
|
||||||
|
while let Some(outward) = outwards.walk_next(layout.drawing()) {
|
||||||
while let Some(next_bend) = gear.ref_(layout.drawing()).next_gear() {
|
if layout
|
||||||
bend = next_bend;
|
.drawing()
|
||||||
gear = bend.into();
|
.primitive(outward)
|
||||||
}
|
.outers()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.is_empty()
|
||||||
|
{
|
||||||
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
||||||
&mut graph,
|
&mut graph,
|
||||||
&mut map,
|
&mut map,
|
||||||
trianvertex,
|
trianvertex,
|
||||||
bend.into(),
|
outward.into(),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
Self::add_trianvertex_to_graph_and_map_as_binavnode(
|
||||||
&mut graph,
|
&mut graph,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue