From e7ed17d39f7d93b5f9771cfbf3391014f3bb8b7f Mon Sep 17 00:00:00 2001 From: hakolao Date: Wed, 19 Jan 2022 18:14:50 +0200 Subject: [PATCH 1/4] Non-recursive alternative --- sandbox/src/main.rs | 1 + sandbox/src/object/deformation_utils.rs | 91 ++++++++++++++----------- 2 files changed, 52 insertions(+), 40 deletions(-) diff --git a/sandbox/src/main.rs b/sandbox/src/main.rs index 31c532e..dd5d036 100644 --- a/sandbox/src/main.rs +++ b/sandbox/src/main.rs @@ -1,3 +1,4 @@ +#![feature(map_first_last)] #![allow( clippy::needless_question_mark, clippy::too_many_arguments, diff --git a/sandbox/src/object/deformation_utils.rs b/sandbox/src/object/deformation_utils.rs index a96f6bc..e64ce7d 100644 --- a/sandbox/src/object/deformation_utils.rs +++ b/sandbox/src/object/deformation_utils.rs @@ -1,54 +1,65 @@ +use std::collections::BTreeSet; + use cgmath::Vector2; -fn depth_first_label_mark( +/* +list nodes_to_visit = {root}; +while( nodes_to_visit isn't empty ) { + currentnode = nodes_to_visit.take_first(); + nodes_to_visit.prepend( currentnode.children ); + //do something +} + */ +fn mark_depth_first_label( bitmap: &[f64], labels: &mut Vec, width: u32, height: u32, - x: i32, - y: i32, + x_in: i32, + y_in: i32, current_label: u32, min_x: &mut i32, min_y: &mut i32, max_x: &mut i32, max_y: &mut i32, ) { - if x < 0 || x == width as i32 || y < 0 || y == height as i32 { - return; - }; - let index = (y * width as i32 + x) as usize; - if labels[index] != 0 || bitmap[index] == 0.0 { - return; - } - labels[index] = current_label; - // Find maxes - *min_x = (*min_x).min(x); - *min_y = (*min_y).min(y); - *max_x = (*max_x).max(x); - *max_y = (*max_y).max(y); - for (neigh_x, neigh_y) in &[ - (x - 1, y - 1), - (x, y - 1), - (x + 1, y - 1), - (x + 1, y), - (x + 1, y + 1), - (x, y + 1), - (x - 1, y + 1), - (x - 1, y), - ] { - depth_first_label_mark( - bitmap, - labels, - width, - height, - *neigh_x, - *neigh_y, - current_label, - min_x, - min_y, - max_x, - max_y, - ); + let mut to_visit = BTreeSet::new(); + to_visit.insert((x_in, y_in)); + while !to_visit.is_empty() { + // Get current pixel + let (x, y) = to_visit.pop_first().unwrap(); + // Track min maxes + *min_x = (*min_x).min(x); + *min_y = (*min_y).min(y); + *max_x = (*max_x).max(x); + *max_y = (*max_y).max(y); + // Label it + let index = (y * width as i32 + x) as usize; + labels[index] = current_label; + // Add neighbors for labeling & inspection if necessary + for &(neigh_x, neigh_y) in &[ + (x - 1, y - 1), + (x, y - 1), + (x + 1, y - 1), + (x + 1, y), + (x + 1, y + 1), + (x, y + 1), + (x - 1, y + 1), + (x - 1, y), + ] { + // The pixel should be labeled and is within bounds. (It wasn't labeled yet, and object isn't empty there) + if neigh_x >= 0 + && neigh_x < width as i32 + && neigh_y >= 0 + && neigh_y < height as i32 + && !to_visit.contains(&(neigh_x, neigh_y)) + { + let neigh_index = (neigh_y * width as i32 + neigh_x) as usize; + if labels[neigh_index] == 0 && bitmap[neigh_index] != 0.0 { + to_visit.insert((neigh_x, neigh_y)); + } + }; + } } } @@ -72,7 +83,7 @@ pub fn extract_connected_components_from_bitmap( let index = (y * width + x) as usize; if labels[index] == 0 && bitmap[index] == 1.0 { current_label += 1; - depth_first_label_mark( + mark_depth_first_label( bitmap, &mut labels, width, From 5db5df4fe5f090b168ead1850a3b480dd1e99ba9 Mon Sep 17 00:00:00 2001 From: hakolao Date: Wed, 19 Jan 2022 18:21:31 +0200 Subject: [PATCH 2/4] Add better doc of the dfs search --- sandbox/src/object/deformation_utils.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/sandbox/src/object/deformation_utils.rs b/sandbox/src/object/deformation_utils.rs index e64ce7d..a812b5b 100644 --- a/sandbox/src/object/deformation_utils.rs +++ b/sandbox/src/object/deformation_utils.rs @@ -2,15 +2,9 @@ use std::collections::BTreeSet; use cgmath::Vector2; -/* -list nodes_to_visit = {root}; -while( nodes_to_visit isn't empty ) { - currentnode = nodes_to_visit.take_first(); - nodes_to_visit.prepend( currentnode.children ); - //do something -} - */ -fn mark_depth_first_label( +/// Performs a depth first search of connected pixels and labels them with current label. +/// Tracks the connected pixel mins & maxes for bitmap formation purposes later. +fn mark_connected_pixels_depth_first( bitmap: &[f64], labels: &mut Vec, width: u32, @@ -83,7 +77,7 @@ pub fn extract_connected_components_from_bitmap( let index = (y * width + x) as usize; if labels[index] == 0 && bitmap[index] == 1.0 { current_label += 1; - mark_depth_first_label( + mark_connected_pixels_depth_first( bitmap, &mut labels, width, From 8ab430504588332d6ff83700d5dec446d7deb13f Mon Sep 17 00:00:00 2001 From: hakolao Date: Wed, 19 Jan 2022 18:23:50 +0200 Subject: [PATCH 3/4] Ensure CI runs on nightly --- .github/workflows/tests.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cc258c5..eff966b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,6 +41,10 @@ jobs: with: args: install python3 --params "/InstallAllUsers" - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true - name: Build run: cargo build --verbose --release - name: Run tests @@ -50,6 +54,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true - name: init run: sudo apt-get install build-essential git python cmake libvulkan-dev vulkan-utils libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev - name: Build @@ -61,6 +69,10 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true - name: Build run: cargo build --verbose --release - name: Run tests From 46c022b53517d7e0ed1ad741fae7e652dff42f70 Mon Sep 17 00:00:00 2001 From: hakolao Date: Wed, 19 Jan 2022 18:25:42 +0200 Subject: [PATCH 4/4] Rename ci tasks --- .github/workflows/tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index eff966b..5241c91 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,7 @@ jobs: - name: cargo clippy run: cargo clippy --all-targets -- -D warnings - windows_stable: + windows_nightly: runs-on: windows-latest steps: - name: Ninja Install @@ -50,7 +50,7 @@ jobs: - name: Run tests run: cargo test --verbose --release - linux_stable: + linux_nightly: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -65,7 +65,7 @@ jobs: - name: Run tests run: cargo test --verbose --release - macos_stable: + macos_nightly: runs-on: macos-latest steps: - uses: actions/checkout@v2