Skip to content

Commit

Permalink
Parallelize with Rayon
Browse files Browse the repository at this point in the history
  • Loading branch information
Riley Trautman committed Nov 29, 2017
1 parent 026fcab commit 8425827
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 60 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ license = "MIT"
obj = "0.8"
noise = "0.4"
cgmath = "0.15.0"
rayon = "0.9.0"
155 changes: 95 additions & 60 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@
extern crate obj;
extern crate noise;
extern crate cgmath;
extern crate rayon;

use std::sync::{Arc, Mutex};
use std::path::Path;
use std::fs::File;
use std::io::{BufWriter, Write};
use std::io::{BufWriter, Cursor, Write};
use obj::{Obj, SimplePolygon, IndexTuple};
use noise::Fbm;
//use noise::Seedable;
use noise::MultiFractal;
use noise::NoiseModule;
use cgmath::Vector3;
use cgmath::ElementWise;
use rayon::prelude::*;

// A function called test that takes in 1 32-bit integer
// and returns a 32-bit integer.
Expand Down Expand Up @@ -86,29 +89,40 @@ fn duplicate<T>(
positions: &[Vector3<f32>],
translation: Vector3<f32>,
height_scalar: f32,
file: &mut BufWriter<T>,
file: Arc<Mutex<BufWriter<T>>>,
) where
T: Write,
{
let v = Vec::new();
let c = Cursor::new(v);
let mut b = BufWriter::new(c);

for point in positions {
write!(
file,
b,
"v {} {} {}\n",
point.x + translation.x,
point.y + translation.y,
point.z * height_scalar * 2.0
).unwrap();
}

file.lock()
.unwrap()
.write(b.into_inner().unwrap().into_inner().as_ref())
.unwrap();
}

