diff --git a/StringArtRustImpl/processing.jpg b/StringArtRustImpl/processing.jpg index 130f113..a539a11 100644 Binary files a/StringArtRustImpl/processing.jpg and b/StringArtRustImpl/processing.jpg differ diff --git a/StringArtRustImpl/src/generators/greedy.rs b/StringArtRustImpl/src/generators/greedy.rs index 5534a0c..832a3f2 100644 --- a/StringArtRustImpl/src/generators/greedy.rs +++ b/StringArtRustImpl/src/generators/greedy.rs @@ -1,6 +1,6 @@ use crate::error::{Result, StringArtError}; use crate::state::app_state::StringArtState; -use crate::traits::StringArtGenerator; +use crate::traits::{LinePixelCache, StringArtGenerator}; use crate::utils::{ apply_line_darkness_from_pixels, calculate_line_score_from_pixels, }; diff --git a/StringArtRustImpl/src/rendering/image_renderer.rs b/StringArtRustImpl/src/rendering/image_renderer.rs index 07be5bd..41ac7ac 100644 --- a/StringArtRustImpl/src/rendering/image_renderer.rs +++ b/StringArtRustImpl/src/rendering/image_renderer.rs @@ -1,7 +1,7 @@ use crate::error::{Result, StringArtError}; use crate::state::app_state::StringArtState; use crate::traits::renderer::ImageRenderer as ImageRendererTrait; -use crate::utils::Coord; +use crate::traits::LinePixelCache; use image::{ImageBuffer, Rgb, RgbImage}; use std::sync::{Arc, RwLock}; @@ -17,9 +17,11 @@ impl ImageRenderer { } /// Draws a line on the image. - fn draw_line(&self, img: &mut RgbImage, start: Coord, end: Coord, color: (u8, u8, u8)) { + fn draw_line(&self, img: &mut RgbImage, start: usize, end: usize, color: (u8, u8, u8)) { let (width, height) = img.dimensions(); - let pixels = crate::utils::get_line_pixels(start, end); + + let pixel_cache = &self.state.read().unwrap().line_pixel_cache; + let pixels = pixel_cache.get(start, end); for pixel in pixels { if pixel.x >= 0 && pixel.x < width as i32 && pixel.y >= 0 && pixel.y < height as i32 { @@ -37,7 +39,6 @@ impl ImageRendererTrait for ImageRenderer { fn render_to_image(&self, line_color: Option<(u8, u8, u8)>) -> Result { let mut img; let color; - let nail_coords; let path; { let state = match self.state.try_read() { @@ -53,13 +54,10 @@ impl ImageRendererTrait for ImageRenderer { reason: "No path to render".to_string(), }); } - nail_coords = state.nail_coords.clone(); path = state.path.clone(); } for window in path.windows(2) { - let start = nail_coords[window[0]]; - let end = nail_coords[window[1]]; - self.draw_line(&mut img, start, end, color); + self.draw_line(&mut img, window[0], window[1], color); } Ok(img) diff --git a/StringArtRustImpl/src/state/app_state.rs b/StringArtRustImpl/src/state/app_state.rs index b357506..2831120 100644 --- a/StringArtRustImpl/src/state/app_state.rs +++ b/StringArtRustImpl/src/state/app_state.rs @@ -1,6 +1,7 @@ use crate::image_processing::EyeRegion; use crate::state::config::StringArtConfig; -use crate::utils::{Coord, LinePixelCache}; +use crate::state::cache::BasicLinePixelCache; +use crate::utils::{ Coord }; use ndarray::Array2; /// Holds the shared state for the string art generation process. @@ -14,7 +15,7 @@ pub struct StringArtState { pub eye_protection_mask: Array2, pub negative_space_mask: Array2, pub path: Vec, - pub line_pixel_cache: LinePixelCache, + pub line_pixel_cache: BasicLinePixelCache, } impl StringArtState { @@ -25,7 +26,7 @@ impl StringArtState { nail_coords: Vec, ) -> Self { let image_size = config.image_size; - let line_pixel_cache = LinePixelCache::new(&nail_coords); + let line_pixel_cache = BasicLinePixelCache::new(&nail_coords); Self { config, target_image, diff --git a/StringArtRustImpl/src/state/cache/basic_line_pixel_cache.rs b/StringArtRustImpl/src/state/cache/basic_line_pixel_cache.rs new file mode 100644 index 0000000..150006e --- /dev/null +++ b/StringArtRustImpl/src/state/cache/basic_line_pixel_cache.rs @@ -0,0 +1,81 @@ +use std::{collections::HashMap, sync::Mutex}; +use rayon::iter::{IntoParallelIterator, ParallelIterator}; +use crate::{traits::LinePixelCache, Coord}; + + +/// A cache for pre-calculating and storing the pixels for every possible line. +#[derive(Debug, Clone)] +pub struct BasicLinePixelCache { + cache: HashMap<(usize, usize), Vec>, +} + +impl BasicLinePixelCache { + /// Creates a new cache and pre-calculates all line pixels. + pub fn new(nail_coords: &[Coord]) -> Self { + let num_nails = nail_coords.len(); + let cache = Mutex::new(HashMap::new()); + + (0..num_nails).into_par_iter().for_each(|i| { + let local_results: Vec<((usize, usize), Vec)> = ((i + 1)..num_nails) + .map(|j| { + let start = nail_coords[i]; + let end = nail_coords[j]; + let pixels = Self::get_line_pixels(start, end); + ((i, j), pixels) + }) + .collect(); + + let mut cache_lock = cache.lock().unwrap(); + for (key, value) in local_results { + cache_lock.insert(key, value); + } + }); + let unwrapped_cache = cache.into_inner().unwrap(); + Self { cache: unwrapped_cache } + } + + /// Traverse line pixels using Bresenham's line algorithm and apply a closure. + /// This avoids allocating a vector for the pixels. + fn get_line_pixels(start: Coord, end: Coord) -> Vec { + let mut pixels = Vec::new(); + let dx = (end.x - start.x).abs(); + let dy = (end.y - start.y).abs(); + let sx = if start.x < end.x { 1 } else { -1 }; + let sy = if start.y < end.y { 1 } else { -1 }; + let mut err = dx - dy; + + let mut x = start.x; + let mut y = start.y; + + loop { + pixels.push(Coord::new(x, y)); + + if x == end.x && y == end.y { + break; + } + + let e2 = 2 * err; + if e2 > -dy { + err -= dy; + x += sx; + } + if e2 < dx { + err += dx; + y += sy; + } + } + pixels + } +} + + +impl LinePixelCache for BasicLinePixelCache { + fn get(&self, nail1: usize, nail2: usize) -> &Vec { + let key = if nail1 < nail2 { + (nail1, nail2) + } else { + (nail2, nail1) + }; + self.cache.get(&key).expect("Line pixels should be in cache") + } +} \ No newline at end of file diff --git a/StringArtRustImpl/src/state/cache/mod.rs b/StringArtRustImpl/src/state/cache/mod.rs new file mode 100644 index 0000000..221f29c --- /dev/null +++ b/StringArtRustImpl/src/state/cache/mod.rs @@ -0,0 +1,3 @@ +pub mod basic_line_pixel_cache; + +pub use self::basic_line_pixel_cache::BasicLinePixelCache; \ No newline at end of file diff --git a/StringArtRustImpl/src/state/mod.rs b/StringArtRustImpl/src/state/mod.rs index af5e216..c9185f5 100644 --- a/StringArtRustImpl/src/state/mod.rs +++ b/StringArtRustImpl/src/state/mod.rs @@ -1,2 +1,3 @@ pub mod app_state; pub mod config; +pub mod cache; \ No newline at end of file diff --git a/StringArtRustImpl/src/traits/line_pixel_cache.rs b/StringArtRustImpl/src/traits/line_pixel_cache.rs new file mode 100644 index 0000000..0a1461b --- /dev/null +++ b/StringArtRustImpl/src/traits/line_pixel_cache.rs @@ -0,0 +1,9 @@ +use crate::{ Coord }; + +/// Trait for string art path generators. +/// Implementations of this trait are responsible for calculating the optimal path +/// based on a given image and configuration. +pub trait LinePixelCache: Send + Sync { + /// Generate the string path using the specific algorithm. + fn get(&self, nail1: usize, nail2: usize) -> &Vec; +} diff --git a/StringArtRustImpl/src/traits/mod.rs b/StringArtRustImpl/src/traits/mod.rs index 4d18bd8..fd150c1 100644 --- a/StringArtRustImpl/src/traits/mod.rs +++ b/StringArtRustImpl/src/traits/mod.rs @@ -1,7 +1,9 @@ pub mod generator; pub mod mask; pub mod renderer; - +pub mod line_pixel_cache; + pub use self::generator::StringArtGenerator; pub use self::mask::MaskApplicator; pub use self::renderer::ImageRenderer; +pub use self::line_pixel_cache::LinePixelCache; diff --git a/StringArtRustImpl/src/utils.rs b/StringArtRustImpl/src/utils.rs index 8cc533b..e0e8db1 100644 --- a/StringArtRustImpl/src/utils.rs +++ b/StringArtRustImpl/src/utils.rs @@ -1,8 +1,5 @@ use ndarray::Array2; -use std::collections::HashMap; use std::f64::consts::PI; -use rayon::prelude::*; -use std::sync::Mutex; /// Represents a 2D coordinate #[derive(Debug, Clone, Copy, PartialEq)] @@ -17,48 +14,6 @@ impl Coord { } } -/// A cache for pre-calculating and storing the pixels for every possible line. -pub struct LinePixelCache { - cache: HashMap<(usize, usize), Vec>, -} - -impl LinePixelCache { - /// Creates a new cache and pre-calculates all line pixels. - pub fn new(nail_coords: &[Coord]) -> Self { - let num_nails = nail_coords.len(); - let cache = Mutex::new(HashMap::new()); - - (0..num_nails).into_par_iter().for_each(|i| { - let local_results: Vec<((usize, usize), Vec)> = ((i + 1)..num_nails) - .map(|j| { - let start = nail_coords[i]; - let end = nail_coords[j]; - let pixels = get_line_pixels(start, end); - ((i, j), pixels) - }) - .collect(); - - let mut cache_lock = cache.lock().unwrap(); - for (key, value) in local_results { - cache_lock.insert(key, value); - } - }); - let unwrapped_cache = cache.into_inner().unwrap(); - Self { cache: unwrapped_cache } - } - - /// Gets the pixels for a line between two nails. - /// Handles ordering of nail indices. - pub fn get(&self, nail1: usize, nail2: usize) -> &Vec { - let key = if nail1 < nail2 { - (nail1, nail2) - } else { - (nail2, nail1) - }; - self.cache.get(&key).expect("Line pixels should be in cache") - } -} - /// Calculate nail coordinates around a circle pub fn calculate_nail_coords(num_nails: usize, center: Coord, radius: i32) -> Vec { let mut coords = Vec::with_capacity(num_nails); @@ -72,81 +27,6 @@ pub fn calculate_nail_coords(num_nails: usize, center: Coord, radius: i32) -> Ve coords } - -/// Traverse line pixels using Bresenham's line algorithm and apply a closure. -/// This avoids allocating a vector for the pixels. -fn traverse_line_pixels(start: Coord, end: Coord, mut f: F) -where - F: FnMut(Coord), -{ - let dx = (end.x - start.x).abs(); - let dy = (end.y - start.y).abs(); - let sx = if start.x < end.x { 1 } else { -1 }; - let sy = if start.y < end.y { 1 } else { -1 }; - let mut err = dx - dy; - - let mut x = start.x; - let mut y = start.y; - - loop { - f(Coord::new(x, y)); - - if x == end.x && y == end.y { - break; - } - - let e2 = 2 * err; - if e2 > -dy { - err -= dy; - x += sx; - } - if e2 < dx { - err += dx; - y += sy; - } - } -} - -/// Get line pixels using Bresenham's line algorithm -/// Returns a vector of coordinates representing the pixels on the line -pub fn get_line_pixels(start: Coord, end: Coord) -> Vec { - let mut pixels = Vec::new(); - traverse_line_pixels(start, end, |pixel| { - pixels.push(pixel); - }); - pixels -} - -/// Calculate the average value along a line in an image -pub fn calculate_line_score( - image: &Array2, - start: Coord, - end: Coord, - protection_mask: Option<&Array2>, -) -> f32 { - let pixels = get_line_pixels(start, end); - calculate_line_score_from_pixels(image, &pixels, protection_mask, None, 0.0) -} - -/// Calculate line score with negative space awareness and eye enhancement -pub fn calculate_line_score_with_negative_space( - image: &Array2, - start: Coord, - end: Coord, - enhancement_mask: Option<&Array2>, - negative_space_mask: Option<&Array2>, - negative_space_penalty: f32, -) -> f32 { - let pixels = get_line_pixels(start, end); - calculate_line_score_from_pixels( - image, - &pixels, - enhancement_mask, - negative_space_mask, - negative_space_penalty, - ) -} - /// Calculate line score from a pre-computed list of pixels. pub fn calculate_line_score_from_pixels( image: &Array2, @@ -200,17 +80,6 @@ pub fn calculate_line_score_from_pixels( final_score.max(0.0) } -/// Apply line darkness to the residual image -pub fn apply_line_darkness( - residual: &mut Array2, - start: Coord, - end: Coord, - darkness: f32, -) { - let pixels = get_line_pixels(start, end); - apply_line_darkness_from_pixels(residual, &pixels, darkness); -} - /// Apply line darkness from a pre-computed list of pixels. pub fn apply_line_darkness_from_pixels( residual: &mut Array2, @@ -229,38 +98,3 @@ pub fn apply_line_darkness_from_pixels( } } } - -#[cfg(test)] -mod tests { - use super::*; - use ndarray::Array2; - - #[test] - fn test_calculate_nail_coords() { - let coords = calculate_nail_coords(4, Coord::new(100, 100), 50); - assert_eq!(coords.len(), 4); - - // Check first coordinate (0 degrees) - assert_eq!(coords[0], Coord::new(150, 100)); - } - - #[test] - fn test_get_line_pixels() { - let pixels = get_line_pixels(Coord::new(0, 0), Coord::new(2, 2)); - assert_eq!( - pixels, - vec![Coord::new(0, 0), Coord::new(1, 1), Coord::new(2, 2)] - ); - } - - #[test] - fn test_calculate_line_score() { - let mut image = Array2::::zeros((3, 3)); - image[[1, 1]] = 100.0; - - let score = calculate_line_score(&image, Coord::new(0, 0), Coord::new(2, 2), None); - - // Should be average of values along diagonal - assert!((score - 33.333_332).abs() < 1e-5); - } -} diff --git a/StringArtRustImpl/src/wasm.rs b/StringArtRustImpl/src/wasm.rs index 184ec5d..d1f4067 100644 --- a/StringArtRustImpl/src/wasm.rs +++ b/StringArtRustImpl/src/wasm.rs @@ -6,11 +6,8 @@ use crate::error::StringArtError; use crate::factories::generator_factory::StringArtFactory; use crate::generators::greedy::GreedyGenerator; -use crate::image_processing::EyeRegion; -use crate::rendering::image_renderer::ImageRenderer; use crate::state::{app_state::StringArtState, config::StringArtConfig}; use crate::traits::generator::StringArtGenerator; -use crate::utils::Coord; use js_sys::{Array, Function, Promise, Uint8Array}; use serde::{Deserialize, Serialize}; use std::sync::{Arc, RwLock}; @@ -131,7 +128,6 @@ pub struct ProgressInfo { #[wasm_bindgen] pub struct StringArtWasm { generator: Option, - renderer: Option, state: Arc>, config: WasmStringArtConfig, } @@ -146,13 +142,12 @@ impl StringArtWasm { let image_bytes: Vec = image_data.to_vec(); - let (generator, renderer, state) = + let (generator, _, state) = StringArtFactory::create_from_image_data(&image_bytes, app_config) .map_err(|e| JsValue::from_str(&format!("Failed to create generator: {}", e)))?; Ok(StringArtWasm { generator: Some(generator), - renderer: Some(renderer), state, config: wasm_config, }) diff --git a/StringArtRustImpl/string_art_output.png b/StringArtRustImpl/string_art_output.png index 2b98948..8c88cec 100644 Binary files a/StringArtRustImpl/string_art_output.png and b/StringArtRustImpl/string_art_output.png differ diff --git a/StringArtRustImpl/string_art_path.txt b/StringArtRustImpl/string_art_path.txt index e4648d3..51cea01 100644 --- a/StringArtRustImpl/string_art_path.txt +++ b/StringArtRustImpl/string_art_path.txt @@ -1 +1 @@ -0,1015,338,1089,438,1107,433,1061,391,994,384,1143,374,1062,432,1109,425,1112,419,1102,440,1105,435,1060,378,1143,366,981,1361,977,345,1013,339,1003,385,983,323,1088,439,1085,281,1082,285,957,1333,961,283,1082,294,956,1334,960,284,958,293,1133,383,1004,346,1012,378,1055,435,1072,375,1061,364,1144,373,974,352,987,400,1034,431,1042,383,1045,430,428,1000,349,1145,399,1070,283,1063,361,1146,398,1041,432,1033,340,1088,281,1083,397,1049,379,1053,284,1061,377,1096,439,1033,455,1043,430,1111,407,1146,344,1064,282,962,973,374,1134,292,1058,378,1054,454,1028,403,983,999,429,1010,382,1048,398,991,393,1147,341,1031,402,986,312,1112,406,1045,96,1046,401,1143,376,1071,280,1090,337,1018,1027,457,1041,386,1001,944,1365,929,1293,847,1237,791,1209,730,1187,423,1142,329,1152,339,1075,370,1084,366,1174,360,1147,372,1073,354,1175,359,1065,280,1067,435,1141,349,1121,235,1123,374,1063,368,974,947,942,1005,1011,1014,448,1054,471,1041,1035,430,998,945,1363,931,1381,924,1366,941,1006,383,1047,399,990,416,1045,454,1048,380,1052,286,1060,397,1056,378,1059,291,1125,498,1041,941,265,965,278,1072,373,1146,396,994,948,1362,933,1307,845,1266,897,1272,858,1309,843,1294,846,1287,849,1256,814,1290,896,1376,909,1277,801,1240,776,1248,848,1236,782,1240,766,1211,445,1015,1017,383,1009,1035,398,1002,385,1174,372,1172,337,1153,328,1164,322,1096,356,1068,343,1147,295,1081,1076,369,1080,339,1149,359,1063,363,1146,348,1111,287,945,296,952,955,958,962,266,940,1044,409,1142,379,1011,421,1044,1007,939,1051,397,993,385,991,414,1131,383,1036,499,1114,220,1121,291,1158,327,1154,336,1091,1095,357,1065,343,1079,490,1071,1080,1088,358,1110,431,996,383,1043,494,1070,1063,372,1061,374,1132,527,1059,375,1060,937,1052,382,1050,512,1135,290,1159,325,1170,523,1141,351,1176,326,1109,1094,336,1096,330,1150,337,1116,1120,334,1175,365,1085,362,1092,278,1153,295,953,991,974,391,998,355,1113,301,1118,235,1116,377,1059,493,942,1036,386,978,982,406,1027,1032,433,1027,469,1045,403,985,498,951,491,945,1309,837,1317,868,1295,884,1333,895,1292,849,1235,783,1223,808,1230,501,1032,458,1026,477,953,950,1354,948,478,1111,1082,369,1063,366,1077,354,1101,283,1062,935,258,1136,1140,436,1059,1056,382,1046,1048,1051,380,1019,461,1009,938,1417,931,1071,373,1160,323,1177,330,1122,228,1119,300,298,938,1404,943,492,1088,353,1065,934,259,968,499,949,255,941,1038,415,1121,1129,291,1120,352,1078,494,1058,392,1035,387,1000,413,1043,78,1025,460,1039,432,429,1067,305,1080,327,1156,292,1118,335,1099,318,1111,355,1071,378,1057,453,1050,519,1054,1052,378,1053,128,1049,382,1037,498,942,479,946,487,952,478,959,470,969,477,1020,1017,444,1031,388,977,976,390,1048,115,941,1413,1005,1001,425,1141,1120,226,1123,291,1128,448,1029,402,989,957,487,969,463,1038,433,1030,446,1210,1181,323,1163,1157,327,1155,293,1104,322,1182,1178,322,1111,1115,236,1074,370,1063,1060,377,1111,339,1148,340,1086,358,1064,361,1086,338,1125,347,1112,305,1117,1078,344,1074,353,1105,508,1031,943,497,952,484,974,462,1018,381,1011,454,970,431,1008,383,1044,1046,403,1001,999,390,943,417,1035,389,987,475,955,470,962,465,1017,405,1028,451,974,429,426,1011,3,985,486,947,1398,765,1243,779,1263,545,1169,1165,321,1183,1197,1207,1148,1140,380,1085,340,1147,267,1151,329,1153,1177,325,1158,326,1098,355,1146,346,1114,342,1147,1214,707,1203,1150,339,1079,1054,380,1047,382,1051,1053,534,1067,357,1093,181,1062,372,1075,1120,214,1021,378,1069,355,1097,335,1150,332,1176,342,1074,216,1116,294,1154,328,1127,641,1130,1136,1220,815,1229,507,1021,459,969,498,946,490,952,473,958,485,1014,1015,410,1027,455,1041,1043,82,1008,471,953,489,1119,323,1159,284,1098,351,1111,365,1063,371,1053,380,967,464,963,433,432,969,975,426,1044,408,981,464,1026,383,1046,400,1032,1034,1039,441,1032,443,963,469,1016,409,1041,383,1003,13,1013,466,961,984,406,970,416,989,461,1023,1022,103,1044,404,980,481,958,495,944,492,1105,350,1131,1224,1120,1062,377,1058,1123,218,1070,351,1139,1218,698,1352,854,1318,823,1301,866,1337,955,487,944,109,1044,98,923,1419,751,1412,942,497,1042,221,1112,248,1102,330,1079,370,1073,345,1146,349,1144,1216,1215,502,1006,448,1066,357,1090,1088,183,1103,1085,364,1134,1222,469,960,475,972,430,1039,413,975,461,985,430,1055,1056,380,1050,397,1055,250,1111,237,1067,223,1091,1090,294,1148,1212,1213,719,1380,754,1411,764,1250,527,1264,762,1255,776,1405,905,1384,943,210,1123,213,1057,377,1063,362,1073,314,1165,1163,292,1157,1155,1149,1194,1199,347,1146,343,1083,163,1087,358,1079,351,1103,295,297,1153,1188,318,1177,311,1062,371,1111,313,1167,1173,568,1085,176,1104,1224,1078,930,1010,383,1005,385,1036,384,1041,439,421,993,995,390,1001,1047,398,1049,380,1057,143,964,968,433,957,470,998,403,984,462,964,456,990,993,391,989,399,997,946,495,951,487,956,474,961,487,972,463,982,983,128,1076,1065,361,1074,339,1115,244,1113,347,1121,1117,336,1092,250,1186,321,1166,318,1085,195,1101,348,1134,291,1126,329,1150,334,1147,274,1154,283,1160,289,1136,353,1111,1109,379,1020,1021,446,991,454,972,415,444,1024,61,1030,400,985,457,1040,411,980,468,966,484,954,477,1239,1116,219,1187,235,1208,222,1184,239,1048,397,1052,379,1083,366,1085,275,1183,1182,224,1065,194,1188,211,1077,359,1086,364,1063,367,1076,296,1080,225,1177,1178,310,1114,1117,293,1143,349,1111,358,1089,350,1120,332,1092,600,1307,604,1107,173,1088,125,945,494,953,487,949,490,947,98,1000,1057,394,1030,37,990,987,402,1022,408,1046,402,985,480,1208,272,1186,220,1210,271,1155,273,1184,251,1081,1082,622,1102,1228,1119,291,1127,552,1073,396,1061,371,1072,372,1108,365,1072,1234,803,11,814,35,991,438,1035,396,1018,428,980,424,976,468,467,969,455,1006,52,1036,387,1032,440,972,449,1051,875,1338,689,1330,674,17,994,433,964,468,958,479,951,502,945,1403,743,1409,775,1431,1010,448,981,403,982,1359,715,1388,989,400,1004,1421,643,1111,307,1117,1232,1075,301,1152,334,1087,185,1190,210,1197,271,1190,172,126,1054,363,1120,241,1177,349,1099,162,1089,158,138,1021,419,1041,83,55,1003,88,42,988,150,1091,357,1094,1093,584,606,637,1439,1432,772,1438,646,673,39,98,108,124,1094,646,572,1273,754,742,731,1373,1367,866,1057,938,128,137,164,1194,218,1188,234,1213,1215,264,1177,277,1154,1181,240,1178,276,1146,1149,340,1114,1109,644,582,1105,1107,315,1150,1113,603,587,1420,750,530,571,710,720,1212,217,1195,156,149,1007,383,1002,1054,397,389,385,380,1058,375,1063,915,922,235,1185,221,1100,348,1112,666,651,528,1027,444,975,428,1043,1046,398,992,392,1006,464,971,405,1027,671,527,503,754,761,500,680,697,706,750,568,553,535,1246,1113,311,287,1091,351,1143,256,1066,541,650,1028,573,581,1312,1329,1116,1254,553,1026,459,478,482,955,476,1142,349,1090,327,1169,312,1154,334,1119,215,189,1189,217,22,34,101,2,173,31,819,836,784,1436,179,1190,167,171,35,702,753,517,513,944,496,762,1392,1397,776,841,867,880,890,914,16,3,622,610,1410,1399,1338,835,1318,1324,835,514,677,1365,1341,833,789,786,513,679,691,696,38,159,165,1193,665,45,51,87,95,1066,932,878,75,59,813,792,13,676,518,751,558,649,751,529,867,921,75,77,79,1195,162,36,650,1278,1288,1291,1306,1332,842,1295,801,797,499,838,781,1404,1336,1296,593,640,642,585,1021,461,969,465,467,1003,943,495,949,492,799,1296,1266,1257,775,767,1439,175,214,1421,1430,184,774,111,1195,141,1100,1105,1260,757,501,787,1220,1121,331,1075,350,360,1086,363,1072,376,399,1035,506,753,1402,619,631,633,635,1,174,980,420,425,1037,600,638,1008,1040,384,1038,173,19,941,43,850,862,1058,226,233,1217,259,1177,282,320,1184,236,1162,323,1161,288,1177,253,242,1176,283,319,1097,352,1137,288,1105,640,586,748,667,536,723,729,531,668,43,154,1198,209,196,1424,888,917,517,525,672,1016,482,485,963,457,413,412,976,210,1423,201,1190,1192,166,35,2,722,716,1351,1346,954,487,490,767,845,497,798,1302,1410,1418,217,1400,1304,877,1050,1049,1047,939,207,1199,110,1301,1418,752,508,511,923,928,866,651,1432,180,1334,1409,217,893,528,669,40,157,975,448,450,1060,374,360,1215,270,268,260,1216,1142,282,1183,223,258,970,418,1044,406,412,1002,469,472,962,486,456,987,440,985,1374,1391,218,1371,745,670,1150,291,1003,411,1057,397,1035,433,1029,444,447,1013,626,623,930,504,836,513,921,676,712,743,530,735,1380,588,1091,1291,1419,215,1299,1089,142,147,46,632,881,919,514,895,911,556,532,725,1334,224,1178,252,1183,1185,195,204,211,1422,999,998,433,1031,56,140,1201,298,1177,266,1160,325,1131,296,1113,330,1148,341,1146,1145,279,1152,694,44,152,1199,77,1262,1271,1275,1278,38,1199,96,134,1250,1253,1428,194,190,1429,626,907,766,762,847,677,674,523,751,509,925,491,946,616,1409,258,1178,229,1218,1229,1236,1245,1249,2,596,92,139,1202,70,1267,1290,1420,1269,757,849,673,929,507,951,993,470,968,482,957,762,226,1164,254,1073,368,1082,335,326,275,1179,323,1171,602,950,947,569,648,543,916,520,833,532,1320,210,1300,561,1351,1357,1359,1396,991,475,985,459,1024,455,1046,405,372,1060,1055,1053,382,1045,411,459,462,465,1018,404,996,391,1251,1431,181,188,1430,1252,122,116,113,1194,234,242,1114,339,1066,52,141,1199,5,172,32,1203,1436,176,178,1192,317,1121,278,1161,260,1109,361,1136,368,1084,342,1111,357,1088,911,524,673,907,604,892,529,881,677,741,74,1201,95,97,128,1251,202,1189,272,332,1100,274,327,1153,630,627,883,1394,1364,692,841,498,494,764,923,529,812,818,523,912,1084,186,1189,212,1373,274,1183,237,757,1408,1335,1256,1425,195,700,840,839,778,777,1428,714,1433,1250,1239,139,64,1233,1116,1147,344,1062,389,1046,399,406,1035,421,1015,477,962,468,469,975,439,441,443,969,479,961,502,755,1377,203,1200,75,1075,359,345,1128,1126,209,1336,1254,1426,191,1189,180,1435,1238,140,1229,3,1202,33,167,9,7,171,1191,265,1170,310,1099,366,1057,899,525,894,568,665,537,722,569,891,626,885,886,571,1032,455,999,414,451,452,491,855,652,539,663,854,493,935,1010,422,987,983,462,1008,441,970,18,22,1235,1437,991,83,85,736,514,937,503,931,935,604,998,1061,367,1068,373,1067,255,972,452,1034,387,1001,72,1229,28,174,1190,248,1180,224,1364,1252,1338,201,1097,354,1099,302,304,1098,228,1313,1317,673,887,605,933,500,938,488,949,433,1037,415,1028,420,1018,409,1030,31,1217,248,1161,325,1154,273,1164,1158,1111,343,350,1111,300,299,1114,270,334,362,1076,284,1148,335,340,343,1076,371,1047,1124,1131,654,854,531,734,877,645,643,881,628,856,644,574,885,610,932,519,919,542,649,874,773,843,679,1425,1268,1421,1289,230,1164,323,319,1108,1106,221,223,1370,219,1335,255,1162,203,1422,1258,1333,1413,217,221,890,530,864,754,928,508,926,625,916,523,902,562,648,651,80,139,1249,1434,1240,135,1203,68,1230,24,840,680,1333,226,255,1100,334,1149,329,1103,264,1200,150,148,45,1124,173,4,583,576,883,612,55,53,1202,1201,149,1226,257,1181,275,1420,1279,572,1108,386,1050,378,1051,388,1024,464,964,471,1014,1020,439,990,460,407,943,499,762,925,521,675,848,759,501,932,507,505,943,1372,217,1197,155,41,37,161,1196,233,1297,1419,1332,1263,220,1187,213,211,1246,21,1236,1436,713,570,889,532,667,852,656,1164,1166,243,1117,303,1171,225,222,1216,263,258,1331,966,457,972,461,962,464,1019,1013,919,556,895,563,910,525,906,205,1376,211,970,477,958,486,956,490,953,1353,1350,223,1185,266,1169,294,288,1050,389,1047,425,426,1046,404,977,978,430,1042,1039,431,975,421,418,989,297,302,1085,330,371,1074,373,1070,1071,377,1056,229,1308,1310,1311,1417,251,1231,1,1121,298,299,1061,389,1049,423,1002,210,1265,120,1253,1255,453,455,1003,396,467,982,981,477,976,975,450,1009,440,494,947,489,768,843,690,880,634,871,650,867,577,880,644,544,551,555,564,894,527,751,101,1198,1150,1191,184,1238,148,1227,29,1220,150,1225,73,1202,37,1215,1218,232,1051,257,1137,342,1080,356,1094,1090,297,1187,203,1393,1341,176,1438,1234,23,950,487,486,973,252,1080,282,277,1165,246,1187,218,1235,211,1196,155,1223,1133,376,374,1066,323,1158,309,1183,240,1170,253,1068,364,362,1086,366,409,1042,416,1036,475,1028,437,1026,1021,456,994,420,988,402,1047,397,1059,1142,294,1097,351,1138,1219,30,1204,93,40,1147,275,1153,307,1073,356,1137,329,1154,234,233,1329,1267,1426,209,1392,217,215,1264,1330,227,1220,161,13,14,17,18,1248,204,1199,231,1120,1066,454,974,433,434,1026,447,448,987,460,964,494,932,622,945,498,949,604,888,538,664,853,756,699,841,695,700,828,793,820,702,839,838,512,516,920,508,937,516,918,522,914,546,901,524,895,625,909,559,1070,392,1021,85,1199,100,888,573,571,843,850,668,187,1431,183,1200,199,1424,1257,107,112,1008,453,452,502,940,507,509,924,920,513,922,512,509,695,879,649,872,869,744,529,525,908,565,892,568,1016,435,437,1037,1127,234,1191,157,160,15,1249,135,68,66,65,1208,1207,1213,265,1123,296,1100,351,1107,245,1112,341,1096,355,1134,277,323,1174,1173,318,314,311,1098,335,1146,286,1157,326,1130,1129,385,921,539,541,660,654,864,661,540,1194,163,10,0,1430,193,1189,218,1355,687,847,765,493,491,1016,450,1000,396,1067,365,1076,357,1092,222,1187,249,1178,1176,278,1167,283,1162,231,1298,1418,1270,1276,1282,1420,1259,84,137,138,1230,27,175,172,1342,1347,225,1166,268,337,1149,330,1117,661,861,577,873,632,901,563,897,547,913,555,1025,578,644,1439,1232,24,750,655,853,666,533,724,720,538,923,510,901,604,608,615,882,631,2,1230,148,1203,94,1226,216,1414,1326,263,267,1176,226,1319,1417,1303,230,1200,151,1224,264,339,1118,447,977,420,985,465,958,483,969,464,998,1081,370,1076,328,1152,645,879,1389,1344,228,1234,1235,216,1373,1378,200,1394,195,1426,1255,1256,127,122,1230,91,1153,286,1115 +0,1015,338,1089,438,1107,433,1061,391,994,384,1143,374,1062,432,1109,425,1112,419,1102,440,1105,435,1060,378,1143,366,981,1361,977,345,1013,339,1003,385,983,323,1088,439,1085,281,1082,285,957,1333,961,283,1082,294,956,1334,960,284,958,293,1133,383,1004,346,1012,378,1055,435,1072,375,1061,364,1144,373,974,352,987,400,1034,431,1042,383,1045,430,428,1000,349,1145,399,1070,283,1063,361,1146,398,1041,432,1033,340,1088,281,1083,397,1049,379,1053,284,1061,377,1096,439,1033,455,1043,430,1111,407,1146,344,1064,282,962,973,374,1134,292,1058,378,1054,454,1028,403,983,999,429,1010,382,1048,398,991,393,1147,341,1031,402,986,312,1112,406,1045,96,1046,401,1143,376,1071,280,1090,337,1018,1027,457,1041,386,1001,944,1365,929,1293,847,1237,791,1209,730,1187,423,1142,329,1152,339,1075,370,1084,366,1174,360,1147,372,1073,354,1175,359,1065,280,1067,435,1141,349,1121,235,1123,374,1063,368,974,947,942,1005,1011,1014,448,1054,471,1041,1035,430,998,945,1363,931,1381,924,1366,941,1006,383,1047,399,990,416,1045,454,1048,380,1052,286,1060,397,1056,378,1059,291,1125,498,1041,941,265,965,278,1072,373,1146,396,994,948,1362,933,1307,845,1266,897,1272,858,1309,843,1294,846,1287,849,1256,814,1290,896,1376,909,1277,801,1240,776,1248,848,1236,782,1240,766,1211,445,1015,1017,383,1009,1035,398,1002,385,1174,372,1172,337,1153,328,1164,322,1096,356,1068,343,1147,295,1081,1076,369,1080,339,1149,359,1063,363,1146,348,1111,287,945,296,952,955,958,962,266,940,1044,409,1142,379,1011,421,1044,1007,939,1051,397,993,385,991,414,1131,383,1036,499,1114,220,1121,291,1158,327,1154,336,1091,1095,357,1065,343,1079,490,1071,1080,1088,358,1110,431,996,383,1043,494,1070,1063,372,1061,374,1132,527,1059,375,1060,937,1052,382,1050,512,1135,290,1159,325,1170,523,1141,351,1176,326,1109,1094,336,1096,330,1150,337,1116,1120,334,1175,365,1085,362,1092,278,1153,295,953,991,974,391,998,355,1113,301,1118,235,1116,377,1059,493,942,1036,386,978,982,406,1027,1032,433,1027,469,1045,403,985,498,951,491,945,1309,837,1317,868,1295,884,1333,895,1292,849,1235,783,1223,808,1230,501,1032,458,1026,477,953,950,1354,948,478,1111,1082,369,1063,366,1077,354,1101,283,1062,935,258,1136,1140,436,1059,1056,382,1046,1048,1051,380,1019,461,1009,938,1417,931,1071,373,1160,323,1177,330,1122,228,1119,300,298,938,1404,943,492,1088,353,1065,934,259,968,499,949,255,941,1038,415,1121,1129,291,1120,352,1078,494,1058,392,1035,387,1000,413,1043,78,1025,460,1039,432,429,1067,305,1080,327,1156,292,1118,335,1099,318,1111,355,1071,378,1057,453,1050,519,1054,1052,378,1053,128,1049,382,1037,498,942,479,946,487,952,478,959,470,969,477,1020,1017,444,1031,388,977,976,390,1048,115,941,1413,1005,1001,425,1141,1120,226,1123,291,1128,448,1029,402,989,957,487,969,463,1038,433,1030,446,1210,1181,323,1163,1157,327,1155,293,1104,322,1182,1178,322,1111,1115,236,1074,370,1063,1060,377,1111,339,1148,340,1086,358,1064,361,1086,338,1125,347,1112,305,1117,1078,344,1074,353,1105,508,1031,943,497,952,484,974,462,1018,381,1011,454,970,431,1008,383,1044,1046,403,1001,999,390,943,417,1035,389,987,475,955,470,962,465,1017,405,1028,451,974,429,426,1011,3,985,486,947,1398,765,1243,779,1263,545,1169,1165,321,1183,1197,1207,1148,1140,380,1085,340,1147,267,1151,329,1153,1177,325,1158,326,1098,355,1146,346,1114,342,1147,1214,707,1203,1150,339,1079,1054,380,1047,382,1051,1053,534,1067,357,1093,181,1062,372,1075,1120,214,1021,378,1069,355,1097,335,1150,332,1176,342,1074,216,1116,294,1154,328,1127,641,1130,1136,1220,815,1229,507,1021,459,969,498,946,490,952,473,958,485,1014,1015,410,1027,455,1041,1043,82,1008,471,953,489,1119,323,1159,284,1098,351,1111,365,1063,371,1053,380,967,464,963,433,432,969,975,426,1044,408,981,464,1026,383,1046,400,1032,1034,1039,441,1032,443,963,469,1016,409,1041,383,1003,13,1013,466,961,984,406,970,416,989,461,1023,1022,103,1044,404,980,481,958,495,944,492,1105,350,1131,1224,1120,1062,377,1058,1123,218,1070,351,1139,1218,698,1352,854,1318,823,1301,866,1337,955,487,944,109,1044,98,923,1419,751,1412,942,497,1042,221,1112,248,1102,330,1079,370,1073,345,1146,349,1144,1216,1215,502,1006,448,1066,357,1090,1088,183,1103,1085,364,1134,1222,469,960,475,972,430,1039,413,975,461,985,430,1055,1056,380,1050,397,1055,250,1111,237,1067,223,1091,1090,294,1148,1212,1213,719,1380,754,1411,764,1250,527,1264,762,1255,776,1405,905,1384,943,210,1123,213,1057,377,1063,362,1073,314,1165,1163,292,1157,1155,1149,1194,1199,347,1146,343,1083,163,1087,358,1079,351,1103,295,297,1153,1188,318,1177,311 diff --git a/string-art-demo/src/wasm/string_art_rust_impl.js b/string-art-demo/src/wasm/string_art_rust_impl.js index 78388f0..5cd0923 100644 --- a/string-art-demo/src/wasm/string_art_rust_impl.js +++ b/string-art-demo/src/wasm/string_art_rust_impl.js @@ -810,7 +810,7 @@ function __wbg_get_imports() { const ret = false; return ret; }; - imports.wbg.__wbindgen_closure_wrapper336 = function(arg0, arg1, arg2) { + imports.wbg.__wbindgen_closure_wrapper339 = function(arg0, arg1, arg2) { const ret = makeMutClosure(arg0, arg1, 91, __wbg_adapter_28); return ret; }; diff --git a/string-art-demo/src/wasm/string_art_rust_impl_bg.wasm b/string-art-demo/src/wasm/string_art_rust_impl_bg.wasm index e8f8a36..7d92689 100644 Binary files a/string-art-demo/src/wasm/string_art_rust_impl_bg.wasm and b/string-art-demo/src/wasm/string_art_rust_impl_bg.wasm differ