Skip to content
Snippets Groups Projects
Commit 51c3c254 authored by Jérôme Chételat's avatar Jérôme Chételat
Browse files

Error reification in lib

parent d1afc72e
No related branches found
No related tags found
No related merge requests found
Pipeline #11127 passed
...@@ -31,12 +31,24 @@ impl IEDGE { ...@@ -31,12 +31,24 @@ impl IEDGE {
} }
} }
#[derive(Debug)]
pub enum TriangulationError {
NotEnoughPoints,
InvalidTriangulation,
}
/// Triangulation subroutine. /// Triangulation subroutine.
/// Allows one to triangulate a list of points in a O(n²) time complexity /// Allows one to triangulate a list of points in a O(n²) time complexity
pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, ntri: &mut i32) -> i32 { pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>) -> Result<Vec<ITRIANGLE>, TriangulationError> {
if *nv < 3 {
return Err(TriangulationError::NotEnoughPoints)
}
let trimax = 4 * *nv; let trimax = 4 * *nv;
let mut _nedge: i32 = 0; let mut _nedge: i32 = 0;
let mut status = 0;
let mut v: Vec<ITRIANGLE> = vec![ITRIANGLE::new(-1, -1, -1); trimax as usize];
let mut ntri: i32 = 0;
let mut edges: Vec<IEDGE> = Vec::with_capacity(100000_usize); let mut edges: Vec<IEDGE> = Vec::with_capacity(100000_usize);
let mut complete: Vec<bool> = vec![false; trimax as usize]; let mut complete: Vec<bool> = vec![false; trimax as usize];
...@@ -102,7 +114,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt ...@@ -102,7 +114,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
v[0].p2 = *nv+1; v[0].p2 = *nv+1;
v[0].p3 = *nv+2; v[0].p3 = *nv+2;
complete[0] = false; complete[0] = false;
*ntri = 1; ntri = 1;
/* /*
Include each point one at a time into the existing mesh Include each point one at a time into the existing mesh
...@@ -121,7 +133,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt ...@@ -121,7 +133,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
*/ */
_j = 0; _j = 0;
while _j < *ntri as isize { while _j < ntri as isize {
if complete[_j as usize] { if complete[_j as usize] {
_j += 1; _j += 1;
continue; continue;
...@@ -142,9 +154,9 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt ...@@ -142,9 +154,9 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
edges.push(IEDGE::new(v[_j as usize].p2, v[_j as usize].p3)); edges.push(IEDGE::new(v[_j as usize].p2, v[_j as usize].p3));
edges.push(IEDGE::new(v[_j as usize].p3, v[_j as usize].p1)); edges.push(IEDGE::new(v[_j as usize].p3, v[_j as usize].p1));
_nedge += 3; _nedge += 3;
v[_j as usize] = v[(*ntri-1) as usize]; v[_j as usize] = v[(ntri-1) as usize];
complete[_j as usize] = complete[(*ntri-1) as usize]; complete[_j as usize] = complete[(ntri-1) as usize];
*ntri -= 1; ntri -= 1;
_j -= 1; _j -= 1;
} }
...@@ -188,15 +200,14 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt ...@@ -188,15 +200,14 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
_j += 1; _j += 1;
continue; continue;
} }
if (*ntri) >= trimax { if (ntri) >= trimax {
status = 4; return Err(TriangulationError::InvalidTriangulation);
return status
} }
v[*ntri as usize].p1 = edges[_j as usize].p1; v[ntri as usize].p1 = edges[_j as usize].p1;
v[*ntri as usize].p2 = edges[_j as usize].p2; v[ntri as usize].p2 = edges[_j as usize].p2;
v[*ntri as usize].p3 = i as i32; v[ntri as usize].p3 = i as i32;
complete[*ntri as usize] = false; complete[ntri as usize] = false;
*ntri += 1; ntri += 1;
_j += 1; _j += 1;
} }
...@@ -207,11 +218,11 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt ...@@ -207,11 +218,11 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
These are triangles which have a vertex number greater than nv These are triangles which have a vertex number greater than nv
*/ */
let mut i: isize = 0_isize; let mut i: isize = 0_isize;
while (i as i32) < *ntri { while (i as i32) < ntri {
if v[i as usize].p1 >= *nv || v[i as usize].p2 >= *nv || v[i as usize].p3 >= *nv if v[i as usize].p1 >= *nv || v[i as usize].p2 >= *nv || v[i as usize].p3 >= *nv
{ {
v.remove(i as usize); v.remove(i as usize);
*ntri -= 1; ntri -= 1;
i -=1 ; i -=1 ;
} }
i += 1; i += 1;
...@@ -219,7 +230,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt ...@@ -219,7 +230,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
// Removing unnecessary triangles // Removing unnecessary triangles
i = v.len() as isize - 1; i = v.len() as isize - 1;
while (i as i32) >= *ntri { while (i as i32) >= ntri {
v.remove(i as usize); v.remove(i as usize);
i -= 1; i -= 1;
} }
...@@ -229,7 +240,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt ...@@ -229,7 +240,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
pxyz.remove(pxyz.len()-1); pxyz.remove(pxyz.len()-1);
pxyz.remove(pxyz.len()-1); pxyz.remove(pxyz.len()-1);
status Ok(v)
} }
/// Return true if a point (xp,yp) lies inside the circumcircle made up /// Return true if a point (xp,yp) lies inside the circumcircle made up
......
...@@ -8,7 +8,7 @@ mod lib; ...@@ -8,7 +8,7 @@ mod lib;
mod stl_writer; mod stl_writer;
use las::reader::*; use las::reader::*;
use lib::{XYZ, ITRIANGLE,triangulate}; use lib::{XYZ, TriangulationError, ITRIANGLE, triangulate};
use std::time::Instant; use std::time::Instant;
...@@ -27,12 +27,10 @@ fn main() { ...@@ -27,12 +27,10 @@ fn main() {
points.sort_by(|a, b| a.partial_cmp(b).unwrap()); points.sort_by(|a, b| a.partial_cmp(b).unwrap());
let mut nv: i32 = points.len() as i32; let mut nv: i32 = points.len() as i32;
let mut triangles: Vec<ITRIANGLE> = vec![ITRIANGLE::new(-1, -1, -1); 3*nv as usize];
let mut ntri: i32 = triangles.len() as i32;
println!("triangulating {} points ...", points.len()); println!("triangulating {} points ...", points.len());
let start_triangulation = Instant::now(); let start_triangulation = Instant::now();
triangulate(&mut nv, &mut points, &mut triangles, &mut ntri); let triangles: Vec<ITRIANGLE> = triangulate(&mut nv, &mut points).expect("An error has been detected while triangulating");
let time_taken = start_triangulation.elapsed(); let time_taken = start_triangulation.elapsed();
println!("time taken to triangulate {} points : {} [s]", points.len(), time_taken.as_secs_f64()); println!("time taken to triangulate {} points : {} [s]", points.len(), time_taken.as_secs_f64());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment