Skip to content

Commit

Permalink
Fix wavefront tests + new test for different pos + add them in ci (#268)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vrixyz authored Sep 20, 2024
1 parent 5a9ebff commit 22a4261
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/parry-ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
- name: Check serialization
run: cargo check --features bytemuck-serialize,serde-serialize,rkyv-serialize;
- name: Run tests
run: cargo test
run: cargo test --features wavefront
build-wasm:
runs-on: ubuntu-latest
env:
Expand Down
5 changes: 5 additions & 0 deletions crates/parry3d-f64/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ simd-stable = ["simba/wide", "simd-is-enabled"]
simd-nightly = ["simba/portable_simd", "simd-is-enabled"]
enhanced-determinism = ["simba/libm_force", "indexmap"]
parallel = ["rayon"]
# Adds `TriMesh:to_obj_file` function.
wavefront = ["obj"]
alloc = []
improved_fixed_point_support = []
Expand Down Expand Up @@ -88,3 +89,7 @@ thiserror = { version = "1", optional = true }
oorandom = "11"
ptree = "0.4.0"
rand = { version = "0.8" }

[package.metadata.docs.rs]
rustdoc-args = ["-Zunstable-options", "--generate-link-to-definition"]
features = ["wavefront"]
2 changes: 2 additions & 0 deletions crates/parry3d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ simd-stable = ["simba/wide", "simd-is-enabled"]
simd-nightly = ["simba/portable_simd", "simd-is-enabled"]
enhanced-determinism = ["simba/libm_force", "indexmap"]
parallel = ["rayon"]
# Adds `TriMesh:to_obj_file` function.
wavefront = ["obj"]
alloc = []
improved_fixed_point_support = []
Expand Down Expand Up @@ -95,6 +96,7 @@ rand_isaac = "0.3"
[package.metadata.docs.rs]
rustdoc-args = ["-Zunstable-options", "--generate-link-to-definition"]
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
features = ["wavefront"]

# The following listing is to allow for examples to be scraped,
# see https://doc.rust-lang.org/rustdoc/scraped-examples.html#scraped-examples for details.
Expand Down
80 changes: 56 additions & 24 deletions src/transformation/mesh_intersection/mesh_intersection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use crate::query::{visitors::BoundingVolumeIntersectionsSimultaneousVisitor, Poi
use crate::shape::{TriMesh, Triangle};
use crate::utils;
use na::{Point3, Vector3};
#[cfg(feature = "wavefront")]
use obj::{Group, IndexTuple, ObjData, Object, SimplePolygon};
use rstar::RTree;
use spade::{ConstrainedDelaunayTriangulation, InsertionError, Triangulation as _};
use std::collections::BTreeMap;
Expand Down Expand Up @@ -513,7 +511,7 @@ fn insert_into_set(
fn smallest_angle(points: &[Point3<Real>]) -> Real {
let n = points.len();

let mut worst_cos = -2.0;
let mut worst_cos: Real = -2.0;
for i in 0..points.len() {
let d1 = (points[i] - points[(i + 1) % n]).normalize();
let d2 = (points[(i + 2) % n] - points[(i + 1) % n]).normalize();
Expand Down Expand Up @@ -669,9 +667,9 @@ fn merge_triangle_sets(
#[cfg(test)]
mod tests {
use super::*;
use crate::shape::TriMeshFlags;
use crate::transformation::wavefront::*;
use crate::shape::{Ball, Cuboid, TriMeshFlags};
use obj::Obj;
use obj::ObjData;

#[test]
fn test_same_mesh_intersection() {
Expand All @@ -685,17 +683,18 @@ mod tests {
let mesh = TriMesh::with_flags(
position
.iter()
.map(|v| Point3::new(v[0] as f64, v[1] as f64, v[2] as f64))
.map(|v| Point3::new(v[0] as Real, v[1] as Real, v[2] as Real))
.collect::<Vec<_>>(),
objects[0].groups[0]
.polys
.iter()
.map(|p| [p.0[0].0 as u32, p.0[1].0 as u32, p.0[2].0 as u32])
.collect::<Vec<_>>(),
TriMeshFlags::all(),
);
)
.unwrap();

let res = intersect_meshes(
let _ = intersect_meshes(
&Isometry::identity(),
&mesh,
false,
Expand All @@ -706,7 +705,34 @@ mod tests {
.unwrap()
.unwrap();

mesh.to_obj_file(&PathBuf::from("same_test.obj"));
let _ = mesh.to_obj_file(&PathBuf::from("same_test.obj"));
}

#[test]
fn test_non_origin_pos1_pos2_intersection() {
let ball = Ball::new(2f32 as Real).to_trimesh(10, 10);
let cuboid = Cuboid::new(Vector3::new(2.0, 1.0, 1.0)).to_trimesh();
let mut sphere_mesh = TriMesh::new(ball.0, ball.1).unwrap();
sphere_mesh.set_flags(TriMeshFlags::all()).unwrap();
let mut cuboid_mesh = TriMesh::new(cuboid.0, cuboid.1).unwrap();
cuboid_mesh.set_flags(TriMeshFlags::all()).unwrap();

let res = intersect_meshes(
&Isometry::translation(1.0, 0.0, 0.0),
&cuboid_mesh,
false,
&Isometry::translation(2.0, 0.0, 0.0),
&sphere_mesh,
false,
)
.unwrap()
.unwrap();

let _ = res.to_obj_file(&PathBuf::from("test_non_origin_pos1_pos2_intersection.obj"));

let bounding_sphere = res.local_bounding_sphere();
assert!(bounding_sphere.center == Point3::new(1.5, 0.0, 0.0));
assert_relative_eq!(2.0615528, bounding_sphere.radius, epsilon = 1.0e-5);
}

#[test]
Expand All @@ -721,15 +747,16 @@ mod tests {
let offset_mesh = TriMesh::with_flags(
position
.iter()
.map(|v| Point3::new(v[0] as f64, v[1] as f64, v[2] as f64))
.map(|v| Point3::new(v[0] as Real, v[1] as Real, v[2] as Real))
.collect::<Vec<_>>(),
objects[0].groups[0]
.polys
.iter()
.map(|p| [p.0[0].0 as u32, p.0[1].0 as u32, p.0[2].0 as u32])
.collect::<Vec<_>>(),
TriMeshFlags::all(),
);
)
.unwrap();

let Obj {
data: ObjData {
Expand All @@ -741,15 +768,16 @@ mod tests {
let center_mesh = TriMesh::with_flags(
position
.iter()
.map(|v| Point3::new(v[0] as f64, v[1] as f64, v[2] as f64))
.map(|v| Point3::new(v[0] as Real, v[1] as Real, v[2] as Real))
.collect::<Vec<_>>(),
objects[0].groups[0]
.polys
.iter()
.map(|p| [p.0[0].0 as u32, p.0[1].0 as u32, p.0[2].0 as u32])
.collect::<Vec<_>>(),
TriMeshFlags::all(),
);
)
.unwrap();

let res = intersect_meshes(
&Isometry::identity(),
Expand All @@ -762,7 +790,7 @@ mod tests {
.unwrap()
.unwrap();

res.to_obj_file(&PathBuf::from("offset_test.obj"));
let _ = res.to_obj_file(&PathBuf::from("offset_test.obj"));
}

#[test]
Expand All @@ -777,15 +805,16 @@ mod tests {
let stair_mesh = TriMesh::with_flags(
position
.iter()
.map(|v| Point3::new(v[0] as f64, v[1] as f64, v[2] as f64))
.map(|v| Point3::new(v[0] as Real, v[1] as Real, v[2] as Real))
.collect::<Vec<_>>(),
objects[0].groups[0]
.polys
.iter()
.map(|p| [p.0[0].0 as u32, p.0[1].0 as u32, p.0[2].0 as u32])
.collect::<Vec<_>>(),
TriMeshFlags::all(),
);
)
.unwrap();

let Obj {
data: ObjData {
Expand All @@ -797,15 +826,16 @@ mod tests {
let bar_mesh = TriMesh::with_flags(
position
.iter()
.map(|v| Point3::new(v[0] as f64, v[1] as f64, v[2] as f64))
.map(|v| Point3::new(v[0] as Real, v[1] as Real, v[2] as Real))
.collect::<Vec<_>>(),
objects[0].groups[0]
.polys
.iter()
.map(|p| [p.0[0].0 as u32, p.0[1].0 as u32, p.0[2].0 as u32])
.collect::<Vec<_>>(),
TriMeshFlags::all(),
);
)
.unwrap();

let res = intersect_meshes(
&Isometry::identity(),
Expand All @@ -818,7 +848,7 @@ mod tests {
.unwrap()
.unwrap();

res.to_obj_file(&PathBuf::from("stair_test.obj"));
let _ = res.to_obj_file(&PathBuf::from("stair_test.obj"));
}

#[test]
Expand All @@ -833,15 +863,16 @@ mod tests {
let bunny_mesh = TriMesh::with_flags(
position
.iter()
.map(|v| Point3::new(v[0] as f64, v[1] as f64, v[2] as f64))
.map(|v| Point3::new(v[0] as Real, v[1] as Real, v[2] as Real))
.collect::<Vec<_>>(),
objects[0].groups[0]
.polys
.iter()
.map(|p| [p.0[0].0 as u32, p.0[1].0 as u32, p.0[2].0 as u32])
.collect::<Vec<_>>(),
TriMeshFlags::all(),
);
)
.unwrap();

let Obj {
data: ObjData {
Expand All @@ -853,15 +884,16 @@ mod tests {
let cylinder_mesh = TriMesh::with_flags(
position
.iter()
.map(|v| Point3::new(v[0] as f64, v[1] as f64, v[2] as f64))
.map(|v| Point3::new(v[0] as Real, v[1] as Real, v[2] as Real))
.collect::<Vec<_>>(),
objects[0].groups[0]
.polys
.iter()
.map(|p| [p.0[0].0 as u32, p.0[1].0 as u32, p.0[2].0 as u32])
.collect::<Vec<_>>(),
TriMeshFlags::all(),
);
)
.unwrap();

let res = intersect_meshes(
&Isometry::identity(),
Expand All @@ -874,6 +906,6 @@ mod tests {
.unwrap()
.unwrap();

res.to_obj_file(&PathBuf::from("complex_test.obj"));
let _ = res.to_obj_file(&PathBuf::from("complex_test.obj"));
}
}
2 changes: 1 addition & 1 deletion src/transformation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ mod to_trimesh;
pub mod utils;

#[cfg(feature = "wavefront")]
pub mod wavefront;
mod wavefront;
8 changes: 6 additions & 2 deletions src/transformation/wavefront.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@ use obj::{Group, IndexTuple, ObjData, ObjError, Object, SimplePolygon};
use std::path::PathBuf;

impl TriMesh {
/// Outputs a Wavefront (`.obj`) file at the given path.
///
/// This function is enabled by the `wavefront` feature flag.
pub fn to_obj_file(&self, path: &PathBuf) -> Result<(), ObjError> {
let mut file = std::fs::File::create(path).unwrap();

ObjData {
#[expect(clippy::unnecessary_cast)]
position: self
.vertices()
.into_iter()
.iter()
.map(|v| [v.x as f32, v.y as f32, v.z as f32])
.collect(),
objects: vec![Object {
groups: vec![Group {
polys: self
.indices()
.into_iter()
.iter()
.map(|tri| {
SimplePolygon(vec![
IndexTuple(tri[0] as usize, None, None),
Expand Down

0 comments on commit 22a4261

Please sign in to comment.