Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/gcode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl GcodeWriter {
self.write_gcode(format!(";\n; Layer {}\n;", n).as_str());
self.write_gcode(
format!(
"G1 Z{} {}{} ; layer change",
"G0 Z{} {}{} ; layer change",
z, feed_axis, feed_rate
).as_str()
);
Expand All @@ -71,4 +71,4 @@ impl GcodeWriter {
).as_str()
);
}
}
}
40 changes: 40 additions & 0 deletions src/geometry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ pub struct BoundingBox {
pub z_max: f32
}

///
#[derive(Debug)]
pub struct OuterBox {
pub x_min: f32,
pub y_min: f32,
pub z_min: f32,
pub x_max: f32,
pub y_max: f32,
pub z_max: f32
}

///
#[derive(Clone, Debug)]
pub struct STLMesh {
Expand Down Expand Up @@ -95,6 +106,35 @@ impl STLMesh {
}
}

pub fn outer_bounds(&self) -> OuterBox {
let mut minimums = Vec::with_capacity(3);
let mut maximums = Vec::with_capacity(3);
for i in 0..3 {
let mut min_vals = self.vertices[0][i];
let mut max_vals = self.vertices[0][i];
for row in self.vertices.iter().skip(1) {
if row[i] < min_vals {
min_vals = row[i];

}
if row[i] > max_vals {
max_vals = row[i];
}
}
minimums.push(min_vals);
maximums.push(max_vals);
}
OuterBox {
x_min: minimums[0],
y_min: minimums[1],
z_min: minimums[2],
x_max: maximums[0],
y_max: maximums[1],
z_max: maximums[2]
}

}

pub fn faces(&self) -> &Vec<IndexedTriangle> {
&self.faces
}
Expand Down
23 changes: 21 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,28 @@ fn main() {
.map(|x| STLMesh::new(x.clone()))
.collect();

let z_offset = -1.0 * stl_meshes[0].bounding_box().z_min;
let _ = stl_meshes[0].translate(20.0,20.0,z_offset);

// Testing some files, They are allegedly ok. So where is the problem?
let mut file_testing = std::fs::OpenOptions::new().read(true).open("test/example/Sphere.stl").unwrap();
let mut stl = stl_io::read_stl(&mut file_testing).unwrap();

let Validation = stl_io::IndexedMesh::validate(&stl);
// println!("VALIDATION: {:?}",Validation);
// println!("X Min: {:?}",stl_meshes[0].bounding_box().x_min);
// println!("X Max: {:?}",stl_meshes[0].bounding_box().x_max);
// println!("Y Min: {:?}",stl_meshes[0].bounding_box().y_min);
// println!("Y Max: {:?}",stl_meshes[0].bounding_box().y_max);
// println!("Z Min: {:?}",stl_meshes[0].bounding_box().z_min);
// println!("Z Max: {:?}",stl_meshes[0].bounding_box().z_max);
// println!("Bounding Box: {:?}",stl_meshes[0].bounding_box());
// println!("Faces: {:?}",stl_meshes[0].faces()[0].normal);
// println!("Vertices: {:?}",stl_meshes[0].vertices());
// println!("My minimums: {:?}",stl_meshes[0].outer_bounds());
let z_offset = -1.0 * stl_meshes[0].outer_bounds().z_min;
// println!("Z Offset: {:?}",z_offset);
let _ = stl_meshes[0].translate(30.0,30.0,z_offset);
let _ = stl_meshes[0].scale(10.0, 10.0, 10.0);


let slicer = FFFSlicer::new(settings, stl_meshes);
let _ = slicer.slice(&gcode_file);
Expand Down
160 changes: 139 additions & 21 deletions src/slicer/fff_slicer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,24 @@ impl FFFSlicer {
}
}

pub fn wall_lines(&self, stl:&STLMesh, verts: Vec<[f32;2]>, ind: Vec<usize>, num_lines: u32) {
//testing wall ines
let num_wall_lines = num_lines-1;

// for face in 0..ind.len() {
// println!("Face: {:?}",stl.faces()[ind[face]].normal);
// }



}

