<commit_before>use std::ops::Index;

use cgmath::Point3;

use crate::aabb::AABB;
use crate::pt_renderer::{Intersect, Ray};
use crate::stats;
use crate::triangle::RTTriangle;

const MAX_LEAF_SIZE: usize = 8;

#[allow(dead_code)]
#[derive(Clone, Copy)]
pub enum SplitMode {
    Object,
    Spatial,
    SAH,
}

pub struct BVHNode {
    aabb: AABB,
    pub start_i: usize,
    pub end_i: usize,
    left_child_i: Option<usize>,
    right_child_i: Option<usize>,
}

impl BVHNode {
    fn new(triangles: &Triangles) -> BVHNode {
        let start_i = triangles.start_i;
        let end_i = start_i + triangles.len();
        BVHNode {
            aabb: triangles.aabb.clone(),
            start_i,
            end_i,
            left_child_i: None,
            right_child_i: None,
        }
    }

    fn n_tris(&self) -> usize {
        self.end_i - self.start_i
    }

    pub fn is_leaf(&self) -> bool {
        self.left_child_i.is_none()
    }
}

impl Intersect<'_, f32> for BVHNode {
    fn intersect(&self, ray: &Ray) -> Option<f32> {
        self.aabb.intersect(ray)
    }
}

struct Triangles<'a> {
    triangles: &'a [RTTriangle],
    centers: &'a [Point3<f32>],
    indices: &'a mut [usize],
    aabb: AABB,
    /// Node contains indices [start_i, start_i + len) from the main indices array
    start_i: usize,
    /// Axis along which the indices have been sorted
    sorted_axis: usize,
}

impl<'a> Triangles<'a> {
    fn new(
        triangles: &'a [RTTriangle],
        centers: &'a [Point3<f32>],
        indices: &'a mut [usize],
        start_i: usize,
    ) -> Triangles<'a> {
        let mut aabb = AABB::empty();
        for &i in indices.iter() {
            let tri = &triangles[i];
            aabb.add_aabb(&tri.aabb());
        }
        Triangles {
            triangles,
            centers,
            indices,
            aabb,
            start_i,
            // Use bogus value since nothing has been sorted
            sorted_axis: 42,
        }
    }

    fn sort_longest_axis(&mut self) {
        let axis_i = self.aabb.longest_edge_i();
        self.sort(axis_i);
    }

    fn sort(&mut self, axis_i: usize) {
        // The indices are already sorted along the requested axis
        if axis_i == self.sorted_axis {
            return;
        }
        let centers = self.centers;
        self.indices.sort_unstable_by(|&i1, &i2| {
            let c1 = centers[i1][axis_i];
            let c2 = centers[i2][axis_i];
            c1.partial_cmp(&c2).unwrap()
        });
        self.sorted_axis = axis_i;
    }

    fn split(self, i: usize) -> (Triangles<'a>, Triangles<'a>) {
        let (i1, i2) = self.indices.split_at_mut(i);
        let mut node1 = Triangles::new(self.triangles, self.centers, i1, self.start_i);
        let mut node2 = Triangles::new(self.triangles, self.centers, i2, self.start_i + i);
        node1.sorted_axis = self.sorted_axis;
        node2.sorted_axis = self.sorted_axis;
        (node1, node2)
    }

    fn len(&self) -> usize {
        self.indices.len()
    }

    fn last(&self) -> &RTTriangle {
        let &i = self.indices.last().unwrap();
        &self.triangles[i]
    }
}

impl Index<usize> for Triangles<'_> {
    type Output = RTTriangle;

    fn index(&self, i: usize) -> &RTTriangle {
        let i = self.indices[i];
        &self.triangles[i]
    }
}

pub struct BVH {
    nodes: Vec<BVHNode>,
}

impl BVH {
    pub fn empty() -> BVH {
        BVH { nodes: Vec::new() }
    }