fn write_positions(
fn write_positions<T>(
positions: &[Vector3<f32>],
layers: i32,
spacing: f32,
length: f32,
width: f32,
file: &mut BufWriter<File>,
) {
file: Arc<Mutex<BufWriter<T>>>,
) where
T: Write + Send,
{
let length = length + spacing;
let width = width + spacing;

Expand All @@ -122,79 +136,92 @@ fn write_positions(
positions,
Vector3::new(0.0, 0.0, 0.0),
return_at(0.5, 0.5, &fbm),
file,
file.clone(),
);

for current_duplicate in 0..((layers * (layers - 1)) * 4) {
let current_layer = (0.5 * (((current_duplicate + 1) as f32).sqrt() - 1.0)) as i32 + 1;
let current_duplicate = current_duplicate - 4 * current_layer * (current_layer - 1);
(0..((layers * (layers - 1)) * 4))
.into_par_iter()
.for_each(move |current_duplicate| {
let current_layer = (0.5 * (((current_duplicate + 1) as f32).sqrt() - 1.0)) as i32 + 1;
let current_duplicate = current_duplicate - 4 * current_layer * (current_layer - 1);

let current_ratio = current_duplicate as f32 / (current_layer as f32 * 8.0);
let current_ratio = current_duplicate as f32 / (current_layer as f32 * 8.0);

let unit_translation = if current_ratio <= 1.0 / 4.0 {
Vector3::new(1.0, -1.0 + (current_ratio * 8.0), 0.0)
} else if current_ratio <= 2.0 / 4.0 {
Vector3::new(1.0 - ((current_ratio) - 1.0 / 4.0) * 8.0, 1.0, 0.0)
} else if current_ratio <= 3.0 / 4.0 {
Vector3::new(-1.0, 1.0 - ((current_ratio) - 2.0 / 4.0) * 8.0, 0.0)
} else {
Vector3::new(-1.0 + ((current_ratio) - 3.0 / 4.0) * 8.0, -1.0, 0.0)
};
let unit_translation = if current_ratio <= 1.0 / 4.0 {
Vector3::new(1.0, -1.0 + (current_ratio * 8.0), 0.0)
} else if current_ratio <= 2.0 / 4.0 {
Vector3::new(1.0 - ((current_ratio) - 1.0 / 4.0) * 8.0, 1.0, 0.0)
} else if current_ratio <= 3.0 / 4.0 {
Vector3::new(-1.0, 1.0 - ((current_ratio) - 2.0 / 4.0) * 8.0, 0.0)
} else {
Vector3::new(-1.0 + ((current_ratio) - 3.0 / 4.0) * 8.0, -1.0, 0.0)
};

let translation = current_layer as f32 *
Vector3::new(length * unit_translation.x, width * unit_translation.y, 0.0);
let translation = current_layer as f32 *
Vector3::new(length * unit_translation.x, width * unit_translation.y, 0.0);

// gets into range -1 to +1
let coord = 1.0 / 5.0 *
translation.mul_element_wise(Vector3::new(
1.0 / length as f32,
1.0 / width as f32,
0.0,
));
// gets into range -1 to +1
let coord =
1.0 / 5.0 *
translation.mul_element_wise(
Vector3::new(1.0 / length as f32, 1.0 / width as f32, 0.0),
);

// gets into range -0.4 to +0.4
let coord = 0.4 * coord;
// gets into range -0.4 to +0.4
let coord = 0.4 * coord;

// gets into range 0.1 to 0.9
let coord = coord + Vector3::new(0.5, 0.5, 0.0);
// gets into range 0.1 to 0.9
let coord = coord + Vector3::new(0.5, 0.5, 0.0);

let height_scalar = return_at(coord.x, coord.y, &fbm);
let height_scalar = return_at(coord.x, coord.y, &fbm);

duplicate(&positions, translation, height_scalar, file)
}
duplicate(&positions, translation, height_scalar, file.clone())
})
}

fn write_faces(
fn write_faces<T>(
faces: &[Vec<IndexTuple>],
n_positions: usize,
layers: usize,
file: &mut BufWriter<File>,
) {
for current_value in 0..(2 * layers - 1).pow(2) {
let offset = n_positions * current_value + 1;

for current_face in faces {
write!(file, "f").unwrap();
for value in current_face {
write!(file, " {}/", value.0 + offset).unwrap();
if let Some(i) = value.1 {
write!(file, "{}", i + offset).unwrap();
}
write!(file, "/").unwrap();
if let Some(j) = value.2 {
write!(file, "{}", j + offset).unwrap();
file: Arc<Mutex<BufWriter<T>>>,
) where
T: Write + Send,
{
(0..(2 * layers - 1).pow(2)).into_par_iter().for_each(
move |current_value| {
let v = Vec::new();
let c = Cursor::new(v);
let mut b = BufWriter::new(c);
let offset = n_positions * current_value + 1;

for current_face in faces {
write!(b, "f").unwrap();
for value in current_face {
write!(b, " {}/", value.0 + offset).unwrap();
if let Some(i) = value.1 {
write!(b, "{}", i + offset).unwrap();
}
write!(b, "/").unwrap();
if let Some(j) = value.2 {
write!(b, "{}", j + offset).unwrap();
}
}
write!(b, "\n").unwrap();
}
write!(file, "\n").unwrap();
}
}

file.lock()
.unwrap()
.write(b.into_inner().unwrap().into_inner().as_ref())
.unwrap();
},
);
}

fn main() {
let path = Path::new("data/test.obj");
let obj: Obj<SimplePolygon> = Obj::load(&path).expect("Failed to load input obj");

let layers = 10;
let layers = 80;
let spacing = 1.0;

let (length, width) = find_l_w(&obj);
Expand All @@ -206,13 +233,21 @@ fn main() {


let filename = Path::new("target/noice.obj");
let mut file = BufWriter::new(File::create(filename).unwrap());

write_positions(&input_positions, layers, spacing, length, width, &mut file);
let file_buf_writer = BufWriter::new(File::create(filename).unwrap());
let file = Arc::new(Mutex::new(file_buf_writer));

write_positions(
&input_positions,
layers,
spacing,
length,
width,
file.clone(),
);
write_faces(
&obj.objects[0].groups[0].polys,
obj.position.len(),
layers as usize,
&mut file,
file,
);
}

0 comments on commit 8425827

Please sign in to comment.