Skip to content

Commit

Permalink
address review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
EmbersArc authored and sebcrozet committed Nov 1, 2021
1 parent 76d9e64 commit d913a2f
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 40 deletions.
27 changes: 27 additions & 0 deletions src/shape/compound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
use crate::bounding_volume::{BoundingSphere, BoundingVolume, AABB};
use crate::math::{Isometry, Real};
use crate::partitioning::QBVH;
#[cfg(feature = "dim2")]
use crate::shape::{ConvexPolygon, TriMesh, Triangle};
use crate::shape::{Shape, SharedShape, SimdCompositeShape, TypedSimdCompositeShape};
#[cfg(feature = "dim2")]
use crate::transformation::hertel_mehlhorn;

/// A compound shape with an aabb bounding volume.
///
Expand Down Expand Up @@ -59,6 +63,29 @@ impl Compound {
aabb,
}
}

#[cfg(feature = "dim2")]
/// Create a compound shape from the `TriMesh`. This involves merging adjacent triangles into convex
/// polygons using the Hertel-Mehlhorn algorithm.
///
/// Can fail and return `None` if any of the created shapes has close to zero or zero surface area.
pub fn decompose_trimesh(&self, trimesh: &TriMesh) -> Option<Self> {
let polygons = hertel_mehlhorn(trimesh.vertices(), trimesh.indices());
let shapes: Option<Vec<_>> = polygons
.into_iter()
.map(|points| {
match points.len() {
3 => {
let triangle = Triangle::new(points[0], points[1], points[2]);
Some(SharedShape::new(triangle))
}
_ => ConvexPolygon::from_convex_polyline(points).map(SharedShape::new),
}
.map(|shape| (Isometry::identity(), shape))
})
.collect();
Some(Self::new(shapes?))
}
}

impl Compound {
Expand Down
37 changes: 0 additions & 37 deletions src/shape/trimesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ use crate::bounding_volume::AABB;
use crate::math::{Isometry, Point, Real};
use crate::partitioning::QBVH;
use crate::shape::composite_shape::SimdCompositeShape;
#[cfg(feature = "dim2")]
use crate::shape::{Compound, ConvexPolygon, SharedShape};
use crate::shape::{FeatureId, Shape, Triangle, TypedSimdCompositeShape};
#[cfg(feature = "dim2")]
use crate::transformation::ear_clipping::triangulate_ear_clipping;
#[cfg(feature = "dim2")]
use crate::transformation::hertel_mehlhorn::hertel_mehlhorn;
use crate::utils::hashmap::{Entry, HashMap};
use crate::utils::HashablePartialEq;
#[cfg(feature = "dim3")]
Expand Down Expand Up @@ -87,39 +83,6 @@ impl TriMesh {
triangulate_ear_clipping(&vertices).map(|indices| Self::new(vertices, indices))
}

#[cfg(feature = "dim2")]
/// Create a compound shape from the `TriMesh`. This involves merging adjacent triangles into convex
/// polygons using the Hertel-Mehlhorn algorithm.
///
/// Can fail and return `None` if any of the created shapes has close to zero or zero surface area.
pub fn to_compound(&self) -> Option<Compound> {
let indices = hertel_mehlhorn(self.vertices(), self.indices());
let shapes: Option<Vec<_>> = indices
.into_iter()
.map(|poly_indices| {
match poly_indices.as_slice() {
[i0, i1, i2] => {
let triangle = Triangle::new(
self.vertices()[*i0 as usize],
self.vertices()[*i1 as usize],
self.vertices()[*i2 as usize],
);
Some(SharedShape::new(triangle))
}
i_polygon => {
let vertices = i_polygon
.iter()
.map(|i| self.vertices()[*i as usize])
.collect();
ConvexPolygon::from_convex_polyline(vertices).map(SharedShape::new)
}
}
.map(|shape| (Isometry::identity(), shape))
})
.collect();
Some(Compound::new(shapes?))
}

/// Compute the axis-aligned bounding box of this triangle mesh.
pub fn aabb(&self, pos: &Isometry<Real>) -> AABB {
self.qbvh.root_aabb().transform_by(pos)
Expand Down
19 changes: 16 additions & 3 deletions src/transformation/hertel_mehlhorn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,20 @@ fn find_edge_index_in_polygon(p1: u32, p2: u32, indices: &[u32]) -> Option<(usiz
/// partitioning.
///
/// This algorithm is described in https://people.mpi-inf.mpg.de/~mehlhorn/ftp/FastTriangulation.pdf
pub(crate) fn hertel_mehlhorn(vertices: &[Point<Real>], indices: &[[u32; 3]]) -> Vec<Vec<u32>> {
pub fn hertel_mehlhorn(vertices: &[Point<Real>], indices: &[[u32; 3]]) -> Vec<Vec<Point<Real>>> {
hertel_mehlhorn_idx(vertices, indices)
.into_iter()
.map(|poly_indices| {
poly_indices
.into_iter()
.map(|idx| vertices[idx as usize])
.collect()
})
.collect()
}

/// Internal implementation of the Hertel-Mehlhorn algorithm that returns the polygon indices.
pub fn hertel_mehlhorn_idx(vertices: &[Point<Real>], indices: &[[u32; 3]]) -> Vec<Vec<u32>> {
let mut indices: Vec<Vec<u32>> = indices.iter().map(|indices| indices.to_vec()).collect();
// Iterate over all polygons.
let mut i_poly1 = 0;
Expand Down Expand Up @@ -110,7 +123,7 @@ pub(crate) fn hertel_mehlhorn(vertices: &[Point<Real>], indices: &[[u32; 3]]) ->
// --- Unit tests ----------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use super::hertel_mehlhorn;
use super::hertel_mehlhorn_idx;
use crate::math::Point;

#[test]
Expand Down Expand Up @@ -143,7 +156,7 @@ mod tests {
[2, 0, 1],
];

let indices = hertel_mehlhorn(&vertices, &triangles);
let indices = hertel_mehlhorn_idx(&vertices, &triangles);

let expected_indices = vec![
// (1)
Expand Down
2 changes: 2 additions & 0 deletions src/transformation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub(crate) mod ear_clipping;
#[cfg(feature = "dim2")]
pub(crate) mod hertel_mehlhorn;
#[cfg(feature = "dim2")]
pub use hertel_mehlhorn::{hertel_mehlhorn, hertel_mehlhorn_idx};
#[cfg(feature = "dim2")]
mod to_polyline;
#[cfg(feature = "dim3")]
mod to_trimesh;
Expand Down

0 comments on commit d913a2f

Please sign in to comment.