    pub fn build(triangles: &[RTTriangle], split_mode: SplitMode) -> (BVH, Vec<usize>) {
        stats::start_bvh();
        let centers: Vec<Point3<f32>> = triangles.iter().map(|ref tri| tri.center()).collect();
        let mut permutation: Vec<usize> = (0..triangles.len()).collect();
        let tris = Triangles::new(triangles, &centers, &mut permutation, 0);
        let mut nodes = Vec::with_capacity(f32::log2(triangles.len() as f32) as usize);
        nodes.push(BVHNode::new(&tris));
        let mut split_stack = vec![(0usize, tris)];

        while let Some((node_i, mut tris)) = split_stack.pop() {
            let mid_offset = match split_mode {
                SplitMode::Object => object_split(&mut tris),
                SplitMode::Spatial => spatial_split(&mut tris),
                SplitMode::SAH => sah_split(&mut tris),<commit_msg>Remove unused function<commit_after>use std::ops::Index;

use cgmath::Point3;

use crate::aabb::AABB;
use crate::pt_renderer::{Intersect, Ray};
use crate::stats;
use crate::triangle::RTTriangle;

const MAX_LEAF_SIZE: usize = 8;

#[allow(dead_code)]
#[derive(Clone, Copy)]
pub enum SplitMode {
    Object,
    Spatial,
    SAH,
}

pub struct BVHNode {
    aabb: AABB,
    pub start_i: usize,
    pub end_i: usize,
    left_child_i: Option<usize>,
    right_child_i: Option<usize>,
}

impl BVHNode {
    fn new(triangles: &Triangles) -> BVHNode {
        let start_i = triangles.start_i;
        let end_i = start_i + triangles.len();
        BVHNode {
            aabb: triangles.aabb.clone(),
            start_i,
            end_i,
            left_child_i: None,
            right_child_i: None,
        }
    }

    fn n_tris(&self) -> usize {
        self.end_i - self.start_i
    }

    pub fn is_leaf(&self) -> bool {
        self.left_child_i.is_none()
    }
}

impl Intersect<'_, f32> for BVHNode {
    fn intersect(&self, ray: &Ray) -> Option<f32> {
        self.aabb.intersect(ray)
    }
}

struct Triangles<'a> {
    triangles: &'a [RTTriangle],
    centers: &'a [Point3<f32>],
    indices: &'a mut [usize],
    aabb: AABB,
    /// Node contains indices [start_i, start_i + len) from the main indices array
    start_i: usize,
    /// Axis along which the indices have been sorted
    sorted_axis: usize,
}

impl<'a> Triangles<'a> {
    fn new(
        triangles: &'a [RTTriangle],
        centers: &'a [Point3<f32>],
        indices: &'a mut [usize],
        start_i: usize,
    ) -> Triangles<'a> {
        let mut aabb = AABB::empty();
        for &i in indices.iter() {
            let tri = &triangles[i];
            aabb.add_aabb(&tri.aabb());
        }
        Triangles {
            triangles,
            centers,
            indices,
            aabb,
            start_i,
            // Use bogus value since nothing has been sorted
            sorted_axis: 42,
        }
    }

    fn sort_longest_axis(&mut self) {
        let axis_i = self.aabb.longest_edge_i();
        self.sort(axis_i);
    }

    fn sort(&mut self, axis_i: usize) {
        // The indices are already sorted along the requested axis
        if axis_i == self.sorted_axis {
            return;
        }
        let centers = self.centers;
        self.indices.sort_unstable_by(|&i1, &i2| {
            let c1 = centers[i1][axis_i];
            let c2 = centers[i2][axis_i];
            c1.partial_cmp(&c2).unwrap()
        });
        self.sorted_axis = axis_i;
    }

    fn split(self, i: usize) -> (Triangles<'a>, Triangles<'a>) {
        let (i1, i2) = self.indices.split_at_mut(i);
        let mut node1 = Triangles::new(self.triangles, self.centers, i1, self.start_i);
        let mut node2 = Triangles::new(self.triangles, self.centers, i2, self.start_i + i);
        node1.sorted_axis = self.sorted_axis;
        node2.sorted_axis = self.sorted_axis;
        (node1, node2)
    }

    fn len(&self) -> usize {
        self.indices.len()
    }

    fn last(&self) -> &RTTriangle {
        let &i = self.indices.last().unwrap();
        &self.triangles[i]
    }
}

impl Index<usize> for Triangles<'_> {
    type Output = RTTriangle;

    fn index(&self, i: usize) -> &RTTriangle {
        let i = self.indices[i];
        &self.triangles[i]
    }
}

pub struct BVH {
    nodes: Vec<BVHNode>,
}

impl BVH {
    pub fn build(triangles: &[RTTriangle], split_mode: SplitMode) -> (BVH, Vec<usize>) {
        stats::start_bvh();
        let centers: Vec<Point3<f32>> = triangles.iter().map(|ref tri| tri.center()).collect();
        let mut permutation: Vec<usize> = (0..triangles.len()).collect();
        let tris = Triangles::new(triangles, &centers, &mut permutation, 0);
        let mut nodes = Vec::with_capacity(f32::log2(triangles.len() as f32) as usize);
        nodes.push(BVHNode::new(&tris));
        let mut split_stack = vec![(0usize, tris)];

        while let Some((node_i, mut tris)) = split_stack.pop() {
            let mid_offset = match split_mode {
                SplitMode::Object => object_split(&mut tris),
                SplitMode::Spatial => spatial_split(&mut tris),
                SplitMode::SAH => sah_split(&mut tris),
{'fraction_non_alphanumeric': 0.13936915887850468, 'fraction_numerical': 0.010046728971962618, 'mean_word_length': 2.200373831775701, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 68, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3453021', 'n_tokens_mistral': 3053, 'n_tokens_neox': 3019, 'n_words': 668}