1use either::Either;
2use fool::prelude::*;
3use std::cmp;
4use std::marker::PhantomData;
5use std::mem;
6use std::ops::{Add, Deref, DerefMut, Mul};
7
8use crate::geometry::alias::{ScaledFaceNormal, VertexPosition};
9use crate::geometry::convert::AsPosition;
10use crate::geometry::Geometry;
11use crate::graph::container::{Bind, Consistent, Reborrow, ReborrowMut};
12use crate::graph::geometry::{FaceCentroid, FaceNormal};
13use crate::graph::mutation::alias::Mutable;
14use crate::graph::mutation::face::{
15 self, FaceBridgeCache, FaceExtrudeCache, FaceInsertCache, FacePokeCache, FaceRemoveCache,
16 FaceSplitCache,
17};
18use crate::graph::mutation::{Mutate, Mutation};
19use crate::graph::payload::{ArcPayload, EdgePayload, FacePayload, Payload, VertexPayload};
20use crate::graph::storage::convert::{AsStorage, AsStorageMut};
21use crate::graph::storage::{ArcKey, FaceKey, Storage, VertexKey};
22use crate::graph::view::convert::{FromKeyedSource, IntoKeyedSource, IntoView};
23use crate::graph::view::{ArcNeighborhood, ArcView, OrphanArcView, OrphanVertexView, VertexView};
24use crate::graph::{GraphError, OptionExt, ResultExt, Selector};
25
26use Selector::ByIndex;
27
28pub struct FaceView<M, G>
33where
34 M: Reborrow,
35 M::Target: AsStorage<FacePayload<G>>,
36 G: Geometry,
37{
38 key: FaceKey,
39 storage: M,
40 phantom: PhantomData<G>,
41}
42
43impl<M, G> FaceView<M, G>
45where
46 M: Reborrow,
47 M::Target: AsStorage<FacePayload<G>>,
48 G: Geometry,
49{
50 #[allow(dead_code)]
53 pub(in crate::graph) fn bind<T, N>(self, storage: N) -> FaceView<<M as Bind<T, N>>::Output, G>
54 where
55 T: Payload,
56 M: Bind<T, N>,
57 M::Output: Reborrow,
58 <M::Output as Reborrow>::Target: AsStorage<FacePayload<G>>,
59 N: AsStorage<T>,
60 {
61 let (key, origin) = self.into_keyed_source();
62 FaceView::from_keyed_source_unchecked((key, origin.bind(storage)))
63 }
64}
65
66impl<'a, M, G> FaceView<&'a mut M, G>
67where
68 M: 'a + AsStorage<FacePayload<G>> + AsStorageMut<FacePayload<G>>,
69 G: 'a + Geometry,
70{
71 pub fn into_orphan(self) -> OrphanFaceView<'a, G> {
73 let (key, storage) = self.into_keyed_source();
74 (key, storage).into_view().unwrap()
75 }
76
77 pub fn into_ref(self) -> FaceView<&'a M, G> {
110 let (key, storage) = self.into_keyed_source();
111 (key, &*storage).into_view().unwrap()
112 }
113
114 pub fn with_ref<T, K, F>(self, f: F) -> Either<Result<T, GraphError>, Self>
123 where
124 T: FromKeyedSource<(K, &'a mut M)>,
125 F: FnOnce(FaceView<&M, G>) -> Option<K>,
126 {
127 if let Some(key) = f(self.interior_reborrow()) {
128 let (_, storage) = self.into_keyed_source();
129 Either::Left(
130 T::from_keyed_source((key, storage)).ok_or_else(|| GraphError::TopologyNotFound),
131 )
132 }
133 else {
134 Either::Right(self)
135 }
136 }
137}
138
139impl<M, G> FaceView<M, G>
140where
141 M: Reborrow,
142 M::Target: AsStorage<FacePayload<G>>,
143 G: Geometry,
144{
145 pub fn key(&self) -> FaceKey {
147 self.key
148 }
149
150 fn from_keyed_source_unchecked(source: (FaceKey, M)) -> Self {
151 let (key, storage) = source;
152 FaceView {
153 key,
154 storage,
155 phantom: PhantomData,
156 }
157 }
158
159 fn interior_reborrow(&self) -> FaceView<&M::Target, G> {
160 let key = self.key;
161 let storage = self.storage.reborrow();
162 FaceView::from_keyed_source_unchecked((key, storage))
163 }
164}
165
166impl<M, G> FaceView<M, G>
167where
168 M: Reborrow + ReborrowMut,
169 M::Target: AsStorage<FacePayload<G>>,
170 G: Geometry,
171{
172 fn interior_reborrow_mut(&mut self) -> FaceView<&mut M::Target, G> {
173 let key = self.key;
174 let storage = self.storage.reborrow_mut();
175 FaceView::from_keyed_source_unchecked((key, storage))
176 }
177}
178
179impl<M, G> FaceView<M, G>
181where
182 M: Reborrow,
183 M::Target: AsStorage<ArcPayload<G>> + AsStorage<FacePayload<G>>,
184 G: Geometry,
185{
186 pub(in crate::graph) fn reachable_arc(&self) -> Option<ArcView<&M::Target, G>> {
187 let key = self.arc;
188 let storage = self.storage.reborrow();
189 (key, storage).into_view()
190 }
191
192 pub(in crate::graph) fn into_reachable_arc(self) -> Option<ArcView<M, G>> {
193 let key = self.arc;
194 let (_, storage) = self.into_keyed_source();
195 (key, storage).into_view()
196 }
197
198 pub(in crate::graph) fn reachable_interior_arcs(
199 &self,
200 ) -> impl Clone + Iterator<Item = ArcView<&M::Target, G>> {
201 ArcCirculator::from(self.interior_reborrow())
202 }
203
204 pub(in crate::graph) fn reachable_neighboring_faces(
205 &self,
206 ) -> impl Clone + Iterator<Item = FaceView<&M::Target, G>> {
207 FaceCirculator::from(ArcCirculator::from(self.interior_reborrow()))
208 }
209
210 pub(in crate::graph) fn reachable_arity(&self) -> usize {
211 self.reachable_interior_arcs().count()
212 }
213}
214
215impl<M, G> FaceView<M, G>
216where
217 M: Reborrow,
218 M::Target: AsStorage<ArcPayload<G>> + AsStorage<FacePayload<G>> + Consistent,
219 G: Geometry,
220{
221 pub fn into_interior_path(self) -> InteriorPathView<M, G> {
223 let key = self.arc().key();
224 let (_, storage) = self.into_keyed_source();
225 (key, storage).into_view().expect_consistent()
226 }
227
228 pub fn into_arc(self) -> ArcView<M, G> {
230 self.into_reachable_arc().expect_consistent()
231 }
232
233 pub fn interior_path(&self) -> InteriorPathView<&M::Target, G> {
235 let key = self.arc().key();
236 let storage = self.storage.reborrow();
237 (key, storage).into_view().expect_consistent()
238 }
239
240 pub fn arc(&self) -> ArcView<&M::Target, G> {
242 self.reachable_arc().expect_consistent()
243 }
244
245 pub fn interior_arcs(&self) -> impl Clone + Iterator<Item = ArcView<&M::Target, G>> {
247 self.reachable_interior_arcs()
248 }
249
250 pub fn neighboring_faces(&self) -> impl Clone + Iterator<Item = FaceView<&M::Target, G>> {
252 self.reachable_neighboring_faces()
253 }
254
255 pub fn arity(&self) -> usize {
258 self.reachable_arity()
259 }
260}
261
262impl<M, G> FaceView<M, G>
264where
265 M: Reborrow,
266 M::Target: AsStorage<ArcPayload<G>> + AsStorage<FacePayload<G>> + AsStorage<VertexPayload<G>>,
267 G: Geometry,
268{
269 pub(in crate::graph) fn reachable_vertices(
270 &self,
271 ) -> impl Clone + Iterator<Item = VertexView<&M::Target, G>> {
272 VertexCirculator::from(ArcCirculator::from(self.interior_reborrow()))
273 }
274}
275
276impl<M, G> FaceView<M, G>
277where
278 M: Reborrow,
279 M::Target: AsStorage<ArcPayload<G>>
280 + AsStorage<FacePayload<G>>
281 + AsStorage<VertexPayload<G>>
282 + Consistent,
283 G: Geometry,
284{
285 pub fn neighborhood(&self) -> FaceNeighborhood {
286 FaceNeighborhood::from(self.interior_reborrow())
287 }
288
289 pub fn vertices(&self) -> impl Clone + Iterator<Item = VertexView<&M::Target, G>> {
291 self.reachable_vertices()
292 }
293}
294
295impl<M, G> FaceView<M, G>
297where
298 M: Reborrow + ReborrowMut,
299 M::Target: AsStorage<ArcPayload<G>> + AsStorageMut<ArcPayload<G>> + AsStorage<FacePayload<G>>,
300 G: Geometry,
301{
302 pub(in crate::graph) fn reachable_interior_orphan_arcs(
303 &mut self,
304 ) -> impl Iterator<Item = OrphanArcView<G>> {
305 ArcCirculator::from(self.interior_reborrow_mut())
306 }
307}
308
309impl<M, G> FaceView<M, G>
310where
311 M: Reborrow + ReborrowMut,
312 M::Target: AsStorage<ArcPayload<G>>
313 + AsStorageMut<ArcPayload<G>>
314 + AsStorage<FacePayload<G>>
315 + Consistent,
316 G: Geometry,
317{
318 pub fn interior_orphan_arcs(&mut self) -> impl Iterator<Item = OrphanArcView<G>> {
321 self.reachable_interior_orphan_arcs()
322 }
323}
324
325impl<M, G> FaceView<M, G>
327where
328 M: Reborrow + ReborrowMut,
329 M::Target: AsStorage<ArcPayload<G>> + AsStorage<FacePayload<G>> + AsStorageMut<FacePayload<G>>,
330 G: Geometry,
331{
332 pub(in crate::graph) fn reachable_neighboring_orphan_faces(
333 &mut self,
334 ) -> impl Iterator<Item = OrphanFaceView<G>> {
335 FaceCirculator::from(ArcCirculator::from(self.interior_reborrow_mut()))
336 }
337}
338
339impl<M, G> FaceView<M, G>
340where
341 M: Reborrow + ReborrowMut,
342 M::Target: AsStorage<ArcPayload<G>>
343 + AsStorage<FacePayload<G>>
344 + AsStorageMut<FacePayload<G>>
345 + Consistent,
346 G: Geometry,
347{
348 pub fn neighboring_orphan_faces(&mut self) -> impl Iterator<Item = OrphanFaceView<G>> {
350 self.reachable_neighboring_orphan_faces()
351 }
352}
353
354impl<M, G> FaceView<M, G>
356where
357 M: Reborrow + ReborrowMut,
358 M::Target: AsStorage<ArcPayload<G>>
359 + AsStorage<FacePayload<G>>
360 + AsStorage<VertexPayload<G>>
361 + AsStorageMut<VertexPayload<G>>,
362 G: Geometry,
363{
364 pub(in crate::graph) fn reachable_orphan_vertices(
365 &mut self,
366 ) -> impl Iterator<Item = OrphanVertexView<G>> {
367 VertexCirculator::from(ArcCirculator::from(self.interior_reborrow_mut()))
368 }
369}
370
371impl<M, G> FaceView<M, G>
372where
373 M: Reborrow + ReborrowMut,
374 M::Target: AsStorage<ArcPayload<G>>
375 + AsStorage<FacePayload<G>>
376 + AsStorage<VertexPayload<G>>
377 + AsStorageMut<VertexPayload<G>>
378 + Consistent,
379 G: Geometry,
380{
381 pub fn orphan_vertices(&mut self) -> impl Iterator<Item = OrphanVertexView<G>> {
383 self.reachable_orphan_vertices()
384 }
385}
386
387impl<'a, M, G> FaceView<&'a mut M, G>
388where
389 M: AsStorage<ArcPayload<G>>
390 + AsStorage<EdgePayload<G>>
391 + AsStorage<FacePayload<G>>
392 + AsStorage<VertexPayload<G>>
393 + Default
394 + Mutable<G>,
395 G: 'a + Geometry,
396{
397 pub fn split(
443 self,
444 source: Selector<VertexKey>,
445 destination: Selector<VertexKey>,
446 ) -> Result<ArcView<&'a mut M, G>, GraphError> {
447 let source = source.key_or_else(|index| {
448 self.vertices()
449 .nth(index)
450 .ok_or_else(|| GraphError::TopologyNotFound)
451 .map(|vertex| vertex.key())
452 })?;
453 let destination = destination.key_or_else(|index| {
454 self.vertices()
455 .nth(index)
456 .ok_or_else(|| GraphError::TopologyNotFound)
457 .map(|vertex| vertex.key())
458 })?;
459 let (abc, storage) = self.into_keyed_source();
460 let cache = FaceSplitCache::snapshot(&storage, abc, source, destination)?;
461 Mutation::replace(storage, Default::default())
462 .commit_with(move |mutation| face::split_with_cache(mutation, cache))
463 .map(|(storage, arc)| (arc, storage).into_view().expect_consistent())
464 }
465
466 pub fn merge(self, destination: Selector<FaceKey>) -> Result<Self, GraphError> {
518 let destination = destination.key_or_else(|index| {
519 self.neighboring_faces()
520 .nth(index)
521 .ok_or_else(|| GraphError::TopologyNotFound)
522 .map(|face| face.key())
523 })?;
524 let ab = self
525 .interior_arcs()
526 .find(|arc| match arc.opposite_arc().face() {
527 Some(face) => face.key() == destination,
528 _ => false,
529 })
530 .map(|arc| arc.key())
531 .ok_or_else(|| GraphError::TopologyNotFound)?;
532 let geometry = self.geometry.clone();
533 let (_, storage) = self.into_keyed_source();
534 Ok(ArcView::from_keyed_source((ab, storage))
535 .expect_consistent()
536 .remove()
537 .into_outgoing_arc()
538 .into_interior_path()
539 .get_or_insert_face_with(|| geometry))
540 }
541
542 pub fn bridge(self, destination: FaceKey) -> Result<(), GraphError> {
553 let (source, storage) = self.into_keyed_source();
554 let cache = FaceBridgeCache::snapshot(&storage, source, destination)?;
555 Mutation::replace(storage, Default::default())
556 .commit_with(move |mutation| face::bridge_with_cache(mutation, cache))
557 .map(|_| ())
558 }
559
560 pub fn triangulate(self) -> Self {
565 let mut face = self;
566 while face.arity() > 3 {
567 face = face
568 .split(ByIndex(0), ByIndex(2))
569 .expect_consistent()
570 .into_face()
571 .expect_consistent();
572 }
573 face
574 }
575
576 pub fn poke_with<F>(self, f: F) -> VertexView<&'a mut M, G>
584 where
585 F: FnOnce() -> G::Vertex,
586 {
587 (move || {
588 let (abc, storage) = self.into_keyed_source();
589 let cache = FacePokeCache::snapshot(&storage, abc, f())?;
590 Mutation::replace(storage, Default::default())
591 .commit_with(move |mutation| face::poke_with_cache(mutation, cache))
592 .map(|(storage, vertex)| (vertex, storage).into_view().expect_consistent())
593 })()
594 .expect_consistent()
595 }
596
597 pub fn poke_at_centroid(self) -> VertexView<&'a mut M, G>
633 where
634 G: FaceCentroid<Centroid = <G as Geometry>::Vertex>,
635 {
636 let centroid = self.centroid();
637 self.poke_with(move || centroid)
638 }
639
640 pub fn extrude<T>(self, distance: T) -> Result<FaceView<&'a mut M, G>, GraphError>
641 where
642 G: FaceNormal,
643 G::Normal: Mul<T>,
644 G::Vertex: AsPosition,
645 ScaledFaceNormal<G, T>: Clone,
646 VertexPosition<G>: Add<ScaledFaceNormal<G, T>, Output = VertexPosition<G>> + Clone,
647 {
648 let (abc, storage) = self.into_keyed_source();
649 let cache = FaceExtrudeCache::snapshot(&storage, abc, distance)?;
650 Mutation::replace(storage, Default::default())
651 .commit_with(move |mutation| face::extrude_with_cache(mutation, cache))
652 .map(|(storage, face)| (face, storage).into_view().expect_consistent())
653 }
654
655 pub fn remove(self) -> InteriorPathView<&'a mut M, G> {
659 (move || {
660 let (abc, storage) = self.into_keyed_source();
661 let cache = FaceRemoveCache::snapshot(&storage, abc)?;
662 Mutation::replace(storage, Default::default())
663 .commit_with(move |mutation| face::remove_with_cache(mutation, cache))
664 .map(|(storage, face)| (face.arc, storage).into_view().expect_consistent())
665 })()
666 .expect_consistent()
667 }
668}
669
670impl<M, G> FaceView<M, G>
671where
672 M: Reborrow,
673 M::Target: AsStorage<ArcPayload<G>>
674 + AsStorage<FacePayload<G>>
675 + AsStorage<VertexPayload<G>>
676 + Consistent,
677 G: FaceCentroid + Geometry,
678{
679 pub fn centroid(&self) -> G::Centroid {
680 G::centroid(self.interior_reborrow()).expect_consistent()
681 }
682}
683
684impl<M, G> FaceView<M, G>
685where
686 M: Reborrow,
687 M::Target: AsStorage<ArcPayload<G>>
688 + AsStorage<FacePayload<G>>
689 + AsStorage<VertexPayload<G>>
690 + Consistent,
691 G: FaceNormal + Geometry,
692{
693 pub fn normal(&self) -> G::Normal {
694 G::normal(self.interior_reborrow()).expect_consistent()
695 }
696}
697
698impl<M, G> Clone for FaceView<M, G>
699where
700 M: Clone + Reborrow,
701 M::Target: AsStorage<FacePayload<G>>,
702 G: Geometry,
703{
704 fn clone(&self) -> Self {
705 FaceView {
706 storage: self.storage.clone(),
707 key: self.key,
708 phantom: PhantomData,
709 }
710 }
711}
712
713impl<M, G> Copy for FaceView<M, G>
714where
715 M: Copy + Reborrow,
716 M::Target: AsStorage<FacePayload<G>>,
717 G: Geometry,
718{
719}
720
721impl<M, G> Deref for FaceView<M, G>
722where
723 M: Reborrow,
724 M::Target: AsStorage<FacePayload<G>>,
725 G: Geometry,
726{
727 type Target = FacePayload<G>;
728
729 fn deref(&self) -> &Self::Target {
730 self.storage.reborrow().as_storage().get(&self.key).unwrap()
731 }
732}
733
734impl<M, G> DerefMut for FaceView<M, G>
735where
736 M: Reborrow + ReborrowMut,
737 M::Target: AsStorage<FacePayload<G>> + AsStorageMut<FacePayload<G>>,
738 G: Geometry,
739{
740 fn deref_mut(&mut self) -> &mut Self::Target {
741 self.storage
742 .reborrow_mut()
743 .as_storage_mut()
744 .get_mut(&self.key)
745 .unwrap()
746 }
747}
748
749impl<M, G> FromKeyedSource<(FaceKey, M)> for FaceView<M, G>
750where
751 M: Reborrow,
752 M::Target: AsStorage<FacePayload<G>>,
753 G: Geometry,
754{
755 fn from_keyed_source(source: (FaceKey, M)) -> Option<Self> {
756 let (key, storage) = source;
757 storage
758 .reborrow()
759 .as_storage()
760 .contains_key(&key)
761 .some(FaceView::from_keyed_source_unchecked((key, storage)))
762 }
763}
764
765impl<M, G> IntoKeyedSource<(FaceKey, M)> for FaceView<M, G>
766where
767 M: Reborrow,
768 M::Target: AsStorage<FacePayload<G>>,
769 G: Geometry,
770{
771 fn into_keyed_source(self) -> (FaceKey, M) {
772 let FaceView { key, storage, .. } = self;
773 (key, storage)
774 }
775}
776
777pub struct OrphanFaceView<'a, G>
782where
783 G: 'a + Geometry,
784{
785 key: FaceKey,
786 face: &'a mut FacePayload<G>,
787}
788
789impl<'a, G> OrphanFaceView<'a, G>
790where
791 G: 'a + Geometry,
792{
793 pub fn key(&self) -> FaceKey {
794 self.key
795 }
796}
797
798impl<'a, G> Deref for OrphanFaceView<'a, G>
799where
800 G: 'a + Geometry,
801{
802 type Target = FacePayload<G>;
803
804 fn deref(&self) -> &Self::Target {
805 &*self.face
806 }
807}
808
809impl<'a, G> DerefMut for OrphanFaceView<'a, G>
810where
811 G: 'a + Geometry,
812{
813 fn deref_mut(&mut self) -> &mut Self::Target {
814 self.face
815 }
816}
817
818impl<'a, M, G> FromKeyedSource<(FaceKey, &'a mut M)> for OrphanFaceView<'a, G>
819where
820 M: AsStorage<FacePayload<G>> + AsStorageMut<FacePayload<G>>,
821 G: 'a + Geometry,
822{
823 fn from_keyed_source(source: (FaceKey, &'a mut M)) -> Option<Self> {
824 let (key, storage) = source;
825 storage
826 .as_storage_mut()
827 .get_mut(&key)
828 .map(|face| OrphanFaceView { key, face })
829 }
830}
831
832impl<'a, G> FromKeyedSource<(FaceKey, &'a mut FacePayload<G>)> for OrphanFaceView<'a, G>
833where
834 G: 'a + Geometry,
835{
836 fn from_keyed_source(source: (FaceKey, &'a mut FacePayload<G>)) -> Option<Self> {
837 let (key, face) = source;
838 Some(OrphanFaceView { key, face })
839 }
840}
841
842#[derive(Clone, Debug)]
843pub struct FaceNeighborhood {
844 key: FaceKey,
845 arcs: Vec<ArcNeighborhood>,
846}
847
848impl FaceNeighborhood {
849 pub fn key(&self) -> FaceKey {
850 self.key
851 }
852
853 pub fn interior_arcs(&self) -> &[ArcNeighborhood] {
854 self.arcs.as_slice()
855 }
856}
857
858impl<M, G> From<FaceView<M, G>> for FaceNeighborhood
859where
860 M: Reborrow,
861 M::Target: AsStorage<ArcPayload<G>>
862 + AsStorage<FacePayload<G>>
863 + AsStorage<VertexPayload<G>>
864 + Consistent,
865 G: Geometry,
866{
867 fn from(face: FaceView<M, G>) -> Self {
868 FaceNeighborhood {
869 key: face.key,
870 arcs: face
871 .reachable_interior_arcs()
872 .map(|arc| arc.neighborhood())
873 .collect(),
874 }
875 }
876}
877
878pub struct InteriorPathView<M, G>
889where
890 M: Reborrow,
891 M::Target: AsStorage<ArcPayload<G>> + Consistent,
892 G: Geometry,
893{
894 storage: M,
895 arc: ArcKey,
896 face: Option<FaceKey>,
897 phantom: PhantomData<G>,
898}
899
900impl<'a, M, G> InteriorPathView<&'a mut M, G>
901where
902 M: AsStorage<ArcPayload<G>> + Consistent,
903 G: 'a + Geometry,
904{
905 pub fn into_ref(self) -> InteriorPathView<&'a M, G> {
910 let (arc, face, storage) = self.into_keyed_source();
911 InteriorPathView::from_keyed_source_unchecked((arc, face, &*storage))
912 }
913
914 pub fn with_ref<T, K, F>(self, f: F) -> Either<Result<T, GraphError>, Self>
923 where
924 T: FromKeyedSource<(K, &'a mut M)>,
925 F: FnOnce(InteriorPathView<&M, G>) -> Option<K>,
926 {
927 if let Some(key) = f(self.interior_reborrow()) {
928 let (_, _, storage) = self.into_keyed_source();
929 Either::Left(
930 T::from_keyed_source((key, storage)).ok_or_else(|| GraphError::TopologyNotFound),
931 )
932 }
933 else {
934 Either::Right(self)
935 }
936 }
937}
938
939impl<M, G> InteriorPathView<M, G>
940where
941 M: Reborrow,
942 M::Target: AsStorage<ArcPayload<G>> + Consistent,
943 G: Geometry,
944{
945 fn from_keyed_source_unchecked(source: (ArcKey, Option<FaceKey>, M)) -> Self {
946 let (arc, face, storage) = source;
947 InteriorPathView {
948 storage,
949 arc,
950 face,
951 phantom: PhantomData,
952 }
953 }
954
955 pub fn arity(&self) -> usize {
958 self.arcs().count()
959 }
960
961 pub fn arcs(&self) -> impl Clone + Iterator<Item = ArcView<&M::Target, G>> {
963 ArcCirculator::from(self.interior_reborrow())
964 }
965
966 fn interior_reborrow(&self) -> InteriorPathView<&M::Target, G> {
967 let arc = self.arc;
968 let face = self.face;
969 let storage = self.storage.reborrow();
970 InteriorPathView::from_keyed_source_unchecked((arc, face, storage))
971 }
972}
973
974impl<M, G> InteriorPathView<M, G>
975where
976 M: Reborrow,
977 M::Target: AsStorage<ArcPayload<G>> + AsStorage<VertexPayload<G>> + Consistent,
978 G: Geometry,
979{
980 pub fn into_arc(self) -> ArcView<M, G> {
982 let (arc, _, storage) = self.into_keyed_source();
983 (arc, storage).into_view().expect_consistent()
984 }
985
986 pub fn arc(&self) -> ArcView<&M::Target, G> {
988 let arc = self.arc;
989 let storage = self.storage.reborrow();
990 (arc, storage).into_view().expect_consistent()
991 }
992
993 pub fn distance(
996 &self,
997 source: Selector<VertexKey>,
998 destination: Selector<VertexKey>,
999 ) -> Result<usize, GraphError> {
1000 let arity = self.arity();
1001 let select = |selector: Selector<_>| {
1002 selector
1003 .index_or_else(|key| {
1004 self.vertices()
1005 .map(|vertex| vertex.key())
1006 .enumerate()
1007 .find(|(_, a)| *a == key)
1008 .map(|(index, _)| index)
1009 .ok_or_else(|| GraphError::TopologyNotFound)
1010 })
1011 .and_then(|index| {
1012 if index >= arity {
1013 Err(GraphError::TopologyNotFound)
1014 }
1015 else {
1016 Ok(index)
1017 }
1018 })
1019 };
1020 let source = select(source)? as isize;
1021 let destination = select(destination)? as isize;
1022 let difference = (source - destination).abs() as usize;
1023 Ok(cmp::min(difference, arity - difference))
1024 }
1025
1026 pub fn vertices(&self) -> impl Clone + Iterator<Item = VertexView<&M::Target, G>> {
1028 VertexCirculator::from(ArcCirculator::from(self.interior_reborrow()))
1029 }
1030}
1031
1032impl<M, G> InteriorPathView<M, G>
1033where
1034 M: Reborrow,
1035 M::Target: AsStorage<ArcPayload<G>> + AsStorage<FacePayload<G>> + Consistent,
1036 G: Geometry,
1037{
1038 pub fn into_face(self) -> Option<FaceView<M, G>> {
1042 let (_, face, storage) = self.into_keyed_source();
1043 if let Some(face) = face {
1044 Some((face, storage).into_view().expect_consistent())
1045 }
1046 else {
1047 None
1048 }
1049 }
1050
1051 pub fn face(&self) -> Option<FaceView<&M::Target, G>> {
1055 if let Some(face) = self.face {
1056 let storage = self.storage.reborrow();
1057 Some((face, storage).into_view().expect_consistent())
1058 }
1059 else {
1060 None
1061 }
1062 }
1063}
1064
1065impl<'a, M, G> InteriorPathView<&'a mut M, G>
1066where
1067 M: AsStorage<VertexPayload<G>>
1068 + AsStorage<ArcPayload<G>>
1069 + AsStorage<FacePayload<G>>
1070 + Default
1071 + Mutable<G>,
1072 G: 'a + Geometry,
1073{
1074 pub fn get_or_insert_face(self) -> FaceView<&'a mut M, G> {
1079 self.get_or_insert_face_with(|| Default::default())
1080 }
1081
1082 pub fn get_or_insert_face_with<F>(self, f: F) -> FaceView<&'a mut M, G>
1090 where
1091 F: FnOnce() -> G::Face,
1092 {
1093 if let Some(face) = self.face.clone().take() {
1094 let (_, _, storage) = self.into_keyed_source();
1095 (face, storage).into_view().expect_consistent()
1096 }
1097 else {
1098 (move || {
1099 let vertices = self
1100 .vertices()
1101 .map(|vertex| vertex.key())
1102 .collect::<Vec<_>>();
1103 let (_, _, storage) = self.into_keyed_source();
1104 let cache =
1105 FaceInsertCache::snapshot(&storage, &vertices, (Default::default(), f()))?;
1106 Mutation::replace(storage, Default::default())
1107 .commit_with(move |mutation| mutation.insert_face_with_cache(cache))
1108 .map(|(storage, face)| (face, storage).into_view().expect_consistent())
1109 })()
1110 .expect_consistent()
1111 }
1112 }
1113}
1114
1115impl<M, G> FromKeyedSource<(ArcKey, M)> for InteriorPathView<M, G>
1116where
1117 M: Reborrow,
1118 M::Target: AsStorage<ArcPayload<G>> + Consistent,
1119 G: Geometry,
1120{
1121 fn from_keyed_source(source: (ArcKey, M)) -> Option<Self> {
1122 let (key, storage) = source;
1128 if let Some(arc) = storage.reborrow().as_storage().get(&key) {
1129 let face = arc.face.clone();
1130 Some(InteriorPathView {
1131 storage,
1132 arc: key,
1133 face,
1134 phantom: PhantomData,
1135 })
1136 }
1137 else {
1138 None
1139 }
1140 }
1141}
1142
1143impl<M, G> IntoKeyedSource<(ArcKey, Option<FaceKey>, M)> for InteriorPathView<M, G>
1144where
1145 M: Reborrow,
1146 M::Target: AsStorage<ArcPayload<G>> + Consistent,
1147 G: Geometry,
1148{
1149 fn into_keyed_source(self) -> (ArcKey, Option<FaceKey>, M) {
1150 let InteriorPathView {
1151 storage, arc, face, ..
1152 } = self;
1153 (arc, face, storage)
1154 }
1155}
1156
1157struct VertexCirculator<M, G>
1158where
1159 M: Reborrow,
1160 M::Target: AsStorage<ArcPayload<G>>,
1161 G: Geometry,
1162{
1163 input: ArcCirculator<M, G>,
1164}
1165
1166impl<M, G> VertexCirculator<M, G>
1167where
1168 M: Reborrow,
1169 M::Target: AsStorage<ArcPayload<G>>,
1170 G: Geometry,
1171{
1172 fn next(&mut self) -> Option<VertexKey> {
1173 let ab = self.input.next();
1174 ab.map(|ab| {
1175 let (_, b) = ab.into();
1176 b
1177 })
1178 }
1179}
1180
1181impl<M, G> Clone for VertexCirculator<M, G>
1182where
1183 M: Clone + Reborrow,
1184 M::Target: AsStorage<ArcPayload<G>>,
1185 G: Geometry,
1186{
1187 fn clone(&self) -> Self {
1188 VertexCirculator {
1189 input: self.input.clone(),
1190 }
1191 }
1192}
1193
1194impl<M, G> From<ArcCirculator<M, G>> for VertexCirculator<M, G>
1195where
1196 M: Reborrow,
1197 M::Target: AsStorage<ArcPayload<G>>,
1198 G: Geometry,
1199{
1200 fn from(input: ArcCirculator<M, G>) -> Self {
1201 VertexCirculator { input }
1202 }
1203}
1204
1205impl<'a, M, G> Iterator for VertexCirculator<&'a M, G>
1208where
1209 M: 'a + AsStorage<ArcPayload<G>> + AsStorage<VertexPayload<G>>,
1210 G: 'a + Geometry,
1211{
1212 type Item = VertexView<&'a M, G>;
1213
1214 fn next(&mut self) -> Option<Self::Item> {
1215 VertexCirculator::next(self).and_then(|key| (key, self.input.storage).into_view())
1216 }
1217}
1218
1219impl<'a, M, G> Iterator for VertexCirculator<&'a mut M, G>
1222where
1223 M: 'a + AsStorage<ArcPayload<G>> + AsStorage<VertexPayload<G>> + AsStorageMut<VertexPayload<G>>,
1224 G: 'a + Geometry,
1225{
1226 type Item = OrphanVertexView<'a, G>;
1227
1228 fn next(&mut self) -> Option<Self::Item> {
1229 VertexCirculator::next(self).and_then(|key| {
1230 (key, unsafe {
1231 mem::transmute::<&'_ mut Storage<VertexPayload<G>>, &'a mut Storage<VertexPayload<G>>>(
1232 self.input.storage.as_storage_mut(),
1233 )
1234 })
1235 .into_view()
1236 })
1237 }
1238}
1239
1240struct ArcCirculator<M, G>
1241where
1242 M: Reborrow,
1243 M::Target: AsStorage<ArcPayload<G>>,
1244 G: Geometry,
1245{
1246 storage: M,
1247 arc: Option<ArcKey>,
1248 breadcrumb: Option<ArcKey>,
1249 phantom: PhantomData<G>,
1250}
1251
1252impl<M, G> ArcCirculator<M, G>
1253where
1254 M: Reborrow,
1255 M::Target: AsStorage<ArcPayload<G>>,
1256 G: Geometry,
1257{
1258 fn next(&mut self) -> Option<ArcKey> {
1259 self.arc.and_then(|arc| {
1260 let next = self
1261 .storage
1262 .reborrow()
1263 .as_storage()
1264 .get(&arc)
1265 .and_then(|arc| arc.next);
1266 self.breadcrumb.map(|_| {
1267 if self.breadcrumb == next {
1268 self.breadcrumb = None;
1269 }
1270 else {
1271 self.arc = next;
1272 }
1273 arc
1274 })
1275 })
1276 }
1277}
1278
1279impl<M, G> Clone for ArcCirculator<M, G>
1280where
1281 M: Clone + Reborrow,
1282 M::Target: AsStorage<ArcPayload<G>>,
1283 G: Geometry,
1284{
1285 fn clone(&self) -> Self {
1286 ArcCirculator {
1287 storage: self.storage.clone(),
1288 arc: self.arc,
1289 breadcrumb: self.breadcrumb,
1290 phantom: PhantomData,
1291 }
1292 }
1293}
1294
1295impl<M, G> From<FaceView<M, G>> for ArcCirculator<M, G>
1296where
1297 M: Reborrow,
1298 M::Target: AsStorage<ArcPayload<G>> + AsStorage<FacePayload<G>>,
1299 G: Geometry,
1300{
1301 fn from(face: FaceView<M, G>) -> Self {
1302 let arc = face.arc;
1303 let (_, storage) = face.into_keyed_source();
1304 ArcCirculator {
1305 storage,
1306 arc: Some(arc),
1307 breadcrumb: Some(arc),
1308 phantom: PhantomData,
1309 }
1310 }
1311}
1312
1313impl<M, G> From<InteriorPathView<M, G>> for ArcCirculator<M, G>
1314where
1315 M: Reborrow,
1316 M::Target: AsStorage<ArcPayload<G>> + Consistent,
1317 G: Geometry,
1318{
1319 fn from(path: InteriorPathView<M, G>) -> Self {
1320 let (arc, _, storage) = path.into_keyed_source();
1321 ArcCirculator {
1322 storage,
1323 arc: Some(arc),
1324 breadcrumb: Some(arc),
1325 phantom: PhantomData,
1326 }
1327 }
1328}
1329
1330impl<'a, M, G> Iterator for ArcCirculator<&'a M, G>
1333where
1334 M: 'a + AsStorage<ArcPayload<G>>,
1335 G: 'a + Geometry,
1336{
1337 type Item = ArcView<&'a M, G>;
1338
1339 fn next(&mut self) -> Option<Self::Item> {
1340 ArcCirculator::next(self).and_then(|key| (key, self.storage).into_view())
1341 }
1342}
1343
1344impl<'a, M, G> Iterator for ArcCirculator<&'a mut M, G>
1347where
1348 M: 'a + AsStorage<ArcPayload<G>> + AsStorageMut<ArcPayload<G>>,
1349 G: 'a + Geometry,
1350{
1351 type Item = OrphanArcView<'a, G>;
1352
1353 fn next(&mut self) -> Option<Self::Item> {
1354 ArcCirculator::next(self).and_then(|key| {
1355 (key, unsafe {
1356 mem::transmute::<&'_ mut Storage<ArcPayload<G>>, &'a mut Storage<ArcPayload<G>>>(
1357 self.storage.as_storage_mut(),
1358 )
1359 })
1360 .into_view()
1361 })
1362 }
1363}
1364
1365struct FaceCirculator<M, G>
1366where
1367 M: Reborrow,
1368 M::Target: AsStorage<ArcPayload<G>>,
1369 G: Geometry,
1370{
1371 input: ArcCirculator<M, G>,
1372}
1373
1374impl<M, G> FaceCirculator<M, G>
1375where
1376 M: Reborrow,
1377 M::Target: AsStorage<ArcPayload<G>>,
1378 G: Geometry,
1379{
1380 fn next(&mut self) -> Option<FaceKey> {
1381 while let Some(ba) = self.input.next().map(|ab| ab.opposite()) {
1382 if let Some(abc) = self
1383 .input
1384 .storage
1385 .reborrow()
1386 .as_storage()
1387 .get(&ba)
1388 .and_then(|opposite| opposite.face)
1389 {
1390 return Some(abc);
1391 }
1392 else {
1393 continue;
1396 }
1397 }
1398 None
1399 }
1400}
1401
1402impl<M, G> Clone for FaceCirculator<M, G>
1403where
1404 M: Clone + Reborrow,
1405 M::Target: AsStorage<ArcPayload<G>>,
1406 G: Geometry,
1407{
1408 fn clone(&self) -> Self {
1409 FaceCirculator {
1410 input: self.input.clone(),
1411 }
1412 }
1413}
1414
1415impl<M, G> From<ArcCirculator<M, G>> for FaceCirculator<M, G>
1416where
1417 M: Reborrow,
1418 M::Target: AsStorage<ArcPayload<G>>,
1419 G: Geometry,
1420{
1421 fn from(input: ArcCirculator<M, G>) -> Self {
1422 FaceCirculator { input }
1423 }
1424}
1425
1426impl<'a, M, G> Iterator for FaceCirculator<&'a M, G>
1427where
1428 M: 'a + AsStorage<ArcPayload<G>> + AsStorage<FacePayload<G>>,
1429 G: 'a + Geometry,
1430{
1431 type Item = FaceView<&'a M, G>;
1432
1433 fn next(&mut self) -> Option<Self::Item> {
1434 FaceCirculator::next(self).and_then(|key| (key, self.input.storage).into_view())
1435 }
1436}
1437
1438impl<'a, M, G> Iterator for FaceCirculator<&'a mut M, G>
1439where
1440 M: 'a + AsStorage<ArcPayload<G>> + AsStorage<FacePayload<G>> + AsStorageMut<FacePayload<G>>,
1441 G: 'a + Geometry,
1442{
1443 type Item = OrphanFaceView<'a, G>;
1444
1445 fn next(&mut self) -> Option<Self::Item> {
1446 FaceCirculator::next(self).and_then(|key| {
1447 (key, unsafe {
1448 mem::transmute::<&'_ mut Storage<FacePayload<G>>, &'a mut Storage<FacePayload<G>>>(
1449 self.input.storage.as_storage_mut(),
1450 )
1451 })
1452 .into_view()
1453 })
1454 }
1455}
1456
1457#[cfg(test)]
1458mod tests {
1459 use nalgebra::{Point2, Point3};
1460
1461 use crate::graph::*;
1462 use crate::primitive::cube::Cube;
1463 use crate::primitive::generate::*;
1464 use crate::primitive::index::*;
1465 use crate::primitive::sphere::UvSphere;
1466 use crate::*;
1467
1468 #[test]
1469 fn circulate_over_arcs() {
1470 let graph = UvSphere::new(3, 2)
1471 .polygons_with_position() .collect::<MeshGraph<Point3<f32>>>();
1473 let face = graph.faces().nth(0).unwrap();
1474
1475 assert_eq!(3, face.interior_arcs().count());
1477 }
1478
1479 #[test]
1480 fn circulate_over_faces() {
1481 let graph = UvSphere::new(3, 2)
1482 .polygons_with_position() .collect::<MeshGraph<Point3<f32>>>();
1484 let face = graph.faces().nth(0).unwrap();
1485
1486 assert_eq!(3, face.neighboring_faces().count());
1488 }
1489
1490 #[test]
1491 fn remove_face() {
1492 let mut graph = UvSphere::new(3, 2)
1493 .polygons_with_position() .collect::<MeshGraph<Point3<f32>>>();
1495
1496 assert_eq!(6, graph.face_count());
1498
1499 let abc = graph.faces().nth(0).unwrap().key();
1501 {
1502 let face = graph.face_mut(abc).unwrap();
1503 assert_eq!(3, face.arity()); let path = face.remove().into_ref();
1506 assert_eq!(3, path.arity()); }
1508
1509 assert_eq!(5, graph.face_count());
1511 }
1512
1513 #[test]
1514 fn split_face() {
1515 let mut graph = MeshGraph::<Point2<f32>>::from_raw_buffers_with_arity(
1516 vec![0u32, 1, 2, 3],
1517 vec![(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)],
1518 4,
1519 )
1520 .unwrap();
1521 let abc = graph.faces().nth(0).unwrap().key();
1522 let arc = graph
1523 .face_mut(abc)
1524 .unwrap()
1525 .split(ByIndex(0), ByIndex(2))
1526 .unwrap()
1527 .into_ref();
1528
1529 assert!(arc.face().is_some());
1530 assert!(arc.opposite_arc().face().is_some());
1531 assert_eq!(4, graph.vertex_count());
1532 assert_eq!(10, graph.arc_count());
1533 assert_eq!(2, graph.face_count());
1534 }
1535
1536 #[test]
1537 fn extrude_face() {
1538 let mut graph = UvSphere::new(3, 2)
1539 .polygons_with_position() .collect::<MeshGraph<Point3<f32>>>();
1541 {
1542 let key = graph.faces().nth(0).unwrap().key();
1543 let face = graph
1544 .face_mut(key)
1545 .unwrap()
1546 .extrude(1.0)
1547 .unwrap()
1548 .into_ref();
1549
1550 assert_eq!(3, face.neighboring_faces().count());
1553 }
1554
1555 assert_eq!(8, graph.vertex_count());
1556 assert_eq!(30, graph.arc_count());
1560 assert_eq!(9, graph.face_count());
1564 }
1565
1566 #[test]
1567 fn merge_faces() {
1568 let mut graph = MeshGraph::<Point2<f32>>::from_raw_buffers_with_arity(
1570 vec![0u32, 1, 2, 3, 0, 3, 4, 5],
1571 vec![
1572 (0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0), ],
1579 4,
1580 )
1581 .unwrap();
1582
1583 assert_eq!(2, graph.face_count());
1585
1586 let abc = graph.faces().nth(0).unwrap().key();
1588 let def = graph.faces().nth(1).unwrap().key();
1589 graph.face_mut(abc).unwrap().merge(ByKey(def)).unwrap();
1590
1591 assert_eq!(1, graph.face_count());
1593 assert_eq!(6, graph.faces().nth(0).unwrap().arity());
1594 }
1595
1596 #[test]
1597 fn poke_face() {
1598 let mut graph = Cube::new()
1599 .polygons_with_position() .collect::<MeshGraph<Point3<f32>>>();
1601 let key = graph.faces().nth(0).unwrap().key();
1602 let vertex = graph.face_mut(key).unwrap().poke_at_centroid();
1603
1604 assert_eq!(4, vertex.neighboring_faces().count());
1606
1607 let face = vertex.into_outgoing_arc().into_face().unwrap();
1609
1610 assert_eq!(3, face.arity());
1611
1612 let vertex = face.poke_at_centroid();
1614
1615 assert_eq!(3, vertex.neighboring_faces().count());
1616 }
1617
1618 #[test]
1619 fn triangulate_mesh() {
1620 let (indices, vertices) = Cube::new()
1621 .polygons_with_position() .index_vertices(HashIndexer::default());
1623 let mut graph = MeshGraph::<Point3<f32>>::from_raw_buffers(indices, vertices).unwrap();
1624 graph.triangulate();
1625
1626 assert_eq!(8, graph.vertex_count());
1627 assert_eq!(36, graph.arc_count());
1628 assert_eq!(18, graph.edge_count());
1629 assert_eq!(12, graph.face_count());
1631 }
1632
1633 #[test]
1634 fn interior_path_distance() {
1635 let graph = MeshGraph::<Point2<f32>>::from_raw_buffers_with_arity(
1636 vec![0u32, 1, 2, 3],
1637 vec![(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)],
1638 4,
1639 )
1640 .unwrap();
1641 let face = graph.faces().nth(0).unwrap();
1642 let keys = face
1643 .vertices()
1644 .map(|vertex| vertex.key())
1645 .collect::<Vec<_>>();
1646 let path = face.into_interior_path();
1647 assert_eq!(2, path.distance(keys[0].into(), keys[2].into()).unwrap());
1648 assert_eq!(1, path.distance(keys[0].into(), keys[3].into()).unwrap());
1649 assert_eq!(0, path.distance(keys[0].into(), keys[0].into()).unwrap());
1650 }
1651}