pub fn perimeters(&self, stl: &STLMesh, gcode_writer: &mut GcodeWriter, z: f32) -> () {
let tol = 1e-6 as f32;
let tris = stl.triangles();
let perimeter_edges = Edges::new();

// println!("Normals, {:?}",stl.faces()[0].normal);
// println!("STL: {:?}",stl);

// counter to track the index of the triangles that intersect with each z layer
let mut counter = 0;
Expand All @@ -34,24 +47,25 @@ impl FFFSlicer {
// vector containing the intersection coordinates between the
// triangles and the plane z_height
let mut ab_coords = vec![];

let mut index = 0;
let mut used_indices = vec![];
// iterate through all the triangles in the stl
for tri in tris.iter() {

// break down vertices for easier handling (for me)
let vert_1 = tri[0];
let vert_2 = tri[1];
let vert_3 = tri[2];



// if any of the vertices are above AND any are below,
// if any of the vertices of a triangle are above AND any are below z,
if vert_1[2] < z || vert_2[2] < z || vert_3[2] < z {
if vert_1[2] > z || vert_2[2] > z || vert_3[2] > z {

// append the index of intersecting triangles
vec.push(counter);

used_indices.push(index);
// Must sort the vertices to be able to calculate
// the line segment created by the interception of
// the z_height and the triangles that bound it.
Expand Down Expand Up @@ -79,7 +93,8 @@ impl FFFSlicer {
// There are three triangles possible: two vertices
// below z_height and one above, two vertices above
// z_height and one below, and one vertex coincident
// with z_height and one above and one below. In
// with z_height and one above and one below (Case not
// included, two coincident, one above or below). In
// the first two cases, the single vertex will go into
// the first index (0). In the last case, either
// vertex not coincident with z_height will go into
Expand Down Expand Up @@ -153,32 +168,45 @@ impl FFFSlicer {
let b_coord = [xb, yb];
ab_coords.push([a_coord, b_coord]);
}
// println!("Test Used Indices: {:?}",used_indices)
}
// increase counter for next triangle
counter += 1;

index += 1;
} // end looping through all triangles for a layer at z_height

println!("Global Layer height; {:?}", z);
println!("Number of triangles in Layer: {:?}", vec.len());
// println!("Sample AB-Coords: {:?}",ab_coords[0]);
// println!("Going Crazy: {:?}", ab_coords);
// Testing to sort the perimeter lines (ab)
let TEST = 1;
// let TEST = 1;
// if TEST == 1 { //16.5 {

// println!("All AB-Coords: {:?}", ab_coords);

// perimeter array of the sorted line segments
let mut perimeter_sort = Vec::new();
let mut used_indices_sort = vec![];
let mut perimeter_verts = vec![];

// Clone the vector of all line segments, we
// will be removing all used segments
let mut AB_COORDS = Vec::from(ab_coords.clone());
// push the first line segment to the sorted
// list, the exact place to start will need
// to be adjusted in the future.

// As long as the coordinate list is not empty,
// continue to sort them in order of closest.
// TODO adding capabilities to deal with islands
// in the mesh
if AB_COORDS.len() > 0 {
perimeter_sort.push(AB_COORDS[0]);
// push the first line segment to the sorted
// list, the exact place to start will need
// to be adjusted in the future.
perimeter_sort.push(AB_COORDS[0]);
// perimeter_verts.push(perimeter_sort[0][0]);
perimeter_verts.push(perimeter_sort[0][1]);
used_indices_sort.push(used_indices[0]);
used_indices.swap_remove(0);
// remove the first line segment
AB_COORDS.swap_remove(0);
// create a counter variable
Expand All @@ -192,11 +220,15 @@ impl FFFSlicer {

// Search radius for next line segment.
let mut search_radius = 1.0e-3;

// dummy variable. Need this to check if next point is an island
let mut last_radius = 1.0e-3;
// while the number of available line segments is
// above some number, keep building the connected
// lines
let mut cycle_count = 0;

while num_available_segs > 0 {

// index counter, for the triangle in AB_COORDS
let mut index_count = 0;
// vector to save the matcing indices. This
Expand Down Expand Up @@ -279,7 +311,7 @@ impl FFFSlicer {
if euclidean <= search_radius {
// if y_diff <= search_radius {
// println!("--------------------------------------");
// println!("Match Found");
// println!("Test");
// println!("euclindean A: {:?}",euclidean_b);
// println!("euclindean B: {:?}",euclidean_b);
// println!("euclindean B: {:?}",euclidean_b);
Expand All @@ -289,8 +321,9 @@ impl FFFSlicer {
// println!("Searched X: {:?}, Searched Y: {:?}", perimeter_sort.last().expect("Perimeter is empty")[1][0], perimeter_sort.last().expect("Perimeter is empty")[1][1]);
// println!("X diff: {:?}",x_diff);
// println!("Y diff: {:?}",y_diff);
// println!("Euclidean: {:?}",euclidean);
// println!("Search Radius: {:?}", search_radius);
println!("Euclidean: {:?}",euclidean);
println!("Search Radius: {:?}", search_radius);
println!("Coords: {:?}",AB_COORDS[index_count]);
// perimeter_sort.push(*segs);
index_match.push(index_count);
vertex_switch.push(which_vertex);
Expand All @@ -306,11 +339,16 @@ impl FFFSlicer {
// the search. If none are found, grow the search radus, and
// repeat the search. (Hopefully).
//
// println!("NUM INDEXES: {:?}",index_match.len());
// println!("INDEXES: {:?}",index_match);
// println!("----------------------------------");
println!("NUM INDEXES: {:?}",index_match.len());
println!("INDEXES: {:?}",index_match);
println!("Cycle Count: {:?}",cycle_count);
println!("----------------------------------");
if index_match.len() == 1 {
println!("Num Available Segs: {:?}", num_available_segs);
// println!("Used Indices: {:?}", used_indices);
perimeter_sort.push(AB_COORDS[index_match[0]]);
used_indices_sort.push(used_indices[index_match[0]]);
// println!("Sorted Used Indices: {:?}",used_indices_sort);
// println!("Size of index match: {:?}",index_match.len());
// AB_COORDS.swap_remove(index_count);
// println!("Test index match: {:?}", index_match);
Expand All @@ -319,18 +357,97 @@ impl FFFSlicer {
num_available_segs -= 1;
let REMOVE = *index_match.last().expect("Nothing in the perimeter");
AB_COORDS.swap_remove(REMOVE);
used_indices.swap_remove(REMOVE);
// println!("Size of AB_COUNT: {:?}",AB_COORDS.len());
search_radius = 1e-3;
gcode_writer.write_perimeter(perimeter_sort.last().unwrap()[1][0],perimeter_sort.last().unwrap()[1][1],z,555.0,1200.0);
perimeter_verts.push([perimeter_sort.last().unwrap()[1][0],perimeter_sort.last().unwrap()[1][1]]);
// if the number of matching indices is 2 and we have iterated over 20000
// this might be the case when finding a new island, and the closest two
// segments are the same distance away from the last point.
} else if index_match.len() == 2 && cycle_count > 10000{
println!("*********************DID THIS WORK??????******************");
println!("Search Radius: {:?}", search_radius);
println!("Cycle Count: {:?}",cycle_count);
println!("NUM INDEXES: {:?}",index_match.len());
if index_match.len() == 2 {
println!("Num Available Segs: {:?}", num_available_segs);
// println!("Used Indices: {:?}", used_indices);
perimeter_sort.push(AB_COORDS[index_match[0]]);
used_indices_sort.push(used_indices[index_match[0]]);
// println!("Sorted Used Indices: {:?}",used_indices_sort);
// println!("Size of index match: {:?}",index_match.len());
// AB_COORDS.swap_remove(index_count);
// println!("Test index match: {:?}", index_match);
// println!("Size of AB_COUNT: {:?}",AB_COORDS.len());
// println!("Sorted Segments: {:?}",perimeter_sort);
num_available_segs -= 1;
let REMOVE = *index_match.last().expect("Nothing in the perimeter");
AB_COORDS.swap_remove(REMOVE);
used_indices.swap_remove(REMOVE);
// println!("Size of AB_COUNT: {:?}",AB_COORDS.len());
search_radius = 1e-3;
gcode_writer.write_perimeter(perimeter_sort.last().unwrap()[1][0],perimeter_sort.last().unwrap()[1][1],z,555.0,1200.0);
perimeter_verts.push([perimeter_sort.last().unwrap()[1][0],perimeter_sort.last().unwrap()[1][1]]);
}
// if the number of matching indices is greater than 1,
// shrink the search radius
} else if index_match.len() > 1 {
search_radius = search_radius * 0.9;
search_radius = search_radius * 0.99;
if search_radius < (1e-3)/1000.0 {
break
}
// if the number of matching pairs is zero,
// grow the search radius
} else {
search_radius = search_radius * 1.1;
search_radius = search_radius * 1.015;
// if search_radius > 1000.0*(1e-3) {
// break
// }
}
cycle_count += 1;

if cycle_count > 40000 {
println!("Search Radius: {:?}", search_radius);
println!("Cycle Count: {:?}",cycle_count);
println!("NUM INDEXES: {:?}",index_match.len());
if index_match.len() == 2 {
println!("Num Available Segs: {:?}", num_available_segs);
// println!("Used Indices: {:?}", used_indices);
perimeter_sort.push(AB_COORDS[index_match[0]]);
used_indices_sort.push(used_indices[index_match[0]]);
// println!("Sorted Used Indices: {:?}",used_indices_sort);
// println!("Size of index match: {:?}",index_match.len());
// AB_COORDS.swap_remove(index_count);
// println!("Test index match: {:?}", index_match);
// println!("Size of AB_COUNT: {:?}",AB_COORDS.len());
// println!("Sorted Segments: {:?}",perimeter_sort);
num_available_segs -= 1;
let REMOVE = *index_match.last().expect("Nothing in the perimeter");
AB_COORDS.swap_remove(REMOVE);
used_indices.swap_remove(REMOVE);
// println!("Size of AB_COUNT: {:?}",AB_COORDS.len());
search_radius = 1e-3;
gcode_writer.write_perimeter(perimeter_sort.last().unwrap()[1][0],perimeter_sort.last().unwrap()[1][1],z,555.0,1200.0);
perimeter_verts.push([perimeter_sort.last().unwrap()[1][0],perimeter_sort.last().unwrap()[1][1]]);

}
else {
break;
}
// break;
}
}
// println!("Sorted Segments: {:?}",perimeter_sort);
// println!("Used Indices: {:?}",used_indices_sort);
// println!("Perimeter Chords Sort: {:?}",perimeter_sort);
// println!("Perimeter Vert Sort: {:?}",perimeter_verts);
// println!("Face: {:?}",stl.faces()[used_indices_sort[0]].normal);
// let mut faces = vec![];
// println!("TEst: {:?}", used_indices_sort.len());

self.wall_lines(stl, perimeter_verts, used_indices_sort, 2);

println!("----------------------------------");


Expand All @@ -357,6 +474,7 @@ impl Slicer for FFFSlicer {
println!("{}", self.settings);
println!("Generating layer heights");
let zs = self.layer_heights(&self.settings, &stl);
// println!("ZS: {:?}",self.layer_heights(sel));
let mut z_height: f32 = 0.0;
// TODO must shift the stl up in the z direction, no negatives
// let z_offset = -1.0 * -stl.bounding_box().z_min;
Expand Down
2 changes: 1 addition & 1 deletion src/slicer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::settings::{FloatOrVecOfFloats, Settings};
/// trait for shared behavior between slicers
pub trait Slicer {
fn layer_heights(&self, settings: &Settings, stl: &STLMesh) -> Vec<f32> {
let bb = stl.bounding_box();
let bb = stl.outer_bounds();//stl.bounding_box();
let mut heights = vec![settings.layer_height.layer_0_height];

let total_height = bb.z_max - bb.z_min - heights[0];
Expand Down
Loading