From c4cd211b7c901b5a7a6998fb2c93907418b47dbb Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 27 Sep 2024 19:35:37 +0200 Subject: [PATCH] Remove loop check in bit vec iter --- libraries/path-bool/src/lib.rs | 1 - libraries/path-bool/src/util/grid.rs | 8 +- libraries/path-bool/src/util/rtree.rs | 190 -------------------------- 3 files changed, 2 insertions(+), 197 deletions(-) delete mode 100644 libraries/path-bool/src/util/rtree.rs diff --git a/libraries/path-bool/src/lib.rs b/libraries/path-bool/src/lib.rs index 99049cc7f..3dc576893 100644 --- a/libraries/path-bool/src/lib.rs +++ b/libraries/path-bool/src/lib.rs @@ -12,7 +12,6 @@ mod util { pub(crate) mod grid; pub(crate) mod math; pub(crate) mod quad_tree; - pub(crate) mod rtree; } mod path; #[cfg(test)] diff --git a/libraries/path-bool/src/util/grid.rs b/libraries/path-bool/src/util/grid.rs index 01d9711ce..347015349 100644 --- a/libraries/path-bool/src/util/grid.rs +++ b/libraries/path-bool/src/util/grid.rs @@ -49,17 +49,14 @@ impl Grid { } } -use std::mem::size_of; - pub struct BitVec { data: Vec, - capacity: usize, } impl BitVec { pub fn new(capacity: usize) -> Self { let num_words = (capacity + 63) / 64; - BitVec { data: vec![0; num_words], capacity } + BitVec { data: vec![0; num_words] } } pub fn set(&mut self, index: usize) { @@ -91,7 +88,7 @@ impl<'a> Iterator for BitVecIterator<'a> { type Item = usize; fn next(&mut self) -> Option { - while self.word_index < self.bit_vec.data.len() { + loop { if self.current_word == 0 { self.word_index += 1; if self.word_index == self.bit_vec.data.len() { @@ -107,7 +104,6 @@ impl<'a> Iterator for BitVecIterator<'a> { return Some(result); } - None } } diff --git a/libraries/path-bool/src/util/rtree.rs b/libraries/path-bool/src/util/rtree.rs deleted file mode 100644 index e98084bd2..000000000 --- a/libraries/path-bool/src/util/rtree.rs +++ /dev/null @@ -1,190 +0,0 @@ -use glam::DVec2; -use std::cmp::Ordering; - -use crate::aabb::{bounding_boxes_overlap, merge_bounding_boxes, Aabb}; - -pub(crate) struct RTreeNode { - bbox: Aabb, - children: Vec, - entries: Vec<(Aabb, usize)>, - is_leaf: bool, -} - -impl RTreeNode { - fn new(is_leaf: bool) -> Self { - RTreeNode { - bbox: Aabb::default(), - children: Vec::new(), - entries: Vec::new(), - is_leaf, - } - } - - fn insert(&mut self, bbox: Aabb, index: usize, max_entries: usize) { - if self.is_leaf { - self.entries.push((bbox, index)); - self.update_bbox(&bbox); - if self.entries.len() > max_entries { - self.split(max_entries); - } - } else { - let best_child = self.choose_subtree(&bbox); - self.children[best_child].insert(bbox, index, max_entries); - self.update_bbox(&self.children[best_child].bbox.clone()); - } - } - - fn choose_subtree(&self, bbox: &Aabb) -> usize { - self.children - .iter() - .enumerate() - .min_by(|(_, a), (_, b)| { - let area_increase_a = area(&merge_bounding_boxes(&a.bbox, bbox)) - area(&a.bbox); - let area_increase_b = area(&merge_bounding_boxes(&b.bbox, bbox)) - area(&b.bbox); - area_increase_a.partial_cmp(&area_increase_b).unwrap_or(Ordering::Equal) - }) - .map(|(index, _)| index) - .unwrap_or(0) - } - - fn update_bbox(&mut self, bbox: &Aabb) { - self.bbox = merge_bounding_boxes(&self.bbox, bbox); - } - - fn split(&mut self, max_entries: usize) { - if !self.is_leaf { - return; // We only split leaf nodes in this implementation - } - - let mut new_node = RTreeNode::new(true); - let (seed1, seed2) = self.pick_seeds(); - - new_node.entries.push(self.entries[seed2].clone()); - new_node.update_bbox(&new_node.entries[0].0.clone()); - - self.bbox = self.entries[seed1].0; - - let mut group1 = vec![self.entries[seed1].clone()]; - let mut group2 = vec![self.entries[seed2].clone()]; - - let remaining_entries: Vec<_> = self.entries.iter().enumerate().filter(|&(i, _)| i != seed1 && i != seed2).map(|(_, e)| e.clone()).collect(); - - for entry in remaining_entries { - if group1.len() >= max_entries / 2 { - group2.push(entry); - } else if group2.len() >= max_entries / 2 { - group1.push(entry); - } else { - let increase1 = area(&merge_bounding_boxes(&self.bbox, &entry.0)) - area(&self.bbox); - let increase2 = area(&merge_bounding_boxes(&new_node.bbox, &entry.0)) - area(&new_node.bbox); - if increase1 < increase2 { - group1.push(entry); - self.update_bbox(&entry.0); - } else { - group2.push(entry); - new_node.update_bbox(&entry.0); - } - } - } - - self.entries = group1; - new_node.entries = group2; - - // Create a new parent if this was the root - if self.children.is_empty() { - let mut new_parent = RTreeNode::new(false); - new_parent.children.push(std::mem::replace(self, RTreeNode::new(true))); - new_parent.children.push(new_node); - new_parent.update_bbox(&new_parent.children[0].bbox.clone()); - new_parent.update_bbox(&new_parent.children[1].bbox.clone()); - *self = new_parent; - } else { - self.children.push(new_node); - } - } - - fn pick_seeds(&self) -> (usize, usize) { - let mut max_waste = f64::NEG_INFINITY; - let mut seeds = (0, 1); - - for i in 0..self.entries.len() { - for j in (i + 1)..self.entries.len() { - let combined_bbox = merge_bounding_boxes(&self.entries[i].0, &self.entries[j].0); - let waste = area(&combined_bbox) - area(&self.entries[i].0) - area(&self.entries[j].0); - - if waste > max_waste { - max_waste = waste; - seeds = (i, j); - } - } - } - - seeds - } - - fn pick_next(&self, other: &RTreeNode) -> usize { - self.entries - .iter() - .enumerate() - .max_by(|(_, a), (_, b)| { - let diff_a = area(&merge_bounding_boxes(&self.bbox, &a.0)) - area(&merge_bounding_boxes(&other.bbox, &a.0)); - let diff_b = area(&merge_bounding_boxes(&self.bbox, &b.0)) - area(&merge_bounding_boxes(&other.bbox, &b.0)); - diff_a.partial_cmp(&diff_b).unwrap_or(Ordering::Equal) - }) - .map(|(index, _)| index) - .unwrap_or(0) - } - - fn assign_entry(&mut self, index: usize, other: &mut RTreeNode) { - let entry = self.entries.remove(index); - other.entries.push(entry); - other.update_bbox(&entry.0); - } - - fn query(&self, search_bbox: &Aabb, results: &mut Vec) { - if !bounding_boxes_overlap(&self.bbox, search_bbox) { - return; - } - - if self.is_leaf { - for (bbox, index) in &self.entries { - if bounding_boxes_overlap(bbox, search_bbox) { - results.push(*index); - } - } - } else { - for child in &self.children { - child.query(search_bbox, results); - } - } - } -} - -pub(crate) struct RTree { - root: RTreeNode, - max_entries: usize, -} - -impl RTree { - pub(crate) fn new(max_entries: usize) -> Self { - RTree { - root: RTreeNode::new(true), - max_entries, - } - } - - pub(crate) fn insert(&mut self, bbox: Aabb, index: usize) { - self.root.insert(bbox, index, self.max_entries); - } - - pub(crate) fn query(&self, search_bbox: &Aabb) -> Vec { - let mut results = Vec::new(); - self.root.query(search_bbox, &mut results); - results - } -} - -// Helper function to calculate the area of an Aabb -fn area(bbox: &Aabb) -> f64 { - (bbox.right() - bbox.left()) * (bbox.bottom() - bbox.top()) -}