remesh 0.0.5

Isotropic remeshing library
Documentation
// SPDX-License-Identifier: MIT OR Apache-2.0
// Copyright (c) 2025 lacklustr@protonmail.com https://github.com/eadf

use crate::common::macros::integrity_assert;
use crate::corner_table::CornerIndex;
use crate::corner_table::CornerTable;

impl<const ENABLE_UNSAFE: bool> CornerTable<ENABLE_UNSAFE> {
    /// Get an iterator over all corner indices pivoting around a vertex, starting from a known corner.
    /// `start_corner` will be the first corner of the fan.
    pub(crate) fn iter_ccw_swing(
        &self,
        start_corner: CornerIndex,
    ) -> CornerCcwIterator<'_, ENABLE_UNSAFE> {
        integrity_assert!(start_corner.is_valid());
        CornerCcwIterator {
            mesh: self,
            start_corner,
            current_corner: Some(start_corner),
            first_iteration: true,
        }
    }
}

/// Iterator that yields corners around a vertex in CCW order.
///
/// # Returns
/// Yields corners starting with `start_corner`, then continuing CCW
/// until returning to the start position (which is NOT yielded a second time).
pub(crate) struct CornerCcwIterator<'a, const ENABLE_UNSAFE: bool> {
    mesh: &'a CornerTable<ENABLE_UNSAFE>,
    start_corner: CornerIndex,
    current_corner: Option<CornerIndex>,
    first_iteration: bool,
}

impl<'a, const ENABLE_UNSAFE: bool> Iterator for CornerCcwIterator<'a, ENABLE_UNSAFE> {
    type Item = CornerIndex;

    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        let current = self.current_corner?;

        if !self.first_iteration && current == self.start_corner {
            // Completed the loop
            return None;
        }

        self.first_iteration = false;

        // Get the next corner for the subsequent iteration
        let next_corner = self.mesh.swing_ccw(current);
        integrity_assert!(next_corner.is_valid());

        self.current_corner = Some(next_corner);

        Some(current)
    }
}