// SPDX-FileCopyrightText: 2024 Topola contributors // // SPDX-License-Identifier: MIT use crate::graph::{GenericIndex, GetPetgraphIndex, MakeRef}; use super::{ band::{BandTermsegIndex, BandUid}, bend::LooseBendIndex, gear::{GearIndex, GetNextGear}, graph::PrimitiveIndex, loose::{GetPrevNextLoose, LooseIndex}, primitive::GetJoints, rules::AccessRules, Drawing, }; pub trait Collect { fn loose_band_uid(&self, start_loose: LooseIndex) -> BandUid; fn bend_bow(&self, bend: LooseBendIndex) -> Vec; fn bend_outer_bows(&self, bend: LooseBendIndex) -> Vec; fn wraparounded_bows(&self, around: GearIndex) -> Vec; } impl Collect for Drawing { fn loose_band_uid(&self, start_loose: LooseIndex) -> BandUid { BandUid::from(( self.loose_band_first_seg(start_loose), self.loose_band_last_seg(start_loose), )) } fn bend_bow(&self, bend: LooseBendIndex) -> Vec { let mut v: Vec = vec![]; v.push(bend.into()); let joints = self.primitive(bend).joints(); v.push(joints.0.into()); v.push(joints.1.into()); if let Some(seg0) = self.primitive(joints.0).seg() { v.push(seg0.into()); } if let Some(seg1) = self.primitive(joints.1).seg() { v.push(seg1.into()); } v } fn bend_outer_bows(&self, bend: LooseBendIndex) -> Vec { 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 { 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 } } trait CollectPrivate { fn loose_band_first_seg(&self, start_loose: LooseIndex) -> BandTermsegIndex; fn loose_band_last_seg(&self, start_loose: LooseIndex) -> BandTermsegIndex; } impl CollectPrivate for Drawing { fn loose_band_first_seg(&self, start_loose: LooseIndex) -> BandTermsegIndex { if let LooseIndex::LoneSeg(seg) = start_loose { return BandTermsegIndex::Straight(seg); } let mut loose = start_loose; let mut prev = None; loop { if let Some(next_loose) = self.loose(loose).prev_loose(prev) { prev = Some(loose); loose = next_loose; } else { return BandTermsegIndex::Bended(GenericIndex::new(loose.petgraph_index())); } } } fn loose_band_last_seg(&self, start_loose: LooseIndex) -> BandTermsegIndex { if let LooseIndex::LoneSeg(seg) = start_loose { return BandTermsegIndex::Straight(seg); } let mut loose = start_loose; let mut next = None; loop { if let Some(prev_loose) = self.loose(loose).next_loose(next) { next = Some(loose); loose = prev_loose; } else { return BandTermsegIndex::Bended(GenericIndex::new(loose.petgraph_index())); } } } }