diff --git a/src/bounding_volume/aabb.rs b/src/bounding_volume/aabb.rs index 1c085a44..c038dd28 100644 --- a/src/bounding_volume/aabb.rs +++ b/src/bounding_volume/aabb.rs @@ -543,8 +543,8 @@ impl BoundingVolume for Aabb { #[inline] fn loosen(&mut self, amount: Real) { assert!(amount >= 0.0, "The loosening margin must be positive."); - self.mins = self.mins + Vector::repeat(-amount); - self.maxs = self.maxs + Vector::repeat(amount); + self.mins += Vector::repeat(-amount); + self.maxs += Vector::repeat(amount); } #[inline] @@ -559,8 +559,8 @@ impl BoundingVolume for Aabb { #[inline] fn tighten(&mut self, amount: Real) { assert!(amount >= 0.0, "The tightening margin must be positive."); - self.mins = self.mins + Vector::repeat(amount); - self.maxs = self.maxs + Vector::repeat(-amount); + self.mins += Vector::repeat(amount); + self.maxs += Vector::repeat(-amount); assert!( na::partial_le(&self.mins, &self.maxs), "The tightening margin is to large." diff --git a/src/bounding_volume/aabb_heightfield.rs b/src/bounding_volume/aabb_heightfield.rs index 67d6fe0a..6338a8f3 100644 --- a/src/bounding_volume/aabb_heightfield.rs +++ b/src/bounding_volume/aabb_heightfield.rs @@ -12,6 +12,6 @@ impl GenericHeightField { /// Computes the local-space [`Aabb`] of this heightfield. #[inline] pub fn local_aabb(&self) -> Aabb { - self.root_aabb().clone() + *self.root_aabb() } } diff --git a/src/bounding_volume/bounding_sphere.rs b/src/bounding_volume/bounding_sphere.rs index 64336d84..75d707da 100644 --- a/src/bounding_volume/bounding_sphere.rs +++ b/src/bounding_volume/bounding_sphere.rs @@ -85,20 +85,17 @@ impl BoundingVolume for BoundingSphere { let s_center_dir = self.center.coords.dot(&dir); let o_center_dir = other.center.coords.dot(&dir); - let right; - let left; - - if s_center_dir + self.radius > o_center_dir + other.radius { - right = self.center + dir * self.radius; + let right = if s_center_dir + self.radius > o_center_dir + other.radius { + self.center + dir * self.radius } else { - right = other.center + dir * other.radius; - } + other.center + dir * other.radius + }; - if -s_center_dir + self.radius > -o_center_dir + other.radius { - left = self.center - dir * self.radius; + let left = if -s_center_dir + self.radius > -o_center_dir + other.radius { + self.center - dir * self.radius } else { - left = other.center - dir * other.radius; - } + other.center - dir * other.radius + }; self.center = na::center(&left, &right); self.radius = na::distance(&right, &self.center); @@ -107,7 +104,7 @@ impl BoundingVolume for BoundingSphere { #[inline] fn merged(&self, other: &BoundingSphere) -> BoundingSphere { - let mut res = self.clone(); + let mut res = *self; res.merge(other); @@ -117,7 +114,7 @@ impl BoundingVolume for BoundingSphere { #[inline] fn loosen(&mut self, amount: Real) { assert!(amount >= 0.0, "The loosening margin must be positive."); - self.radius = self.radius + amount + self.radius += amount } #[inline] @@ -130,7 +127,7 @@ impl BoundingVolume for BoundingSphere { fn tighten(&mut self, amount: Real) { assert!(amount >= 0.0, "The tightening margin must be positive."); assert!(amount <= self.radius, "The tightening margin is to large."); - self.radius = self.radius - amount + self.radius -= amount } #[inline] diff --git a/src/bounding_volume/simd_aabb.rs b/src/bounding_volume/simd_aabb.rs index 89db4bb4..8ac51f2c 100644 --- a/src/bounding_volume/simd_aabb.rs +++ b/src/bounding_volume/simd_aabb.rs @@ -323,10 +323,10 @@ impl SimdAabb { /// result between `self.extract(i)` and `other.extract(j)`. pub fn intersects_permutations(&self, other: &SimdAabb) -> [SimdBool; SIMD_WIDTH] { let mut result = [SimdBool::splat(false); SIMD_WIDTH]; - for ii in 0..SIMD_WIDTH { + for (ii, result) in result.iter_mut().enumerate() { // TODO: use SIMD-accelerated shuffling? let extracted = SimdAabb::splat(self.extract(ii)); - result[ii] = extracted.intersects(other); + *result = extracted.intersects(other); } result diff --git a/src/lib.rs b/src/lib.rs index 6889900b..24cfa7ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,10 @@ the rust programming language. #![warn(missing_docs)] // TODO: deny this #![warn(unused_imports)] #![allow(missing_copy_implementations)] +#![allow(clippy::too_many_arguments)] // Maybe revisit this one later. +#![allow(clippy::module_inception)] +#![allow(clippy::manual_range_contains)] // This usually makes it way more verbose that it could be. +#![allow(clippy::type_complexity)] // Complains about closures that are fairly simple. #![doc(html_root_url = "http://docs.rs/parry/0.1.1")] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "rkyv"), deny(unused_qualifications))] // TODO: deny that everytime diff --git a/src/partitioning/qbvh/mod.rs b/src/partitioning/qbvh/mod.rs index cd72717b..1995b25b 100644 --- a/src/partitioning/qbvh/mod.rs +++ b/src/partitioning/qbvh/mod.rs @@ -11,7 +11,7 @@ pub use self::storage::QbvhStorage; mod qbvh; mod storage; -pub(self) mod utils; +mod utils; #[cfg(feature = "std")] mod build; diff --git a/src/partitioning/qbvh/qbvh.rs b/src/partitioning/qbvh/qbvh.rs index 1095ea86..3015c314 100644 --- a/src/partitioning/qbvh/qbvh.rs +++ b/src/partitioning/qbvh/qbvh.rs @@ -46,7 +46,7 @@ impl IndexedData for u32 { impl IndexedData for u64 { fn default() -> Self { - u64::MAX as u64 + u64::MAX } fn index(&self) -> usize { *self as usize @@ -307,6 +307,13 @@ impl CudaQbvh { } } +#[cfg(feature = "std")] +impl Default for Qbvh { + fn default() -> Self { + Self::new() + } +} + #[cfg(feature = "std")] impl Qbvh { /// Initialize an empty Qbvh. diff --git a/src/partitioning/qbvh/traversal.rs b/src/partitioning/qbvh/traversal.rs index 62f86a4e..dcdaf792 100644 --- a/src/partitioning/qbvh/traversal.rs +++ b/src/partitioning/qbvh/traversal.rs @@ -1,3 +1,5 @@ +#![allow(clippy::needless_range_loop)] // This tends to make the traversal code much more verbose that necessary. + use crate::bounding_volume::{Aabb, SimdAabb}; use crate::math::Real; use crate::partitioning::visitor::SimdSimultaneousVisitStatus; @@ -91,14 +93,12 @@ impl> GenericQbvh> GenericQbvh> GenericQbvh> GenericQbvh> GenericQbvh> GenericQbvh> GenericQbvh Qbvh { // If we reached this point, we didn’t find room for our // new proxy. Create a new root to make more room. - let mut old_root = self.nodes[0].clone(); + let mut old_root = self.nodes[0]; old_root.parent = NodeIndex::new(0, 0); for child_id in old_root.children { @@ -569,7 +569,7 @@ impl Qbvh { let nid = if let Some(nid) = self.free_list.pop() { self.nodes[nid as usize] = node; - nid as u32 + nid } else { let nid = self.nodes.len(); self.nodes.push(node); diff --git a/src/partitioning/qbvh/update/tests.rs b/src/partitioning/qbvh/update/tests.rs index b3572722..36ce24bd 100644 --- a/src/partitioning/qbvh/update/tests.rs +++ b/src/partitioning/qbvh/update/tests.rs @@ -137,7 +137,7 @@ fn test_qbvh_random_operations( qbvh.check_topology(); } else { // remove aabb - if added_aabb_indices.len() == 0 { + if added_aabb_indices.is_empty() { continue; } let aabb_index = diff --git a/src/query/closest_points/closest_points_segment_segment.rs b/src/query/closest_points/closest_points_segment_segment.rs index 903cc3f9..259f8ec0 100644 --- a/src/query/closest_points/closest_points_segment_segment.rs +++ b/src/query/closest_points/closest_points_segment_segment.rs @@ -51,24 +51,21 @@ pub fn closest_points_segment_segment_with_locations_nD( let e = d2.norm_squared(); let f = d2.dot(&r); - let _0: Real = 0.0; - let _1: Real = 1.0; - let mut s; let mut t; let _eps = crate::math::DEFAULT_EPSILON; if a <= _eps && e <= _eps { - s = _0; - t = _0; + s = 0.0; + t = 0.0; } else if a <= _eps { - s = _0; - t = na::clamp(f / e, _0, _1); + s = 0.0; + t = na::clamp(f / e, 0.0, 1.0); } else { let c = d1.dot(&r); if e <= _eps { - t = _0; - s = na::clamp(-c / a, _0, _1); + t = 0.0; + s = na::clamp(-c / a, 0.0, 1.0); } else { let b = d1.dot(&d2); let ae = a * e; @@ -77,37 +74,37 @@ pub fn closest_points_segment_segment_with_locations_nD( // Use absolute and ulps error to test collinearity. if denom > _eps && !ulps_eq!(ae, bb) { - s = na::clamp((b * f - c * e) / denom, _0, _1); + s = na::clamp((b * f - c * e) / denom, 0.0, 1.0); } else { - s = _0; + s = 0.0; } t = (b * s + f) / e; - if t < _0 { - t = _0; - s = na::clamp(-c / a, _0, _1); - } else if t > _1 { - t = _1; - s = na::clamp((b - c) / a, _0, _1); + if t < 0.0 { + t = 0.0; + s = na::clamp(-c / a, 0.0, 1.0); + } else if t > 1.0 { + t = 1.0; + s = na::clamp((b - c) / a, 0.0, 1.0); } } } - let loc1 = if s == _0 { + let loc1 = if s == 0.0 { SegmentPointLocation::OnVertex(0) - } else if s == _1 { + } else if s == 1.0 { SegmentPointLocation::OnVertex(1) } else { - SegmentPointLocation::OnEdge([_1 - s, s]) + SegmentPointLocation::OnEdge([1.0 - s, s]) }; - let loc2 = if t == _0 { + let loc2 = if t == 0.0 { SegmentPointLocation::OnVertex(0) - } else if t == _1 { + } else if t == 1.0 { SegmentPointLocation::OnVertex(1) } else { - SegmentPointLocation::OnEdge([_1 - t, t]) + SegmentPointLocation::OnEdge([1.0 - t, t]) }; (loc1, loc2) diff --git a/src/query/contact/contact_ball_convex_polyhedron.rs b/src/query/contact/contact_ball_convex_polyhedron.rs index 1cd6fd43..15786941 100644 --- a/src/query/contact/contact_ball_convex_polyhedron.rs +++ b/src/query/contact/contact_ball_convex_polyhedron.rs @@ -49,7 +49,7 @@ pub fn contact_convex_polyhedron_ball( normal1 = shape1 .feature_normal_at_point(f1, &proj.point) .or_else(|| Unit::try_new(proj.point.coords, crate::math::DEFAULT_EPSILON)) - .unwrap_or_else(|| Vector::y_axis()); + .unwrap_or_else(Vector::y_axis); } if dist <= prediction { diff --git a/src/query/contact_manifolds/contact_manifold.rs b/src/query/contact_manifolds/contact_manifold.rs index e1560fce..e54f0ef6 100644 --- a/src/query/contact_manifolds/contact_manifold.rs +++ b/src/query/contact_manifolds/contact_manifold.rs @@ -70,7 +70,7 @@ impl TrackedContact { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] /// A contact manifold between two shapes. /// @@ -113,7 +113,7 @@ impl ContactManifold ContactManifold, data: &dyn Fn() -> ManifoldData, ) -> &'a mut Self { - if manifolds.len() == 0 { + if manifolds.is_empty() { let manifold_data = data(); manifolds.push(ContactManifold::with_data((0, 0), manifold_data)); } @@ -194,7 +194,7 @@ impl ContactManifold bool { - if self.points.len() == 0 { + if self.points.is_empty() { return false; } @@ -267,7 +267,7 @@ impl ContactManifold Option<&TrackedContact> { - let mut deepest = self.points.get(0)?; + let mut deepest = self.points.first()?; for pt in &self.points { if pt.dist < deepest.dist { diff --git a/src/query/contact_manifolds/contact_manifolds_ball_ball.rs b/src/query/contact_manifolds/contact_manifolds_ball_ball.rs index c06aaafc..2cbcd761 100644 --- a/src/query/contact_manifolds/contact_manifolds_ball_ball.rs +++ b/src/query/contact_manifolds/contact_manifolds_ball_ball.rs @@ -43,7 +43,7 @@ pub fn contact_manifold_ball_ball( let fid = PackedFeatureId::face(0); let contact = TrackedContact::new(local_p1.into(), local_p2.into(), fid, fid, dist); - if manifold.points.len() != 0 { + if !manifold.points.is_empty() { manifold.points[0].copy_geometry_from(contact); } else { manifold.points.push(contact); diff --git a/src/query/contact_manifolds/contact_manifolds_capsule_capsule.rs b/src/query/contact_manifolds/contact_manifolds_capsule_capsule.rs index 1c823349..15db535d 100644 --- a/src/query/contact_manifolds/contact_manifolds_capsule_capsule.rs +++ b/src/query/contact_manifolds/contact_manifolds_capsule_capsule.rs @@ -171,7 +171,7 @@ pub fn contact_manifold_capsule_capsule<'a, ManifoldData, ContactData>( dist, ); - if manifold.points.len() != 0 { + if !manifold.points.is_empty() { manifold.points[0].copy_geometry_from(contact); } else { manifold.points.push(contact); diff --git a/src/query/contact_manifolds/contact_manifolds_composite_shape_composite_shape.rs b/src/query/contact_manifolds/contact_manifolds_composite_shape_composite_shape.rs index 52641aa3..a653f7ff 100644 --- a/src/query/contact_manifolds/contact_manifolds_composite_shape_composite_shape.rs +++ b/src/query/contact_manifolds/contact_manifolds_composite_shape_composite_shape.rs @@ -24,7 +24,7 @@ struct SubDetector { } #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] -#[derive(Clone)] +#[derive(Clone, Default)] pub struct CompositeShapeCompositeShapeContactManifoldsWorkspace { timestamp: bool, sub_detectors: HashMap<(u32, u32), SubDetector>, @@ -32,10 +32,7 @@ pub struct CompositeShapeCompositeShapeContactManifoldsWorkspace { impl CompositeShapeCompositeShapeContactManifoldsWorkspace { pub fn new() -> Self { - Self { - timestamp: false, - sub_detectors: HashMap::default(), - } + Self::default() } } diff --git a/src/query/contact_manifolds/contact_manifolds_composite_shape_shape.rs b/src/query/contact_manifolds/contact_manifolds_composite_shape_shape.rs index 31037e93..16a68d63 100644 --- a/src/query/contact_manifolds/contact_manifolds_composite_shape_shape.rs +++ b/src/query/contact_manifolds/contact_manifolds_composite_shape_shape.rs @@ -24,7 +24,7 @@ struct SubDetector { } #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] -#[derive(Clone)] +#[derive(Clone, Default)] pub struct CompositeShapeShapeContactManifoldsWorkspace { timestamp: bool, sub_detectors: HashMap, @@ -32,10 +32,7 @@ pub struct CompositeShapeShapeContactManifoldsWorkspace { impl CompositeShapeShapeContactManifoldsWorkspace { pub fn new() -> Self { - Self { - timestamp: false, - sub_detectors: HashMap::default(), - } + Self::default() } } diff --git a/src/query/contact_manifolds/contact_manifolds_convex_ball.rs b/src/query/contact_manifolds/contact_manifolds_convex_ball.rs index 108b50b7..18c194c3 100644 --- a/src/query/contact_manifolds/contact_manifolds_convex_ball.rs +++ b/src/query/contact_manifolds/contact_manifolds_convex_ball.rs @@ -40,7 +40,7 @@ pub fn contact_manifold_convex_ball<'a, ManifoldData, ContactData, S1>( // shape's origin towards our origin if defined, otherwise towards +x let (mut local_n1, mut dist) = Unit::try_new_and_get(dpos, 0.0).unwrap_or_else(|| { ( - Unit::try_new(pos12.translation.vector, 0.0).unwrap_or_else(|| Vector::x_axis()), + Unit::try_new(pos12.translation.vector, 0.0).unwrap_or_else(Vector::x_axis), 0.0, ) }); diff --git a/src/query/contact_manifolds/contact_manifolds_cuboid_cuboid.rs b/src/query/contact_manifolds/contact_manifolds_cuboid_cuboid.rs index 5c31e91c..2cbf6018 100644 --- a/src/query/contact_manifolds/contact_manifolds_cuboid_cuboid.rs +++ b/src/query/contact_manifolds/contact_manifolds_cuboid_cuboid.rs @@ -30,7 +30,6 @@ pub fn contact_manifold_cuboid_cuboid<'a, ManifoldData, ContactData: Default + C } let pos21 = &pos12.inverse(); - let pos12 = &*pos12; /* * diff --git a/src/query/contact_manifolds/contact_manifolds_heightfield_composite_shape.rs b/src/query/contact_manifolds/contact_manifolds_heightfield_composite_shape.rs index e1c6afaa..87764c83 100644 --- a/src/query/contact_manifolds/contact_manifolds_heightfield_composite_shape.rs +++ b/src/query/contact_manifolds/contact_manifolds_heightfield_composite_shape.rs @@ -29,7 +29,7 @@ struct SubDetector { } #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] -#[derive(Clone)] +#[derive(Clone, Default)] pub struct HeightFieldCompositeShapeContactManifoldsWorkspace { timestamp: bool, sub_detectors: HashMap<(u32, u32), SubDetector>, @@ -39,12 +39,7 @@ pub struct HeightFieldCompositeShapeContactManifoldsWorkspace { impl HeightFieldCompositeShapeContactManifoldsWorkspace { pub fn new() -> Self { - Self { - timestamp: false, - sub_detectors: HashMap::default(), - #[cfg(feature = "dim3")] - internal_edges: InternalEdgesFixer::default(), - } + Self::default() } } @@ -102,7 +97,7 @@ pub fn contact_manifolds_heightfield_composite_shape( let ls_aabb1_2 = part1.compute_aabb(pos21).loosened(prediction); let mut leaf_fn2 = |leaf2: &u32| { composite2.map_part_at(*leaf2, &mut |part_pos2, part_shape2| { - let sub_detector = match workspace.sub_detectors.entry((leaf1 as u32, *leaf2)) { + let sub_detector = match workspace.sub_detectors.entry((leaf1, *leaf2)) { Entry::Occupied(entry) => { let sub_detector = entry.into_mut(); let manifold = old_manifolds[sub_detector.manifold_id].take(); @@ -121,10 +116,10 @@ pub fn contact_manifolds_heightfield_composite_shape( if flipped { manifold.subshape1 = *leaf2; - manifold.subshape2 = leaf1 as u32; + manifold.subshape2 = leaf1; manifold.subshape_pos1 = part_pos2.copied(); } else { - manifold.subshape1 = leaf1 as u32; + manifold.subshape1 = leaf1; manifold.subshape2 = *leaf2; manifold.subshape_pos2 = part_pos2.copied(); }; diff --git a/src/query/contact_manifolds/contact_manifolds_heightfield_shape.rs b/src/query/contact_manifolds/contact_manifolds_heightfield_shape.rs index 1ea8a641..15e517b6 100644 --- a/src/query/contact_manifolds/contact_manifolds_heightfield_shape.rs +++ b/src/query/contact_manifolds/contact_manifolds_heightfield_shape.rs @@ -27,7 +27,7 @@ struct SubDetector { } #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] -#[derive(Clone)] +#[derive(Clone, Default)] pub struct HeightFieldShapeContactManifoldsWorkspace { timestamp: bool, sub_detectors: HashMap, @@ -37,12 +37,7 @@ pub struct HeightFieldShapeContactManifoldsWorkspace { impl HeightFieldShapeContactManifoldsWorkspace { pub fn new() -> Self { - Self { - timestamp: false, - sub_detectors: HashMap::default(), - #[cfg(feature = "dim3")] - internal_edges: InternalEdgesFixer::default(), - } + Self::default() } } diff --git a/src/query/contact_manifolds/contact_manifolds_trimesh_shape.rs b/src/query/contact_manifolds/contact_manifolds_trimesh_shape.rs index 0d7e2ac2..3516c935 100644 --- a/src/query/contact_manifolds/contact_manifolds_trimesh_shape.rs +++ b/src/query/contact_manifolds/contact_manifolds_trimesh_shape.rs @@ -22,6 +22,12 @@ pub struct TriMeshShapeContactManifoldsWorkspace { internal_edges: InternalEdgesFixer, } +impl Default for TriMeshShapeContactManifoldsWorkspace { + fn default() -> Self { + Self::new() + } +} + impl TriMeshShapeContactManifoldsWorkspace { pub fn new() -> Self { Self { diff --git a/src/query/contact_manifolds/internal_edges_fixer.rs b/src/query/contact_manifolds/internal_edges_fixer.rs index a950922c..7df434af 100644 --- a/src/query/contact_manifolds/internal_edges_fixer.rs +++ b/src/query/contact_manifolds/internal_edges_fixer.rs @@ -22,7 +22,7 @@ impl InternalEdgesFixer { #[cfg(feature = "dim2")] pub fn remove_invalid_contacts( &mut self, - _manifolds: &mut Vec>, + _manifolds: &mut [ContactManifold], _flipped: bool, _get_triangle: impl Fn(u32) -> Triangle, _get_triangle_indices: impl Fn(u32) -> [u32; 3], @@ -36,7 +36,7 @@ impl InternalEdgesFixer { #[cfg(feature = "dim3")] pub fn remove_invalid_contacts( &mut self, - manifolds: &mut Vec>, + manifolds: &mut [ContactManifold], flipped: bool, get_triangle: impl Fn(u32) -> Triangle, get_triangle_indices: impl Fn(u32) -> [u32; 3], diff --git a/src/query/contact_manifolds/mod.rs b/src/query/contact_manifolds/mod.rs index 47f63ca5..3be0ed42 100644 --- a/src/query/contact_manifolds/mod.rs +++ b/src/query/contact_manifolds/mod.rs @@ -36,7 +36,7 @@ pub use self::contact_manifolds_workspace::{ ContactManifoldsWorkspace, TypedWorkspaceData, WorkspaceData, }; -pub(self) use { +use { self::contact_manifolds_composite_shape_composite_shape::CompositeShapeCompositeShapeContactManifoldsWorkspace, self::contact_manifolds_composite_shape_shape::CompositeShapeShapeContactManifoldsWorkspace, self::contact_manifolds_heightfield_composite_shape::HeightFieldCompositeShapeContactManifoldsWorkspace, diff --git a/src/query/contact_manifolds/polygon_polygon_contact_generator.rs b/src/query/contact_manifolds/polygon_polygon_contact_generator.rs index 934a64b3..ac2c60f8 100644 --- a/src/query/contact_manifolds/polygon_polygon_contact_generator.rs +++ b/src/query/contact_manifolds/polygon_polygon_contact_generator.rs @@ -92,7 +92,7 @@ fn generate_contacts<'a>( ((support_face2 * 2 + clip_b.3) % (len2 * 2)) as u8, ); - if manifold.points.len() != 0 { + if !manifold.points.is_empty() { assert_eq!(manifold.points.len(), 2); // We already had 2 points in the previous iteration. diff --git a/src/query/distance/distance_composite_shape_shape.rs b/src/query/distance/distance_composite_shape_shape.rs index 59244932..1e7b2e18 100644 --- a/src/query/distance/distance_composite_shape_shape.rs +++ b/src/query/distance/distance_composite_shape_shape.rs @@ -109,17 +109,14 @@ where .distance(&part_pos1.inv_mul(self.pos12), g1, self.g2); }); - match dist { - Ok(dist) => { - if dist == 0.0 { - return SimdBestFirstVisitStatus::ExitEarly(Some((part_id, 0.0))); - } else { - weights[ii] = dist; - mask[ii] = dist < best; - results[ii] = Some((part_id, dist)); - } + if let Ok(dist) = dist { + if dist == 0.0 { + return SimdBestFirstVisitStatus::ExitEarly(Some((part_id, 0.0))); + } else { + weights[ii] = dist; + mask[ii] = dist < best; + results[ii] = Some((part_id, dist)); } - Err(_) => {} } } } diff --git a/src/query/epa/epa2.rs b/src/query/epa/epa2.rs index dac3476a..eb79d3a4 100644 --- a/src/query/epa/epa2.rs +++ b/src/query/epa/epa2.rs @@ -32,7 +32,7 @@ impl Eq for FaceId {} impl PartialOrd for FaceId { #[inline] fn partial_cmp(&self, other: &Self) -> Option { - self.neg_dist.partial_cmp(&other.neg_dist) + Some(self.cmp(other)) } } @@ -110,6 +110,7 @@ impl Face { } /// The Expanding Polytope Algorithm in 2D. +#[derive(Default)] pub struct EPA { vertices: Vec, faces: Vec, @@ -119,11 +120,7 @@ pub struct EPA { impl EPA { /// Creates a new instance of the 2D Expanding Polytope Algorithm. pub fn new() -> Self { - EPA { - vertices: Vec::new(), - faces: Vec::new(), - heap: BinaryHeap::new(), - } + EPA::default() } fn reset(&mut self) { diff --git a/src/query/epa/epa3.rs b/src/query/epa/epa3.rs index bea8597e..ac6d3718 100644 --- a/src/query/epa/epa3.rs +++ b/src/query/epa/epa3.rs @@ -31,7 +31,7 @@ impl Eq for FaceId {} impl PartialOrd for FaceId { #[inline] fn partial_cmp(&self, other: &Self) -> Option { - self.neg_dist.partial_cmp(&other.neg_dist) + Some(self.cmp(other)) } } @@ -159,6 +159,7 @@ impl SilhouetteEdge { } /// The Expanding Polytope Algorithm in 3D. +#[derive(Default)] pub struct EPA { vertices: Vec, faces: Vec, @@ -169,12 +170,7 @@ pub struct EPA { impl EPA { /// Creates a new instance of the 3D Expanding Polytope Algorithm. pub fn new() -> Self { - EPA { - vertices: Vec::new(), - faces: Vec::new(), - silhouette: Vec::new(), - heap: BinaryHeap::new(), - } + Self::default() } fn reset(&mut self) { @@ -358,7 +354,7 @@ impl EPA { let first_new_face_id = self.faces.len(); - if self.silhouette.len() == 0 { + if self.silhouette.is_empty() { // FIXME: Something went very wrong because we failed to extract a silhouette… return None; } @@ -460,7 +456,7 @@ impl EPA { ); } } - println!(""); + println!(); } #[allow(dead_code)] diff --git a/src/query/gjk/gjk.rs b/src/query/gjk/gjk.rs index 3ba616de..97f48055 100644 --- a/src/query/gjk/gjk.rs +++ b/src/query/gjk/gjk.rs @@ -137,7 +137,7 @@ where let cso_point = CSOPoint::from_shapes(pos12, g1, g2, &dir); let min_bound = -dir.dot(&cso_point.point.coords); - assert!(min_bound == min_bound); + assert!(min_bound.is_finite()); if min_bound > max_dist { return GJKResult::NoIntersection(dir); @@ -332,7 +332,7 @@ where let min_bound = -dir.dot(&(support_point.point.coords - curr_ray.origin.coords)); - assert!(min_bound == min_bound); + assert!(min_bound.is_finite()); if max_bound - min_bound <= _eps_rel * max_bound { // This is needed when using fixed-points to avoid missing diff --git a/src/query/gjk/voronoi_simplex2.rs b/src/query/gjk/voronoi_simplex2.rs index 891c8c4d..a7c59115 100644 --- a/src/query/gjk/voronoi_simplex2.rs +++ b/src/query/gjk/voronoi_simplex2.rs @@ -15,6 +15,12 @@ pub struct VoronoiSimplex { dim: usize, } +impl Default for VoronoiSimplex { + fn default() -> Self { + Self::new() + } +} + impl VoronoiSimplex { /// Crates a new empty simplex. pub fn new() -> VoronoiSimplex { diff --git a/src/query/gjk/voronoi_simplex3.rs b/src/query/gjk/voronoi_simplex3.rs index 44f07ff9..f510f021 100644 --- a/src/query/gjk/voronoi_simplex3.rs +++ b/src/query/gjk/voronoi_simplex3.rs @@ -21,6 +21,12 @@ pub struct VoronoiSimplex { dim: usize, } +impl Default for VoronoiSimplex { + fn default() -> Self { + Self::new() + } +} + impl VoronoiSimplex { /// Creates a new empty simplex. pub fn new() -> VoronoiSimplex { diff --git a/src/query/intersection_test/intersection_test_composite_shape_shape.rs b/src/query/intersection_test/intersection_test_composite_shape_shape.rs index f28148f7..9cc4d90d 100644 --- a/src/query/intersection_test/intersection_test_composite_shape_shape.rs +++ b/src/query/intersection_test/intersection_test_composite_shape_shape.rs @@ -95,9 +95,10 @@ where let bitmask = mask.bitmask(); let mut found_intersection = false; - for ii in 0..SIMD_WIDTH { - if (bitmask & (1 << ii)) != 0 && data[ii].is_some() { - let part_id = *data[ii].unwrap(); + for (ii, data) in data.into_iter().enumerate() { + if (bitmask & (1 << ii)) != 0 { + let Some(data) = data else { continue }; + let part_id = *data; self.g1.map_untyped_part_at(part_id, |part_pos1, g1| { found_intersection = self.dispatcher.intersection_test( &part_pos1.inv_mul(self.pos12), @@ -181,9 +182,9 @@ where let bitmask = mask.bitmask(); let mut found_intersection = false; - for ii in 0..SIMD_WIDTH { - if (bitmask & (1 << ii)) != 0 && data[ii].is_some() { - let part_id = *data[ii].unwrap(); + for (ii, data) in data.into_iter().enumerate() { + if (bitmask & (1 << ii)) != 0 && data.is_some() { + let part_id = *data.unwrap(); self.g1.map_untyped_part_at(part_id, |part_pos1, g1| { found_intersection = self.dispatcher.intersection_test( &part_pos1.inv_mul(self.pos12), diff --git a/src/query/nonlinear_time_of_impact/nonlinear_rigid_motion.rs b/src/query/nonlinear_time_of_impact/nonlinear_rigid_motion.rs index 0f6a14b7..3a9e2de9 100644 --- a/src/query/nonlinear_time_of_impact/nonlinear_rigid_motion.rs +++ b/src/query/nonlinear_time_of_impact/nonlinear_rigid_motion.rs @@ -87,7 +87,7 @@ impl NonlinearRigidMotion { /// Appends a constant translation to this rigid-motion. #[must_use] pub fn append_translation(&self, tra: Vector) -> Self { - let mut result = self.clone(); + let mut result = *self; result.set_start(Translation::from(tra) * result.start); result } @@ -95,7 +95,7 @@ impl NonlinearRigidMotion { /// Prepends a constant translation to this rigid-motion. #[must_use] pub fn prepend_translation(&self, tra: Vector) -> Self { - let mut result = self.clone(); + let mut result = *self; result.set_start(result.start * Translation::from(tra)); result } @@ -103,7 +103,7 @@ impl NonlinearRigidMotion { /// Appends a constant isometry to this rigid-motion. #[must_use] pub fn append(&self, iso: Isometry) -> Self { - let mut result = self.clone(); + let mut result = *self; result.set_start(iso * result.start); result } @@ -111,7 +111,7 @@ impl NonlinearRigidMotion { /// Prepends a constant translation to this rigid-motion. #[must_use] pub fn prepend(&self, iso: Isometry) -> Self { - let mut result = self.clone(); + let mut result = *self; result.set_start(result.start * iso); result } diff --git a/src/query/point/point_segment.rs b/src/query/point/point_segment.rs index 90c2cf59..3968548f 100644 --- a/src/query/point/point_segment.rs +++ b/src/query/point/point_segment.rs @@ -55,7 +55,6 @@ impl PointQueryWithLocation for Segment { let ap = pt - self.a; let ab_ap = ab.dot(&ap); let sqnab = ab.norm_squared(); - let _1 = 1.0; let proj; let location; @@ -73,7 +72,7 @@ impl PointQueryWithLocation for Segment { // Voronoï region of the segment interior. let u = ab_ap / sqnab; - let bcoords = [_1 - u, u]; + let bcoords = [1.0 - u, u]; location = SegmentPointLocation::OnEdge(bcoords); proj = self.a + ab * u; } diff --git a/src/query/point/point_tetrahedron.rs b/src/query/point/point_tetrahedron.rs index 9964937e..2ace3e08 100644 --- a/src/query/point/point_tetrahedron.rs +++ b/src/query/point/point_tetrahedron.rs @@ -46,9 +46,7 @@ impl PointQueryWithLocation for Tetrahedron { let ap_ac = ap.dot(&ac); let ap_ad = ap.dot(&ad); - let _0: Real = 0.0; - - if ap_ab <= _0 && ap_ac <= _0 && ap_ad <= _0 { + if ap_ab <= 0.0 && ap_ac <= 0.0 && ap_ad <= 0.0 { // Voronoï region of `a`. let proj = PointProjection::new(false, self.a); return (proj, TetrahedronPointLocation::OnVertex(0)); @@ -62,7 +60,7 @@ impl PointQueryWithLocation for Tetrahedron { let bp_bd = bp.dot(&bd); let bp_ab = bp.dot(&ab); - if bp_bc <= _0 && bp_bd <= _0 && bp_ab >= _0 { + if bp_bc <= 0.0 && bp_bd <= 0.0 && bp_ab >= 0.0 { // Voronoï region of `b`. let proj = PointProjection::new(false, self.b); return (proj, TetrahedronPointLocation::OnVertex(1)); @@ -75,7 +73,7 @@ impl PointQueryWithLocation for Tetrahedron { let cp_bc = cp.dot(&bc); let cp_cd = cp.dot(&cd); - if cp_cd <= _0 && cp_bc >= _0 && cp_ac >= _0 { + if cp_cd <= 0.0 && cp_bc >= 0.0 && cp_ac >= 0.0 { // Voronoï region of `c`. let proj = PointProjection::new(false, self.c); return (proj, TetrahedronPointLocation::OnVertex(2)); @@ -87,7 +85,7 @@ impl PointQueryWithLocation for Tetrahedron { let dp_bd = dp.dot(&bd); let dp_ad = dp.dot(&ad); - if dp_ad >= _0 && dp_bd >= _0 && dp_cd >= _0 { + if dp_ad >= 0.0 && dp_bd >= 0.0 && dp_cd >= 0.0 { // Voronoï region of `d`. let proj = PointProjection::new(false, self.d); return (proj, TetrahedronPointLocation::OnVertex(3)); @@ -112,9 +110,6 @@ impl PointQueryWithLocation for Tetrahedron { Real, Option<(PointProjection, TetrahedronPointLocation)>, ) { - let _0: Real = 0.0; - let _1: Real = 1.0; - let ab_ab = ap_ab - bp_ab; // NOTE: The following avoids the subsequent cross and dot products but are not @@ -127,11 +122,11 @@ impl PointQueryWithLocation for Tetrahedron { let dabc = ap_x_ab.dot(nabc); let dabd = ap_x_ab.dot(nabd); - // TODO: the case where ab_ab == _0 is not well defined. - if ab_ab != _0 && dabc >= _0 && dabd >= _0 && ap_ab >= _0 && ap_ab <= ab_ab { + // TODO: the case where ab_ab == 0.0 is not well defined. + if ab_ab != 0.0 && dabc >= 0.0 && dabd >= 0.0 && ap_ab >= 0.0 && ap_ab <= ab_ab { // Voronoi region of `ab`. let u = ap_ab / ab_ab; - let bcoords = [_1 - u, u]; + let bcoords = [1.0 - u, u]; let res = a + ab * u; let proj = PointProjection::new(false, res); ( @@ -258,12 +253,9 @@ impl PointQueryWithLocation for Tetrahedron { /* ap_ab: Real, bp_ab: Real, cp_ab: Real, ap_ac: Real, bp_ac: Real, cp_ac: Real, */ ) -> Option<(PointProjection, TetrahedronPointLocation)> { - let _0: Real = 0.0; - let _1: Real = 1.0; - - if dabc < _0 && dbca < _0 && dacb < _0 { + if dabc < 0.0 && dbca < 0.0 && dacb < 0.0 { let n = ab.cross(ac); // TODO: is is possible to avoid this cross product? - if n.dot(ad) * n.dot(ap) < _0 { + if n.dot(ad) * n.dot(ap) < 0.0 { // Voronoï region of the face. // NOTE: @@ -284,8 +276,8 @@ impl PointQueryWithLocation for Tetrahedron { let vb = normal.dot(&cp.cross(ap)); let denom = va + vb + vc; - assert!(denom != _0); - let inv_denom = _1 / denom; + assert!(denom != 0.0); + let inv_denom = 1.0 / denom; let bcoords = [va * inv_denom, vb * inv_denom, vc * inv_denom]; let res = a * bcoords[0] + b.coords * bcoords[1] + c.coords * bcoords[2]; diff --git a/src/query/point/point_triangle.rs b/src/query/point/point_triangle.rs index ce118645..a37a0c8f 100644 --- a/src/query/point/point_triangle.rs +++ b/src/query/point/point_triangle.rs @@ -64,8 +64,6 @@ impl PointQueryWithLocation for Triangle { let b = self.b; let c = self.c; - let _1 = 1.0; - let ab = b - a; let ac = c - a; let ap = pt - a; @@ -184,7 +182,7 @@ impl PointQueryWithLocation for Triangle { ProjectionInfo::OnAB => { // Voronoï region of `ab`. let v = ab_ap / ab.norm_squared(); - let bcoords = [_1 - v, v]; + let bcoords = [1.0 - v, v]; let res = a + ab * v; return ( @@ -195,7 +193,7 @@ impl PointQueryWithLocation for Triangle { ProjectionInfo::OnAC => { // Voronoï region of `ac`. let w = ac_ap / ac.norm_squared(); - let bcoords = [_1 - w, w]; + let bcoords = [1.0 - w, w]; let res = a + ac * w; return ( @@ -206,7 +204,7 @@ impl PointQueryWithLocation for Triangle { ProjectionInfo::OnBC => { // Voronoï region of `bc`. let w = bc.dot(&bp) / bc.norm_squared(); - let bcoords = [_1 - w, w]; + let bcoords = [1.0 - w, w]; let res = b + bc * w; return ( @@ -221,10 +219,10 @@ impl PointQueryWithLocation for Triangle { // may result in the denominator being zero // when the triangle is nearly degenerate. if va + vb + vc != 0.0 { - let denom = _1 / (va + vb + vc); + let denom = 1.0 / (va + vb + vc); let v = vb * denom; let w = vc * denom; - let bcoords = [_1 - v - w, v, w]; + let bcoords = [1.0 - v - w, v, w]; let res = a + ab * v + ac * w; return ( @@ -263,27 +261,25 @@ impl PointQueryWithLocation for Triangle { if d_ab < d_ac { if d_ab < d_bc { // ab - let bcoords = [_1 - v, v]; + let bcoords = [1.0 - v, v]; proj = a + ab * v; loc = TrianglePointLocation::OnEdge(0, bcoords); } else { // bc - let bcoords = [_1 - u, u]; + let bcoords = [1.0 - u, u]; proj = b + bc * u; loc = TrianglePointLocation::OnEdge(1, bcoords); } + } else if d_ac < d_bc { + // ac + let bcoords = [1.0 - w, w]; + proj = a + ac * w; + loc = TrianglePointLocation::OnEdge(2, bcoords); } else { - if d_ac < d_bc { - // ac - let bcoords = [_1 - w, w]; - proj = a + ac * w; - loc = TrianglePointLocation::OnEdge(2, bcoords); - } else { - // bc - let bcoords = [_1 - u, u]; - proj = b + bc * u; - loc = TrianglePointLocation::OnEdge(1, bcoords); - } + // bc + let bcoords = [1.0 - u, u]; + proj = b + bc * u; + loc = TrianglePointLocation::OnEdge(1, bcoords); } (PointProjection::new(true, proj), loc) diff --git a/src/query/ray/ray_heightfield.rs b/src/query/ray/ray_heightfield.rs index e3cab913..cfd80eee 100644 --- a/src/query/ray/ray_heightfield.rs +++ b/src/query/ray/ray_heightfield.rs @@ -194,7 +194,7 @@ impl RayCast for GenericHeightField { let x = self.x_at(cell.1 + 1); ((x - ray.origin.x) / ray.dir.x, true) } else if ray.dir.x < 0.0 { - let x = self.x_at(cell.1 + 0); + let x = self.x_at(cell.1); ((x - ray.origin.x) / ray.dir.x, false) } else { (Real::max_value(), false) @@ -204,7 +204,7 @@ impl RayCast for GenericHeightField { let z = self.z_at(cell.0 + 1); ((z - ray.origin.z) / ray.dir.z, true) } else if ray.dir.z < 0.0 { - let z = self.z_at(cell.0 + 0); + let z = self.z_at(cell.0); ((z - ray.origin.z) / ray.dir.z, false) } else { (Real::max_value(), false) diff --git a/src/query/ray/ray_triangle.rs b/src/query/ray/ray_triangle.rs index 7d5445ee..2de221aa 100644 --- a/src/query/ray/ray_triangle.rs +++ b/src/query/ray/ray_triangle.rs @@ -34,8 +34,8 @@ impl RayCast for Triangle { let mut best = None; let mut smallest_toi = Real::MAX; - for i in 0..3 { - if let Some(inter) = edges[i].cast_local_ray_and_get_normal(ray, max_toi, solid) { + for edge in &edges { + if let Some(inter) = edge.cast_local_ray_and_get_normal(ray, max_toi, solid) { if inter.toi < smallest_toi { smallest_toi = inter.toi; best = Some(inter); @@ -125,8 +125,8 @@ pub fn local_ray_intersection_with_triangle( let invd = 1.0 / d; toi = -t * invd; normal = -n.normalize(); - v = v * invd; - w = w * invd; + v *= invd; + w *= invd; } else { v = ac.dot(&e); @@ -143,8 +143,8 @@ pub fn local_ray_intersection_with_triangle( let invd = 1.0 / d; toi = t * invd; normal = n.normalize(); - v = v * invd; - w = w * invd; + v *= invd; + w *= invd; } Some(( diff --git a/src/query/split/split_trimesh.rs b/src/query/split/split_trimesh.rs index 90ad67c4..b2e88b5d 100644 --- a/src/query/split/split_trimesh.rs +++ b/src/query/split/split_trimesh.rs @@ -6,6 +6,7 @@ use crate::shape::{Cuboid, FeatureId, Polyline, Segment, Shape, TriMesh, TriMesh use crate::transformation; use crate::utils::{hashmap::HashMap, SortedPair, WBasis}; use spade::{handles::FixedVertexHandle, ConstrainedDelaunayTriangulation, Triangulation as _}; +use std::cmp::Ordering; struct Triangulation { delaunay: ConstrainedDelaunayTriangulation>, @@ -216,8 +217,8 @@ impl TriMesh { let intersection_idx = intersect_edge(idx_a, idx_b); // Compute the indices of the two triangles. - let new_tri_a = [idx_c, idx_a, intersection_idx as u32]; - let new_tri_b = [idx_b, idx_c, intersection_idx as u32]; + let new_tri_a = [idx_c, idx_a, intersection_idx]; + let new_tri_b = [idx_b, idx_c, intersection_idx]; new_indices[tri_id] = new_tri_a; new_indices.push(new_tri_b); @@ -422,10 +423,10 @@ impl TriMesh { let mut add_segment_adjacencies = |idx_a: usize, idx_b| { assert!(idx_a <= index_adjacencies.len()); - if idx_a < index_adjacencies.len() { - index_adjacencies[idx_a].push(idx_b); - } else if idx_a == index_adjacencies.len() { - index_adjacencies.push(vec![idx_b]) + match idx_a.cmp(&index_adjacencies.len()) { + Ordering::Less => index_adjacencies[idx_a].push(idx_b), + Ordering::Equal => index_adjacencies.push(vec![idx_b]), + Ordering::Greater => {} } }; let mut add_segment_adjacencies_symmetric = |idx_a: usize, idx_b| { diff --git a/src/query/time_of_impact/time_of_impact_halfspace_support_map.rs b/src/query/time_of_impact/time_of_impact_halfspace_support_map.rs index dfabfd56..2352d646 100644 --- a/src/query/time_of_impact/time_of_impact_halfspace_support_map.rs +++ b/src/query/time_of_impact/time_of_impact_halfspace_support_map.rs @@ -29,18 +29,17 @@ where return None; } - let status; let witness2 = support_point; let mut witness1 = ray.point_at(toi); - if support_point.coords.dot(&halfspace.normal) < 0.0 { - status = TOIStatus::Penetrating + let status = if support_point.coords.dot(&halfspace.normal) < 0.0 { + TOIStatus::Penetrating } else { // Project the witness point to the halfspace. // Note that witness2 is already in the halfspace's local-space. witness1 = witness1 - *halfspace.normal * witness1.coords.dot(&halfspace.normal); - status = TOIStatus::Converged - } + TOIStatus::Converged + }; Some(TOI { toi, diff --git a/src/query/time_of_impact/time_of_impact_heightfield_shape.rs b/src/query/time_of_impact/time_of_impact_heightfield_shape.rs index d265bd96..92611b4b 100644 --- a/src/query/time_of_impact/time_of_impact_heightfield_shape.rs +++ b/src/query/time_of_impact/time_of_impact_heightfield_shape.rs @@ -163,20 +163,18 @@ where let mut hit_triangles = |i, j| { if i >= 0 && j >= 0 { let (tri_a, tri_b) = heightfield1.triangles_at(i as usize, j as usize); - for tri in [tri_a, tri_b] { - if let Some(tri) = tri { - // TODO: pre-check using a ray-cast on the Aabbs first? - if let Some(hit) = dispatcher.time_of_impact( - pos12, - vel12, - &tri, - g2, - max_toi, - stop_at_penetration, - )? { - if hit.toi < best_hit.map(|toi| toi.toi).unwrap_or(Real::MAX) { - best_hit = Some(hit); - } + for tri in [tri_a, tri_b].into_iter().flatten() { + // TODO: pre-check using a ray-cast on the Aabbs first? + if let Some(hit) = dispatcher.time_of_impact( + pos12, + vel12, + &tri, + g2, + max_toi, + stop_at_penetration, + )? { + if hit.toi < best_hit.map(|toi| toi.toi).unwrap_or(Real::MAX) { + best_hit = Some(hit); } } } @@ -207,7 +205,7 @@ where let x = heightfield1.signed_x_at(cell.1 + 1); (x - ray.origin.x) / ray.dir.x } else if ray.dir.x < 0.0 { - let x = heightfield1.signed_x_at(cell.1 + 0); + let x = heightfield1.signed_x_at(cell.1); (x - ray.origin.x) / ray.dir.x } else { Real::MAX @@ -217,7 +215,7 @@ where let z = heightfield1.signed_z_at(cell.0 + 1); (z - ray.origin.z) / ray.dir.z } else if ray.dir.z < 0.0 { - let z = heightfield1.signed_z_at(cell.0 + 0); + let z = heightfield1.signed_z_at(cell.0); (z - ray.origin.z) / ray.dir.z } else { Real::MAX diff --git a/src/query/visitors/bounding_volume_intersections_simultaneous_visitor.rs b/src/query/visitors/bounding_volume_intersections_simultaneous_visitor.rs index a1f0958d..0151ec26 100644 --- a/src/query/visitors/bounding_volume_intersections_simultaneous_visitor.rs +++ b/src/query/visitors/bounding_volume_intersections_simultaneous_visitor.rs @@ -61,14 +61,14 @@ where }; if let (Some(data1), Some(data2)) = (left_data, right_data) { - for ii in 0..SIMD_WIDTH { + for (ii, data1) in data1.into_iter().enumerate() { + let Some(data1) = data1 else { continue }; let bitmask = mask[ii].bitmask(); - for jj in 0..SIMD_WIDTH { - if (bitmask & (1 << jj)) != 0 && data1[ii].is_some() && data2[jj].is_some() { - if !(self.callback)(data1[ii].unwrap(), data2[jj].unwrap()) { - return SimdSimultaneousVisitStatus::ExitEarly; - } + for (jj, data2) in data2.into_iter().enumerate() { + let Some(data2) = data2 else { continue }; + if (bitmask & (1 << jj)) != 0 && !(self.callback)(data1, data2) { + return SimdSimultaneousVisitStatus::ExitEarly; } } } @@ -110,12 +110,12 @@ where }; if let (Some(data1), Some(data2)) = (left_data, right_data) { - for ii in 0..SIMD_WIDTH { + for (ii, data1) in data1.into_iter().enumerate() { let bitmask = mask[ii].bitmask(); - for jj in 0..SIMD_WIDTH { - if (bitmask & (1 << jj)) != 0 && data1[ii].is_some() && data2[jj].is_some() { - if !(self.callback)(data1[ii].unwrap(), data2[jj].unwrap()) { + for (jj, data2) in data2.into_iter().enumerate() { + if (bitmask & (1 << jj)) != 0 && data1.is_some() && data2.is_some() { + if !(self.callback)(data1.unwrap(), data2.unwrap()) { return (SimdSimultaneousVisitStatus::ExitEarly, ()); } } diff --git a/src/query/visitors/bounding_volume_intersections_visitor.rs b/src/query/visitors/bounding_volume_intersections_visitor.rs index a9e0d1d5..2f5ababc 100644 --- a/src/query/visitors/bounding_volume_intersections_visitor.rs +++ b/src/query/visitors/bounding_volume_intersections_visitor.rs @@ -37,10 +37,12 @@ where if let Some(data) = b { let bitmask = mask.bitmask(); - for ii in 0..SIMD_WIDTH { - if (bitmask & (1 << ii)) != 0 && data[ii].is_some() { - if !(self.callback)(data[ii].unwrap()) { - return SimdVisitStatus::ExitEarly; + for (ii, data) in data.iter().enumerate() { + if (bitmask & (1 << ii)) != 0 { + if let Some(data) = data { + if !(self.callback)(data) { + return SimdVisitStatus::ExitEarly; + } } } } diff --git a/src/query/visitors/composite_point_containment_test.rs b/src/query/visitors/composite_point_containment_test.rs index 23d135a7..86f428a8 100644 --- a/src/query/visitors/composite_point_containment_test.rs +++ b/src/query/visitors/composite_point_containment_test.rs @@ -43,10 +43,10 @@ impl<'a, S: TypedSimdCompositeShape> SimdVisitor if let Some(data) = b { let bitmask = mask.bitmask(); - for ii in 0..SIMD_WIDTH { - if (bitmask & (1 << ii)) != 0 && data[ii].is_some() { - self.shape - .map_typed_part_at(*data[ii].unwrap(), |part_pos, obj| { + for (ii, data) in data.into_iter().enumerate() { + if (bitmask & (1 << ii)) != 0 { + if let Some(data) = data { + self.shape.map_typed_part_at(*data, |part_pos, obj| { if obj .contains_local_point(&part_pos.inverse_transform_point(self.point)) { @@ -54,8 +54,9 @@ impl<'a, S: TypedSimdCompositeShape> SimdVisitor } }); - if self.found { - return SimdVisitStatus::ExitEarly; + if self.found { + return SimdVisitStatus::ExitEarly; + } } } } diff --git a/src/query/visitors/point_intersections_visitor.rs b/src/query/visitors/point_intersections_visitor.rs index 8f0cba73..483cdc3c 100644 --- a/src/query/visitors/point_intersections_visitor.rs +++ b/src/query/visitors/point_intersections_visitor.rs @@ -39,10 +39,13 @@ where if let Some(data) = b { let bitmask = mask.bitmask(); - for ii in 0..SIMD_WIDTH { - if (bitmask & (1 << ii)) != 0 && data[ii].is_some() { - if !(self.callback)(data[ii].unwrap()) { - return SimdVisitStatus::ExitEarly; + + for (ii, data) in data.iter().enumerate() { + if (bitmask & (1 << ii)) != 0 { + if let Some(data) = data { + if !(self.callback)(data) { + return SimdVisitStatus::ExitEarly; + } } } } diff --git a/src/query/visitors/ray_intersections_visitor.rs b/src/query/visitors/ray_intersections_visitor.rs index 8cd3cde2..642d963d 100644 --- a/src/query/visitors/ray_intersections_visitor.rs +++ b/src/query/visitors/ray_intersections_visitor.rs @@ -40,10 +40,13 @@ where if let Some(data) = b { let bitmask = mask.bitmask(); - for ii in 0..SIMD_WIDTH { - if (bitmask & (1 << ii)) != 0 && data[ii].is_some() { - if !(self.callback)(data[ii].unwrap()) { - return SimdVisitStatus::ExitEarly; + #[allow(clippy::needless_range_loop)] // Easier to read for simd stuffs. + for (ii, data) in data.into_iter().enumerate() { + if (bitmask & (1 << ii)) != 0 { + if let Some(data) = data { + if !(self.callback)(data) { + return SimdVisitStatus::ExitEarly; + } } } } diff --git a/src/shape/compound.rs b/src/shape/compound.rs index 024fded9..3b89d04d 100644 --- a/src/shape/compound.rs +++ b/src/shape/compound.rs @@ -40,11 +40,11 @@ impl Compound { let mut leaves = Vec::new(); let mut aabb = Aabb::new_invalid(); - for (i, &(ref delta, ref shape)) in shapes.iter().enumerate() { + for (i, (delta, shape)) in shapes.iter().enumerate() { let bv = shape.compute_aabb(delta); aabb.merge(&bv); - aabbs.push(bv.clone()); + aabbs.push(bv); leaves.push((i as u32, bv)); if shape.as_composite_shape().is_some() { diff --git a/src/shape/cone.rs b/src/shape/cone.rs index f48dbde7..8cead502 100644 --- a/src/shape/cone.rs +++ b/src/shape/cone.rs @@ -88,7 +88,7 @@ impl SupportMap for Cone { vres = na::zero(); vres[1] = self.half_height.copysign(dir[1]); } else { - vres = vres * self.radius; + vres *= self.radius; vres[1] = -self.half_height; if dir.dot(&vres) < dir[1] * self.half_height { diff --git a/src/shape/convex_polygon.rs b/src/shape/convex_polygon.rs index 7ef31b94..81205823 100644 --- a/src/shape/convex_polygon.rs +++ b/src/shape/convex_polygon.rs @@ -64,7 +64,7 @@ impl ConvexPolygon { points.truncate(new_length); normals.truncate(new_length); - if points.len() != 0 { + if !points.is_empty() { Some(ConvexPolygon { points, normals }) } else { None diff --git a/src/shape/convex_polyhedron.rs b/src/shape/convex_polyhedron.rs index f5e1bd6d..bd30da7f 100644 --- a/src/shape/convex_polyhedron.rs +++ b/src/shape/convex_polyhedron.rs @@ -344,8 +344,7 @@ impl ConvexPolyhedron { v.num_adj_faces_or_edge = 0; } - for face_id in 0..faces.len() { - let face = &faces[face_id]; + for (face_id, face) in faces.iter().enumerate() { let first_vid = face.first_vertex_or_edge; let last_vid = face.first_vertex_or_edge + face.num_vertices_or_edges; diff --git a/src/shape/cuboid.rs b/src/shape/cuboid.rs index 808ada48..835020b6 100644 --- a/src/shape/cuboid.rs +++ b/src/shape/cuboid.rs @@ -49,7 +49,11 @@ impl Cuboid { /// the dot product with `dir`. #[cfg(feature = "dim2")] pub fn vertex_feature_id(vertex: Point) -> u32 { - ((vertex.x.to_bits() >> 31) & 0b001 | (vertex.y.to_bits() >> 30) & 0b010) as u32 + // FIXME: is this still correct with the f64 version? + #[allow(clippy::unnecessary_cast)] // Unnecessary for f32 but necessary for f64. + { + ((vertex.x.to_bits() >> 31) & 0b001 | (vertex.y.to_bits() >> 30) & 0b010) as u32 + } } /// Return the feature of this cuboid with a normal that maximizes @@ -296,18 +300,17 @@ impl Cuboid { let signs = id >> 2; let mut dir: Vector = na::zero(); - let _1: Real = na::one(); if signs & (1 << face1) != 0 { - dir[face1 as usize] = -_1 + dir[face1 as usize] = -1.0 } else { - dir[face1 as usize] = _1 + dir[face1 as usize] = 1.0 } if signs & (1 << face2) != 0 { - dir[face2 as usize] = -_1 + dir[face2 as usize] = -1.0 } else { - dir[face2 as usize] = _1; + dir[face2 as usize] = 1.0; } Some(Unit::new_normalize(dir)) @@ -315,12 +318,10 @@ impl Cuboid { FeatureId::Vertex(id) => { let mut dir: Vector = na::zero(); for i in 0..3 { - let _1: Real = na::one(); - if id & (1 << i) != 0 { - dir[i] = -_1; + dir[i] = -1.0; } else { - dir[i] = _1 + dir[i] = 1.0 } } diff --git a/src/shape/cylinder.rs b/src/shape/cylinder.rs index e4954e41..c9905fd0 100644 --- a/src/shape/cylinder.rs +++ b/src/shape/cylinder.rs @@ -86,7 +86,7 @@ impl SupportMap for Cylinder { if vres.normalize_mut().is_zero() { vres = na::zero() } else { - vres = vres * self.radius; + vres *= self.radius; } vres[1] = self.half_height.copysign(dir[1]); diff --git a/src/shape/feature_id.rs b/src/shape/feature_id.rs index b0e648e2..3269a7dc 100644 --- a/src/shape/feature_id.rs +++ b/src/shape/feature_id.rs @@ -12,7 +12,7 @@ use rkyv::{bytecheck, CheckBytes}; derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize), archive(as = "Self") )] -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Default)] pub enum FeatureId { /// Shape-dependent identifier of a vertex. Vertex(u32), @@ -23,15 +23,10 @@ pub enum FeatureId { Face(u32), // XXX: remove this variant. /// Unknown identifier. + #[default] Unknown, } -impl Default for FeatureId { - fn default() -> Self { - FeatureId::Unknown - } -} - impl FeatureId { /// Revries the value of the identifier if `self` is a vertex. pub fn unwrap_vertex(self) -> u32 { diff --git a/src/shape/heightfield2.rs b/src/shape/heightfield2.rs index 9d998cda..b3943b5e 100644 --- a/src/shape/heightfield2.rs +++ b/src/shape/heightfield2.rs @@ -139,7 +139,7 @@ impl HeightField { } /// Converts this RAM-based heightfield to an heightfield based on CUDA memory. - #[cfg(all(feature = "cuda"))] + #[cfg(feature = "cuda")] pub fn to_cuda(&self) -> CudaResult { Ok(CudaHeightField { heights: CudaArray1::from_vector(&self.heights)?, @@ -264,7 +264,7 @@ impl GenericHeightField { } /// Iterator through all the segments of this heightfield. - pub fn segments<'a>(&'a self) -> impl Iterator + 'a { + pub fn segments(&self) -> impl Iterator + '_ { // FIXME: this is not very efficient since this wil // recompute shared points twice. (0..self.num_cells()).filter_map(move |i| self.segment_at(i)) @@ -281,7 +281,7 @@ impl GenericHeightField { let x0 = -0.5 + seg_length * (i as Real); let x1 = x0 + seg_length; - let y0 = self.heights[i + 0]; + let y0 = self.heights[i]; let y1 = self.heights[i + 1]; let mut p0 = Point2::new(x0, y0); @@ -339,7 +339,7 @@ impl GenericHeightField { let x0 = -0.5 + seg_length * (i as Real); let x1 = x0 + seg_length; - let y0 = self.heights[i + 0]; + let y0 = self.heights[i]; let y1 = self.heights[i + 1]; if (y0 > ref_maxs.y && y1 > ref_maxs.y) || (y0 < ref_mins.y && y1 < ref_mins.y) { diff --git a/src/shape/heightfield3.rs b/src/shape/heightfield3.rs index 591731cc..67064f9a 100644 --- a/src/shape/heightfield3.rs +++ b/src/shape/heightfield3.rs @@ -311,7 +311,7 @@ impl GenericHeightField { } /// An iterator through all the triangles of this heightfield. - pub fn triangles<'a>(&'a self) -> impl Iterator + 'a { + pub fn triangles(&self) -> impl Iterator + '_ { HeightFieldTriangles { heightfield: self, curr: (0, 0), @@ -320,8 +320,8 @@ impl GenericHeightField { } /// An iterator through all the triangles around the given point, after vertical projection on the heightfield. - pub fn triangles_around_point<'a>( - &'a self, + pub fn triangles_around_point( + &self, point: &Point3, ) -> HeightFieldRadialTriangles { let center = self.closest_cell_at_point(point); @@ -369,9 +369,9 @@ impl GenericHeightField { return (None, None); } - let p00 = ((i + 0) + (j + 0) * self.heights.nrows()) as u32; - let p10 = ((i + 1) + (j + 0) * self.heights.nrows()) as u32; - let p01 = ((i + 0) + (j + 1) * self.heights.nrows()) as u32; + let p00 = (i + j * self.heights.nrows()) as u32; + let p10 = ((i + 1) + j * self.heights.nrows()) as u32; + let p01 = (i + (j + 1) * self.heights.nrows()) as u32; let p11 = ((i + 1) + (j + 1) * self.heights.nrows()) as u32; if status.contains(HeightFieldCellStatus::ZIGZAG_SUBDIVISION) { @@ -432,9 +432,9 @@ impl GenericHeightField { let x0 = -0.5 + cell_width * (j as Real); let x1 = -0.5 + cell_width * ((j + 1) as Real); - let y00 = self.heights.get(i + 0, j + 0); - let y10 = self.heights.get(i + 1, j + 0); - let y01 = self.heights.get(i + 0, j + 1); + let y00 = self.heights.get(i, j); + let y10 = self.heights.get(i + 1, j); + let y01 = self.heights.get(i, j + 1); let y11 = self.heights.get(i + 1, j + 1); let mut p00 = Point3::new(x0, y00, z0); @@ -577,14 +577,10 @@ impl GenericHeightField { } else { FeatureId::Vertex([ij, ij + 1 + nrows, ij + nrows][ivertex as usize] as u32) } + } else if left { + FeatureId::Vertex([ij, ij + 1, ij + nrows][ivertex as usize] as u32) } else { - if left { - FeatureId::Vertex([ij, ij + 1, ij + nrows][ivertex as usize] as u32) - } else { - FeatureId::Vertex( - [ij + 1, ij + 1 + nrows, ij + nrows][ivertex as usize] as u32, - ) - } + FeatureId::Vertex([ij + 1, ij + 1 + nrows, ij + nrows][ivertex as usize] as u32) } } FeatureId::Edge(iedge) => { @@ -618,22 +614,20 @@ impl GenericHeightField { // FeatureId::Edge([idiag, iright, itop][iedge as usize] as u32) } + } else if left { + // Triangle: + // ___ + // | / + // |/ + // + FeatureId::Edge([ileft, idiag, itop][iedge as usize] as u32) } else { - if left { - // Triangle: - // ___ - // | / - // |/ - // - FeatureId::Edge([ileft, idiag, itop][iedge as usize] as u32) - } else { - // Triangle: - // - // /| - // /_| - // - FeatureId::Edge([ibottom, iright, idiag][iedge as usize] as u32) - } + // Triangle: + // + // /| + // /_| + // + FeatureId::Edge([ibottom, iright, idiag][iedge as usize] as u32) } } FeatureId::Face(iface) => { @@ -702,9 +696,9 @@ impl GenericHeightField { let x0 = -0.5 + cell_width * (j as Real); let x1 = x0 + cell_width; - let y00 = self.heights.get(i + 0, j + 0); - let y10 = self.heights.get(i + 1, j + 0); - let y01 = self.heights.get(i + 0, j + 1); + let y00 = self.heights.get(i, j); + let y10 = self.heights.get(i + 1, j); + let y01 = self.heights.get(i, j + 1); let y11 = self.heights.get(i + 1, j + 1); if (y00 > ref_maxs.y && y10 > ref_maxs.y && y01 > ref_maxs.y && y11 > ref_maxs.y) @@ -736,7 +730,7 @@ impl GenericHeightField { }; let tid = self.triangle_id(i, j, true); - f(tid as u32, &tri1); + f(tid, &tri1); } if !status.contains(HeightFieldCellStatus::RIGHT_TRIANGLE_REMOVED) { @@ -746,7 +740,7 @@ impl GenericHeightField { Triangle::new(p10, p11, p01) }; let tid = self.triangle_id(i, j, false); - f(tid as u32, &tri2); + f(tid, &tri2); } } } diff --git a/src/shape/polygonal_feature3d.rs b/src/shape/polygonal_feature3d.rs index c61e826b..108c91df 100644 --- a/src/shape/polygonal_feature3d.rs +++ b/src/shape/polygonal_feature3d.rs @@ -276,8 +276,10 @@ impl PolygonalFeature { let denom = normal2_1.dot(sep_axis1); if !relative_eq!(denom, 0.0) { - let last_index2 = face2.num_vertices as usize - 1; - 'point_loop1: for i in 0..face1.num_vertices as usize { + let last_index2 = face2.num_vertices - 1; + + #[allow(clippy::needless_range_loop)] // Would make it much more verbose. + 'point_loop1: for i in 0..face1.num_vertices { let p1 = projected_face1[i]; let mut sign = (projected_face2[0] - projected_face2[last_index2]) @@ -320,8 +322,8 @@ impl PolygonalFeature { let denom = -normal1.dot(sep_axis1); if !relative_eq!(denom, 0.0) { - let last_index1 = face1.num_vertices as usize - 1; - 'point_loop2: for i in 0..face2.num_vertices as usize { + let last_index1 = face1.num_vertices - 1; + 'point_loop2: for i in 0..face2.num_vertices { let p2 = projected_face2[i]; let mut sign = (projected_face1[0] - projected_face1[last_index1]) diff --git a/src/shape/polygonal_feature_map.rs b/src/shape/polygonal_feature_map.rs index b2c6f608..d5c331e7 100644 --- a/src/shape/polygonal_feature_map.rs +++ b/src/shape/polygonal_feature_map.rs @@ -41,7 +41,7 @@ impl PolygonalFeatureMap for Triangle { impl PolygonalFeatureMap for Cuboid { fn local_support_feature(&self, dir: &Unit>, out_feature: &mut PolygonalFeature) { - *out_feature = self.support_face(**dir).into(); + *out_feature = self.support_face(**dir); } } diff --git a/src/shape/polyline.rs b/src/shape/polyline.rs index 64be51a7..ab07f5d5 100644 --- a/src/shape/polyline.rs +++ b/src/shape/polyline.rs @@ -169,7 +169,7 @@ impl Polyline { let vertices = self.vertices(); let indices = self.indices(); - if indices.len() == 0 { + if indices.is_empty() { // Polyline is empty, return empty Vec Vec::new() } else { @@ -182,7 +182,7 @@ impl Polyline { let mut component_indices: Vec<[u32; 2]> = Vec::new(); // Iterate over indices, building polylines as we go - for (i, idx) in indices.into_iter().enumerate() { + for (i, idx) in indices.iter().enumerate() { component_vertices.push(vertices[idx[0] as usize]); if idx[1] != start_node { @@ -192,8 +192,8 @@ impl Polyline { // Start node reached: build polyline and start next component component_indices.push([(i - start_i) as u32, 0]); components.push(Polyline::new( - component_vertices.drain(..).collect(), - Some(component_indices.drain(..).collect()), + std::mem::take(&mut component_vertices), + Some(std::mem::take(&mut component_indices)), )); if i + 1 < indices.len() { diff --git a/src/shape/shape.rs b/src/shape/shape.rs index 1b482d14..e77b6b93 100644 --- a/src/shape/shape.rs +++ b/src/shape/shape.rs @@ -581,7 +581,7 @@ impl dyn Shape { impl Shape for Ball { #[cfg(feature = "std")] fn clone_box(&self) -> Box { - Box::new(self.clone()) + Box::new(*self) } fn compute_local_aabb(&self) -> Aabb { @@ -638,7 +638,7 @@ impl Shape for Ball { impl Shape for Cuboid { #[cfg(feature = "std")] fn clone_box(&self) -> Box { - Box::new(self.clone()) + Box::new(*self) } fn compute_local_aabb(&self) -> Aabb { @@ -697,7 +697,7 @@ impl Shape for Cuboid { impl Shape for Capsule { #[cfg(feature = "std")] fn clone_box(&self) -> Box { - Box::new(self.clone()) + Box::new(*self) } fn compute_local_aabb(&self) -> Aabb { @@ -748,7 +748,7 @@ impl Shape for Capsule { impl Shape for Triangle { #[cfg(feature = "std")] fn clone_box(&self) -> Box { - Box::new(self.clone()) + Box::new(*self) } fn compute_local_aabb(&self) -> Aabb { @@ -811,7 +811,7 @@ impl Shape for Triangle { impl Shape for Segment { #[cfg(feature = "std")] fn clone_box(&self) -> Box { - Box::new(self.clone()) + Box::new(*self) } fn compute_local_aabb(&self) -> Aabb { @@ -1180,7 +1180,7 @@ impl Shape for ConvexPolyhedron { impl Shape for Cylinder { #[cfg(feature = "std")] fn clone_box(&self) -> Box { - Box::new(self.clone()) + Box::new(*self) } fn compute_local_aabb(&self) -> Aabb { @@ -1232,7 +1232,7 @@ impl Shape for Cylinder { impl Shape for Cone { #[cfg(feature = "std")] fn clone_box(&self) -> Box { - Box::new(self.clone()) + Box::new(*self) } fn compute_local_aabb(&self) -> Aabb { @@ -1286,7 +1286,7 @@ impl Shape for Cone { impl Shape for HalfSpace { #[cfg(feature = "std")] fn clone_box(&self) -> Box { - Box::new(self.clone()) + Box::new(*self) } fn compute_local_aabb(&self) -> Aabb { diff --git a/src/shape/triangle.rs b/src/shape/triangle.rs index 79492ce4..d3931460 100644 --- a/src/shape/triangle.rs +++ b/src/shape/triangle.rs @@ -95,11 +95,7 @@ impl TrianglePointLocation { /// Returns `true` if the point is located on the relative interior of the triangle. pub fn is_on_face(&self) -> bool { - if let TrianglePointLocation::OnFace(..) = *self { - true - } else { - false - } + matches!(*self, TrianglePointLocation::OnFace(..)) } } @@ -330,11 +326,11 @@ impl Triangle { #[inline] pub fn area(&self) -> Real { // Kahan's formula. - let mut a = na::distance(&self.a, &self.b); - let mut b = na::distance(&self.b, &self.c); - let mut c = na::distance(&self.c, &self.a); + let a = na::distance(&self.a, &self.b); + let b = na::distance(&self.b, &self.c); + let c = na::distance(&self.c, &self.a); - let (c, b, a) = utils::sort3(&mut a, &mut b, &mut c); + let (c, b, a) = utils::sort3(&a, &b, &c); let a = *a; let b = *b; let c = *c; @@ -384,8 +380,7 @@ impl Triangle { let dab = a.dot(&b); - let _2: Real = na::convert::(2.0); - let denom = _2 * (na * nb - dab * dab); + let denom = 2.0 * (na * nb - dab * dab); if denom.is_zero() { // The triangle is degenerate (the three points are colinear). @@ -576,12 +571,10 @@ impl SupportMap for Triangle { } else { self.c } + } else if d2 > d3 { + self.b } else { - if d2 > d3 { - self.b - } else { - self.c - } + self.c } } } diff --git a/src/shape/trimesh.rs b/src/shape/trimesh.rs index c282fbfb..44b79f6c 100644 --- a/src/shape/trimesh.rs +++ b/src/shape/trimesh.rs @@ -428,7 +428,7 @@ impl TriMesh { flags: TriMeshFlags, ) -> Self { assert!( - indices.len() > 0, + !indices.is_empty(), "A triangle mesh must contain at least one triangle." ); @@ -663,14 +663,14 @@ impl TriMesh { vtx_to_id: &mut HashMap>, u32>, new_vertices: &mut Vec>, ) -> u32 { - let key = HashablePartialEq::new(coord.clone()); + let key = HashablePartialEq::new(*coord); let id = match vtx_to_id.entry(key) { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => entry.insert(new_vertices.len() as u32), }; if *id == new_vertices.len() as u32 { - new_vertices.push(coord.clone()); + new_vertices.push(*coord); } *id @@ -1319,7 +1319,7 @@ where pseudo_normals: self.pseudo_normals.clone(), topology: self.topology.clone(), connected_components: self.connected_components.clone(), - flags: self.flags.clone(), + flags: self.flags, } } } diff --git a/src/transformation/convex_hull2.rs b/src/transformation/convex_hull2.rs index 41832da7..38b618ed 100644 --- a/src/transformation/convex_hull2.rs +++ b/src/transformation/convex_hull2.rs @@ -27,7 +27,7 @@ pub fn convex_hull2_idx(points: &[Point2]) -> Vec { let mut i = 0; while i != segments.len() { if !segments[i].valid { - i = i + 1; + i += 1; continue; } @@ -44,21 +44,21 @@ pub fn convex_hull2_idx(points: &[Point2]) -> Vec { segments[i].prev, segments[i].next, point, - &points[..], + points, &mut segments, i, &mut undecidable_points, ); } - i = i + 1; + i += 1; } let mut idx = Vec::new(); let mut curr_facet = 0; while !segments[curr_facet].valid { - curr_facet = curr_facet + 1 + curr_facet += 1 } let first_facet = curr_facet; @@ -178,7 +178,7 @@ fn attach_and_push_facets2( new_facet2.visible_points.push(undecidable[i]); let _ = undecidable.swap_remove(i); } else { - i = i + 1; + i += 1; } } diff --git a/src/transformation/convex_hull3/convex_hull.rs b/src/transformation/convex_hull3/convex_hull.rs index cd59bdfa..f7207a90 100644 --- a/src/transformation/convex_hull3/convex_hull.rs +++ b/src/transformation/convex_hull3/convex_hull.rs @@ -45,7 +45,7 @@ pub fn try_convex_hull( silhouette_loop_facets_and_idx.clear(); if !triangles[i].valid || triangles[i].affinely_dependent { - i = i + 1; + i += 1; continue; } @@ -98,8 +98,8 @@ pub fn try_convex_hull( // Due to inaccuracies, the silhouette could not be computed // (the point seems to be visible from… every triangle). let mut any_valid = false; - for j in i + 1..triangles.len() { - if triangles[j].valid && !triangles[j].affinely_dependent { + for triangle in &triangles[i + 1..triangles.len()] { + if triangle.valid && !triangle.affinely_dependent { any_valid = true; } } @@ -132,7 +132,7 @@ pub fn try_convex_hull( // } } - i = i + 1; + i += 1; } let mut idx = Vec::new(); @@ -292,7 +292,7 @@ fn fix_silhouette_topology( // } } - // println!(""); + // println!(); } Ok(()) @@ -313,9 +313,9 @@ fn attach_and_push_facets( let mut adj_facet: usize; let mut indirect_id: usize; - for i in 0..silhouette_loop_facets_and_idx.len() { - adj_facet = silhouette_loop_facets_and_idx[i].0; - indirect_id = silhouette_loop_facets_and_idx[i].1; + for silhouette_loop_facets_and_id in silhouette_loop_facets_and_idx { + adj_facet = silhouette_loop_facets_and_id.0; + indirect_id = silhouette_loop_facets_and_id.1; // print!( // "[{}, {}] ", @@ -331,17 +331,15 @@ fn attach_and_push_facets( ); new_facets.push(facet); } - // println!(""); + // println!(); // Link the facets together. for i in 0..silhouette_loop_facets_and_idx.len() { - let prev_facet; - - if i == 0 { - prev_facet = triangles.len() + silhouette_loop_facets_and_idx.len() - 1; + let prev_facet = if i == 0 { + triangles.len() + silhouette_loop_facets_and_idx.len() - 1 } else { - prev_facet = triangles.len() + i - 1; - } + triangles.len() + i - 1 + }; let (middle_facet, middle_id) = silhouette_loop_facets_and_idx[i]; let next_facet = triangles.len() + (i + 1) % silhouette_loop_facets_and_idx.len(); @@ -374,10 +372,10 @@ fn attach_and_push_facets( } } - if furthest != usize::max_value() { - if new_facets[furthest].can_see_point(*visible_point, points) { - new_facets[furthest].add_visible_point(*visible_point, points); - } + if furthest != usize::max_value() + && new_facets[furthest].can_see_point(*visible_point, points) + { + new_facets[furthest].add_visible_point(*visible_point, points); } // If none of the facet can be seen from the point, it is implicitly @@ -408,7 +406,7 @@ fn attach_and_push_facets( new_facets[furthest].add_visible_point(undecidable_point, points); let _ = undecidable.swap_remove(i); } else { - i = i + 1; + i += 1; } } diff --git a/src/transformation/convex_hull3/initial_mesh.rs b/src/transformation/convex_hull3/initial_mesh.rs index 573687e5..30ba8b47 100644 --- a/src/transformation/convex_hull3/initial_mesh.rs +++ b/src/transformation/convex_hull3/initial_mesh.rs @@ -86,13 +86,13 @@ pub fn try_get_initial_mesh( break; } - dimension = dimension + 1; + dimension += 1; } match dimension { 0 => { // The hull is a point. - let (vtx, idx) = build_degenerate_mesh_point(original_points[0].clone()); + let (vtx, idx) = build_degenerate_mesh_point(original_points[0]); Ok(InitialMesh::ResultMesh(vtx, idx)) } 1 => { @@ -120,10 +120,7 @@ pub fn try_get_initial_mesh( // Finalize the result, triangulating the polyline. let npoints = idx.len(); - let coords = idx - .into_iter() - .map(|i| original_points[i].clone()) - .collect(); + let coords = idx.into_iter().map(|i| original_points[i]).collect(); let mut triangles = Vec::with_capacity(npoints + npoints - 4); for id in 1u32..npoints as u32 - 1 { @@ -182,7 +179,6 @@ pub fn try_get_initial_mesh( // … and attribute visible points to each one of them. // FIXME: refactor this with the two others. - let mut ignored = 0usize; for point in 0..normalized_points.len() { if normalized_points[point] == normalized_points[p1] || normalized_points[point] == normalized_points[p2] @@ -209,7 +205,6 @@ pub fn try_get_initial_mesh( facets[furthest].add_visible_point(point, normalized_points); } else { undecidable.push(point); - ignored = ignored + 1; } // If none of the facet can be seen from the point, it is naturally deleted. diff --git a/src/transformation/convex_hull3/mod.rs b/src/transformation/convex_hull3/mod.rs index 64bdefcf..3f710074 100644 --- a/src/transformation/convex_hull3/mod.rs +++ b/src/transformation/convex_hull3/mod.rs @@ -1,7 +1,7 @@ pub use self::error::ConvexHullError; -pub(self) use self::initial_mesh::{try_get_initial_mesh, InitialMesh}; -pub(self) use self::triangle_facet::TriangleFacet; -pub(self) use self::validation::check_facet_links; +use self::initial_mesh::{try_get_initial_mesh, InitialMesh}; +use self::triangle_facet::TriangleFacet; +use self::validation::check_facet_links; pub use convex_hull::{convex_hull, try_convex_hull}; pub use validation::check_convex_hull; diff --git a/src/transformation/convex_hull_utils.rs b/src/transformation/convex_hull_utils.rs index b72cd461..20fcf370 100644 --- a/src/transformation/convex_hull_utils.rs +++ b/src/transformation/convex_hull_utils.rs @@ -77,7 +77,7 @@ where /// Scale and center the given set of point depending on their Aabb. #[cfg(feature = "dim3")] pub fn normalize(coords: &mut [Point]) -> (Point, Real) { - let aabb = bounding_volume::details::local_point_cloud_aabb(&coords[..]); + let aabb = bounding_volume::details::local_point_cloud_aabb(&*coords); let diag = na::distance(&aabb.mins, &aabb.maxs); let center = aabb.center(); diff --git a/src/transformation/mesh_intersection/mesh_intersection.rs b/src/transformation/mesh_intersection/mesh_intersection.rs index a473c459..e81d15df 100644 --- a/src/transformation/mesh_intersection/mesh_intersection.rs +++ b/src/transformation/mesh_intersection/mesh_intersection.rs @@ -129,13 +129,13 @@ pub fn intersect_meshes( // Grab all the trinangles from the intersections. for idx12 in &mut new_indices12 { - for k in 0..3 { - let new_id = *index_map.entry(idx12[k]).or_insert_with(|| { - let vtx = unified_vertex(mesh1, mesh2, &new_vertices12, &pos12, idx12[k]); + for id12 in idx12 { + let new_id = *index_map.entry(*id12).or_insert_with(|| { + let vtx = unified_vertex(mesh1, mesh2, &new_vertices12, &pos12, *id12); new_vertices.push(vtx); new_vertices.len() - 1 }); - idx12[k] = new_id as u32; + *id12 = new_id as u32; } } @@ -188,7 +188,7 @@ fn extract_connected_components( for edge in edges { if let Some(twin) = topo1.half_edges.get(edge.twin as usize) { if !deleted_faces1.contains(&twin.face) { - let tri1 = mesh1.triangle(twin.face as u32); + let tri1 = mesh1.triangle(twin.face); if flip2 ^ mesh2.contains_local_point(&pos12.inverse_transform_point(&tri1.center())) @@ -291,8 +291,8 @@ impl Triangulation { .try_inverse() .unwrap_or(na::Matrix2::identity()); - for k in 0..3 { - ref_proj[k] = normalization * ref_proj[k]; + for ref_proj in &mut ref_proj { + *ref_proj = normalization * *ref_proj; } let vtx_handles = [ @@ -322,26 +322,23 @@ impl Triangulation { let mut proj = self.normalization * Point2::new(dpt.dot(&self.basis[0]), dpt.dot(&self.basis[1])); - match orig_fid { - FeatureId::Edge(i) => { - let a = self.ref_proj[i as usize]; - let b = self.ref_proj[(i as usize + 1) % 3]; - let ab = b - a; - let ap = proj - a; - let param = ab.dot(&ap) / ab.norm_squared(); - let shift = Vector2::new(ab.y, -ab.x); - - // NOTE: if we have intersections exactly on the edge, we nudge - // their projection slightly outside of the triangle. That - // way, the triangle’s edge gets split automatically by - // the triangulation (or, rather, it will be split when we - // add the contsraint involving that point). - // NOTE: this is not ideal though, so we should find a way to simply - // delete spurious triangles that are outside of the intersection - // curve. - proj = a + ab * param + shift * EPS * 10.0; - } - _ => {} + if let FeatureId::Edge(i) = orig_fid { + let a = self.ref_proj[i as usize]; + let b = self.ref_proj[(i as usize + 1) % 3]; + let ab = b - a; + let ap = proj - a; + let param = ab.dot(&ap) / ab.norm_squared(); + let shift = Vector2::new(ab.y, -ab.x); + + // NOTE: if we have intersections exactly on the edge, we nudge + // their projection slightly outside of the triangle. That + // way, the triangle’s edge gets split automatically by + // the triangulation (or, rather, it will be split when we + // add the contsraint involving that point). + // NOTE: this is not ideal though, so we should find a way to simply + // delete spurious triangles that are outside of the intersection + // curve. + proj = a + ab * param + shift * EPS * 10.0; } spade::Point2::new(proj.x, proj.y) @@ -581,7 +578,7 @@ fn extract_result( let vid = fids_to_unified_index(fids); let vertex = unified_vertex(mesh1, mesh2, new_vertices12, pos12, vid); - idx[k] = vid as u32; + idx[k] = vid; tri[k] = vertex; } @@ -611,7 +608,7 @@ fn extract_result( let vid = fids_to_unified_index(fids); let vertex = unified_vertex(mesh1, mesh2, new_vertices12, pos12, vid); - idx[k] = vid as u32; + idx[k] = vid; tri[k] = vertex; } diff --git a/src/transformation/mesh_intersection/mod.rs b/src/transformation/mesh_intersection/mod.rs index e9b0d6b9..1a99d68a 100644 --- a/src/transformation/mesh_intersection/mod.rs +++ b/src/transformation/mesh_intersection/mod.rs @@ -1,6 +1,6 @@ pub use self::mesh_intersection::intersect_meshes; pub use self::mesh_intersection_error::MeshIntersectionError; -pub(self) use triangle_triangle_intersection::*; +use triangle_triangle_intersection::*; use crate::math::Real; @@ -8,4 +8,4 @@ mod mesh_intersection; mod mesh_intersection_error; mod triangle_triangle_intersection; -pub(self) const EPS: Real = 1.0e-6; +const EPS: Real = 1.0e-6; diff --git a/src/transformation/mesh_intersection/triangle_triangle_intersection.rs b/src/transformation/mesh_intersection/triangle_triangle_intersection.rs index 038b6664..db309856 100644 --- a/src/transformation/mesh_intersection/triangle_triangle_intersection.rs +++ b/src/transformation/mesh_intersection/triangle_triangle_intersection.rs @@ -57,14 +57,12 @@ pub fn triangle_triangle_intersection( .map(|(p, feat)| (intersection_dir.dot(&p.coords), p, feat)), ]; - for k in 0..3 { - if let Some(hit1) = &hits1[k] { - if hit1.0 < range1[0].0 { - range1[0] = *hit1; - } - if hit1.0 > range1[1].0 { - range1[1] = *hit1; - } + for hit1 in hits1.into_iter().flatten() { + if hit1.0 < range1[0].0 { + range1[0] = hit1; + } + if hit1.0 > range1[1].0 { + range1[1] = hit1; } } @@ -82,14 +80,12 @@ pub fn triangle_triangle_intersection( .map(|(p, feat)| (intersection_dir.dot(&p.coords), p, feat)), ]; - for k in 0..3 { - if let Some(hit2) = &hits2[k] { - if hit2.0 < range2[0].0 { - range2[0] = *hit2; - } - if hit2.0 > range2[1].0 { - range2[1] = *hit2; - } + for hit2 in hits2.into_iter().flatten() { + if hit2.0 < range2[0].0 { + range2[0] = hit2; + } + if hit2.0 > range2[1].0 { + range2[1] = hit2; } } @@ -199,15 +195,13 @@ pub fn triangle_triangle_intersection( proj(tri1.c - tri2.a), ]; let poly2 = [ - proj(tri2.a - tri2.a), + proj(Vector::zeros()), // = proj(tri2.a - tri2.a) proj(tri2.b - tri2.a), proj(tri2.c - tri2.a), ]; let convert_loc = |loc, pts: &[Point; 3]| match loc { - PolylinePointLocation::OnVertex(vid) => { - (FeatureId::Vertex(vid as u32), pts[vid as usize]) - } + PolylinePointLocation::OnVertex(vid) => (FeatureId::Vertex(vid as u32), pts[vid]), PolylinePointLocation::OnEdge(vid1, vid2, bcoords) => ( match (vid1, vid2) { (0, 1) | (1, 0) => FeatureId::Edge(0), @@ -272,13 +266,11 @@ fn segment_plane_intersection( if scaled_toi < -EPS || scaled_toi > dir_norm + EPS { None + } else if scaled_toi <= EPS { + Some((segment.a, FeatureId::Vertex(vids.0))) + } else if scaled_toi >= dir_norm - EPS { + Some((segment.b, FeatureId::Vertex(vids.1))) } else { - if scaled_toi <= EPS { - Some((segment.a, FeatureId::Vertex(vids.0))) - } else if scaled_toi >= dir_norm - EPS { - Some((segment.b, FeatureId::Vertex(vids.1))) - } else { - Some((segment.a + dir * toi, FeatureId::Edge(eid))) - } + Some((segment.a + dir * toi, FeatureId::Edge(eid))) } } diff --git a/src/transformation/to_outline/cone_to_outline.rs b/src/transformation/to_outline/cone_to_outline.rs index 1934b459..99e65e33 100644 --- a/src/transformation/to_outline/cone_to_outline.rs +++ b/src/transformation/to_outline/cone_to_outline.rs @@ -18,6 +18,7 @@ impl Cone { fn unit_cone_outline(nsubdiv: u32) -> (Vec>, Vec<[u32; 2]>) { let mut out_vtx = vec![Point3::new(-0.5, -0.5, 0.0), Point3::new(0.0, 0.5, 0.0)]; let mut out_ptx = vec![]; + #[allow(clippy::single_range_in_vec_init)] // The single range is on purpose. utils::apply_revolution(false, true, &[0..1], nsubdiv, &mut out_vtx, &mut out_ptx); (out_vtx, out_ptx) } diff --git a/src/transformation/to_outline/cylinder_to_outline.rs b/src/transformation/to_outline/cylinder_to_outline.rs index 64e5ca0b..e893ba19 100644 --- a/src/transformation/to_outline/cylinder_to_outline.rs +++ b/src/transformation/to_outline/cylinder_to_outline.rs @@ -18,6 +18,7 @@ impl Cylinder { fn unit_cylinder_outline(nsubdiv: u32) -> (Vec>, Vec<[u32; 2]>) { let mut out_vtx = vec![Point3::new(-0.5, -0.5, 0.0), Point3::new(-0.5, 0.5, 0.0)]; let mut out_idx = vec![]; + #[allow(clippy::single_range_in_vec_init)] // The single range is on purpose. utils::apply_revolution(false, false, &[0..2], nsubdiv, &mut out_vtx, &mut out_idx); (out_vtx, out_idx) } diff --git a/src/transformation/to_outline/round_cuboid_to_outline.rs b/src/transformation/to_outline/round_cuboid_to_outline.rs index a8366ad3..13165c1b 100644 --- a/src/transformation/to_outline/round_cuboid_to_outline.rs +++ b/src/transformation/to_outline/round_cuboid_to_outline.rs @@ -25,10 +25,10 @@ impl RoundCuboid { let mut idx = vec![]; for i in 0..6 { - idx.push([i * 4 + 0, i * 4 + 1]); + idx.push([i * 4, i * 4 + 1]); idx.push([i * 4 + 1, i * 4 + 2]); idx.push([i * 4 + 2, i * 4 + 3]); - idx.push([i * 4 + 3, i * 4 + 0]); + idx.push([i * 4 + 3, i * 4]); } let arcs = [ diff --git a/src/transformation/to_trimesh/ball_to_trimesh.rs b/src/transformation/to_trimesh/ball_to_trimesh.rs index cfe41ba4..58f94e69 100644 --- a/src/transformation/to_trimesh/ball_to_trimesh.rs +++ b/src/transformation/to_trimesh/ball_to_trimesh.rs @@ -33,7 +33,7 @@ fn unit_sphere(ntheta_subdiv: u32, nphi_subdiv: u32) -> (Vec>, Vec< ComplexField::sin(curr_phi), &mut coords, ); - curr_phi = curr_phi + dphi; + curr_phi += dphi; } coords.push(Point::new(0.0, 1.0, 0.0)); @@ -83,7 +83,7 @@ pub(crate) fn unit_hemisphere( ComplexField::sin(curr_phi), &mut coords, ); - curr_phi = curr_phi + dphi; + curr_phi += dphi; } coords.push(Point::new(0.0, 1.0, 0.0)); diff --git a/src/transformation/to_trimesh/capsule_to_trimesh.rs b/src/transformation/to_trimesh/capsule_to_trimesh.rs index 9fd12880..eb30af5f 100644 --- a/src/transformation/to_trimesh/capsule_to_trimesh.rs +++ b/src/transformation/to_trimesh/capsule_to_trimesh.rs @@ -36,30 +36,30 @@ pub(crate) fn canonical_capsule( // shift the top for coord in top_coords.iter_mut() { - coord.x = coord.x * caps_diameter; + coord.x *= caps_diameter; coord.y = coord.y * caps_diameter + half_height; - coord.z = coord.z * caps_diameter; + coord.z *= caps_diameter; } // flip + shift the bottom for coord in bottom_coords.iter_mut() { - coord.x = coord.x * caps_diameter; + coord.x *= caps_diameter; coord.y = -(coord.y * caps_diameter) - half_height; - coord.z = coord.z * caps_diameter; + coord.z *= caps_diameter; } // shift the top index buffer let base_top_coords = bottom_coords.len() as u32; for idx in top_indices.iter_mut() { - idx[0] = idx[0] + base_top_coords; - idx[1] = idx[1] + base_top_coords; - idx[2] = idx[2] + base_top_coords; + idx[0] += base_top_coords; + idx[1] += base_top_coords; + idx[2] += base_top_coords; } // merge all buffers - bottom_coords.extend(top_coords.into_iter()); - bottom_indices.extend(top_indices.into_iter()); + bottom_coords.extend(top_coords); + bottom_indices.extend(top_indices); // attach the two caps utils::push_ring_indices(0, base_top_coords, ntheta_subdiv, &mut bottom_indices); diff --git a/src/transformation/to_trimesh/convex_polyhedron_to_trimesh.rs b/src/transformation/to_trimesh/convex_polyhedron_to_trimesh.rs index c86c2b18..d91468b1 100644 --- a/src/transformation/to_trimesh/convex_polyhedron_to_trimesh.rs +++ b/src/transformation/to_trimesh/convex_polyhedron_to_trimesh.rs @@ -10,10 +10,10 @@ impl ConvexPolyhedron { for face in self.faces() { let i1 = face.first_vertex_or_edge; let i2 = i1 + face.num_vertices_or_edges; - let first_id = self.vertices_adj_to_face()[i1 as usize] as u32; + let first_id = self.vertices_adj_to_face()[i1 as usize]; for idx in self.vertices_adj_to_face()[i1 as usize + 1..i2 as usize].windows(2) { - indices.push([first_id, idx[0] as u32, idx[1] as u32]); + indices.push([first_id, idx[0], idx[1]]); } } diff --git a/src/transformation/utils.rs b/src/transformation/utils.rs index 978541d2..403f2701 100644 --- a/src/transformation/utils.rs +++ b/src/transformation/utils.rs @@ -34,10 +34,10 @@ pub fn push_circle(radius: Real, nsubdiv: u32, dtheta: Real, y: Real, out: &mut for _ in 0..nsubdiv { out.push(Point::new( ComplexField::cos(curr_theta) * radius, - y.clone(), + y, ComplexField::sin(curr_theta) * radius, )); - curr_theta = curr_theta + dtheta; + curr_theta += dtheta; } } @@ -55,7 +55,7 @@ pub fn push_xy_arc(radius: Real, nsubdiv: u32, dtheta: Real, out: &mut Vec) { - out.push([ul.clone(), dl, dr.clone()]); + out.push([ul, dl, dr]); out.push([dr, ur, ul]); } @@ -273,7 +273,7 @@ pub fn apply_revolution( ) { use na::RealField; let ang_increment = Real::two_pi() / (nsubdivs as Real); - let angs = [ + let angles = [ ang_increment * (nsubdivs / 4) as Real, ang_increment * (nsubdivs / 2) as Real, ang_increment * ((3 * nsubdivs) / 4) as Real, @@ -295,9 +295,9 @@ pub fn apply_revolution( } // Push rotated profiles. - for i in 0..3 { + for angle in angles { let base = out_vtx.len() as u32; - let rot = na::UnitQuaternion::new(Vector::y() * angs[i]); + let rot = na::UnitQuaternion::new(Vector::y() * angle); if collapse_bottom { out_idx.push([0, base]); diff --git a/src/transformation/voxelization/voxel_set.rs b/src/transformation/voxelization/voxel_set.rs index 2f9a3f37..c1619beb 100644 --- a/src/transformation/voxelization/voxel_set.rs +++ b/src/transformation/voxelization/voxel_set.rs @@ -65,6 +65,12 @@ pub struct VoxelSet { pub(crate) primitive_classes: Arc>, } +impl Default for VoxelSet { + fn default() -> Self { + Self::new() + } +} + impl VoxelSet { /// Creates a new empty set of voxels. pub fn new() -> Self { @@ -144,6 +150,11 @@ impl VoxelSet { self.origin + voxel.coords * self.scale } + /// Does this voxel not contain any element? + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + /// The number of voxels in this set. pub fn len(&self) -> usize { self.voxels.len() @@ -234,7 +245,7 @@ impl VoxelSet { // included in only one convex part. So instead of cutting it, just push the whole // triangle once. let prim_class = self.primitive_classes.get(*prim_id as usize).copied(); - if prim_class == Some(u32::MAX) || prim_class == None { + if prim_class == Some(u32::MAX) || prim_class.is_none() { let aabb_center = self.origin + voxel.coords.coords.map(|k| k as Real) * self.scale; let aabb = @@ -456,15 +467,13 @@ impl VoxelSet { sp = 0; } } + } else if -d <= d0 { + self.map_voxel_points(&voxel, |p| negative_pts.push(p)); } else { - if -d <= d0 { + sn += 1; + if sn == sampling { self.map_voxel_points(&voxel, |p| negative_pts.push(p)); - } else { - sn += 1; - if sn == sampling { - self.map_voxel_points(&voxel, |p| negative_pts.push(p)); - sn = 0; - } + sn = 0; } } } @@ -541,13 +550,11 @@ impl VoxelSet { } else { positive_part.voxels.push(voxel); } + } else if voxel.is_on_surface || -d <= d0 { + voxel.is_on_surface = true; + negative_part.voxels.push(voxel); } else { - if voxel.is_on_surface || -d <= d0 { - voxel.is_on_surface = true; - negative_part.voxels.push(voxel); - } else { - negative_part.voxels.push(voxel); - } + negative_part.voxels.push(voxel); } } } @@ -567,18 +574,18 @@ impl VoxelSet { if voxel.is_on_surface == is_on_surface { self.map_voxel_points(voxel, |p| vertices.push(p)); - indices.push([base_index + 0, base_index + 2, base_index + 1]); - indices.push([base_index + 0, base_index + 3, base_index + 2]); + indices.push([base_index, base_index + 2, base_index + 1]); + indices.push([base_index, base_index + 3, base_index + 2]); indices.push([base_index + 4, base_index + 5, base_index + 6]); indices.push([base_index + 4, base_index + 6, base_index + 7]); indices.push([base_index + 7, base_index + 6, base_index + 2]); indices.push([base_index + 7, base_index + 2, base_index + 3]); indices.push([base_index + 4, base_index + 1, base_index + 5]); - indices.push([base_index + 4, base_index + 0, base_index + 1]); + indices.push([base_index + 4, base_index, base_index + 1]); indices.push([base_index + 6, base_index + 5, base_index + 1]); indices.push([base_index + 6, base_index + 1, base_index + 2]); - indices.push([base_index + 7, base_index + 0, base_index + 4]); - indices.push([base_index + 7, base_index + 3, base_index + 0]); + indices.push([base_index + 7, base_index, base_index + 4]); + indices.push([base_index + 7, base_index + 3, base_index]); } } diff --git a/src/transformation/voxelization/voxelized_volume.rs b/src/transformation/voxelization/voxelized_volume.rs index d4eee154..12e6a3be 100644 --- a/src/transformation/voxelization/voxelized_volume.rs +++ b/src/transformation/voxelization/voxelized_volume.rs @@ -257,57 +257,47 @@ impl VoxelizedVolume { let aabb = Aabb::from_half_extents(pt, box_half_size); #[cfg(feature = "dim2")] - { - if !detect_self_intersections { - let segment = crate::shape::Segment::from(tri_pts); - let intersect = query::details::intersection_test_aabb_segment( - &aabb, &segment, - ); - - if intersect { - if keep_voxel_to_primitives_map { - data.num_primitive_intersections += 1; - result - .primitive_intersections - .push((id, tri_id as u32)); - } - - *value = VoxelValue::PrimitiveOnSurface; + if !detect_self_intersections { + let segment = crate::shape::Segment::from(tri_pts); + let intersect = + query::details::intersection_test_aabb_segment(&aabb, &segment); + + if intersect { + if keep_voxel_to_primitives_map { + data.num_primitive_intersections += 1; + result.primitive_intersections.push((id, tri_id as u32)); } + + *value = VoxelValue::PrimitiveOnSurface; + } + } else if let Some(params) = + aabb.clip_line_parameters(&tri_pts[0], &(tri_pts[1] - tri_pts[0])) + { + let eps = 0.0; // -1.0e-6; + + assert!(params.0 <= params.1); + if params.0 > 1.0 + eps || params.1 < 0.0 - eps { + continue; + } + + data.multiplicity += ((params.0 >= -eps && params.0 <= eps) + || (params.0 >= 1.0 - eps && params.0 <= 1.0 + eps)) + as u32; + data.multiplicity += ((params.1 >= -eps && params.1 <= eps) + || (params.1 >= 1.0 - eps && params.1 <= 1.0 + eps)) + as u32; + data.multiplicity += (params.0 > eps) as u32 * 2; + data.multiplicity += (params.1 < 1.0 - eps) as u32 * 2; + + if keep_voxel_to_primitives_map { + data.num_primitive_intersections += 1; + result.primitive_intersections.push((id, tri_id as u32)); + } + + if data.multiplicity > 4 && lock_high_multiplicities { + *value = VoxelValue::PrimitiveOnSurfaceNoWalk; } else { - if let Some(params) = aabb.clip_line_parameters( - &tri_pts[0], - &(tri_pts[1] - tri_pts[0]), - ) { - let eps = 0.0; // -1.0e-6; - - assert!(params.0 <= params.1); - if params.0 > 1.0 + eps || params.1 < 0.0 - eps { - continue; - } - - data.multiplicity += ((params.0 >= -eps && params.0 <= eps) - || (params.0 >= 1.0 - eps && params.0 <= 1.0 + eps)) - as u32; - data.multiplicity += ((params.1 >= -eps && params.1 <= eps) - || (params.1 >= 1.0 - eps && params.1 <= 1.0 + eps)) - as u32; - data.multiplicity += (params.0 > eps) as u32 * 2; - data.multiplicity += (params.1 < 1.0 - eps) as u32 * 2; - - if keep_voxel_to_primitives_map { - data.num_primitive_intersections += 1; - result - .primitive_intersections - .push((id, tri_id as u32)); - } - - if data.multiplicity > 4 && lock_high_multiplicities { - *value = VoxelValue::PrimitiveOnSurfaceNoWalk; - } else { - *value = VoxelValue::PrimitiveOnSurface; - } - } + *value = VoxelValue::PrimitiveOnSurface; } }; @@ -777,18 +767,18 @@ impl VoxelizedVolume { } let s = vertices.len() as u32; - indices.push([s + 0, s + 2, s + 1]); - indices.push([s + 0, s + 3, s + 2]); + indices.push([s, s + 2, s + 1]); + indices.push([s, s + 3, s + 2]); indices.push([s + 4, s + 5, s + 6]); indices.push([s + 4, s + 6, s + 7]); indices.push([s + 7, s + 6, s + 2]); indices.push([s + 7, s + 2, s + 3]); indices.push([s + 4, s + 1, s + 5]); - indices.push([s + 4, s + 0, s + 1]); + indices.push([s + 4, s, s + 1]); indices.push([s + 6, s + 5, s + 1]); indices.push([s + 6, s + 1, s + 2]); - indices.push([s + 7, s + 0, s + 4]); - indices.push([s + 7, s + 3, s + 0]); + indices.push([s + 7, s, s + 4]); + indices.push([s + 7, s + 3, s]); } } } @@ -798,24 +788,24 @@ impl VoxelizedVolume { } } -impl Into for VoxelizedVolume { - fn into(mut self) -> VoxelSet { +impl From for VoxelSet { + fn from(mut shape: VoxelizedVolume) -> Self { let mut curr_intersection_index = 0; let mut vset = VoxelSet::new(); let mut vset_intersections = Vec::new(); - vset.origin = self.origin; - vset.scale = self.scale; + vset.origin = shape.origin; + vset.scale = shape.scale; #[cfg(feature = "dim2")] let k1 = 1; #[cfg(feature = "dim3")] - let k1 = self.resolution[2]; + let k1 = shape.resolution[2]; - for i in 0..self.resolution[0] { - for j in 0..self.resolution[1] { + for i in 0..shape.resolution[0] { + for j in 0..shape.resolution[1] { for k in 0..k1 { - let id = self.voxel_index(i, j, k) as usize; - let value = self.values[id]; + let id = shape.voxel_index(i, j, k) as usize; + let value = shape.values[id]; #[cfg(feature = "dim2")] let coords = Point::new(i, j); #[cfg(feature = "dim3")] @@ -825,30 +815,24 @@ impl Into for VoxelizedVolume { let voxel = Voxel { coords, is_on_surface: false, - intersections_range: ( - curr_intersection_index as usize, - curr_intersection_index as usize, - ), + intersections_range: (curr_intersection_index, curr_intersection_index), }; vset.voxels.push(voxel); } else if value == VoxelValue::PrimitiveOnSurface { let mut voxel = Voxel { coords, is_on_surface: true, - intersections_range: ( - curr_intersection_index as usize, - curr_intersection_index as usize, - ), + intersections_range: (curr_intersection_index, curr_intersection_index), }; - if !self.primitive_intersections.is_empty() { + if !shape.primitive_intersections.is_empty() { let num_intersections = - self.data[id].num_primitive_intersections as usize; + shape.data[id].num_primitive_intersections as usize; // We store the index where we should write the intersection on the // vset into num_primitive_intersections. That way we can reuse it // afterwards when copying the set of intersection into a single // flat Vec. - self.data[id].num_primitive_intersections = + shape.data[id].num_primitive_intersections = curr_intersection_index as u32; curr_intersection_index += num_intersections; voxel.intersections_range.1 = curr_intersection_index; @@ -860,10 +844,10 @@ impl Into for VoxelizedVolume { } } - if !self.primitive_intersections.is_empty() { - vset_intersections.resize(self.primitive_intersections.len(), 0); - for (voxel_id, prim_id) in self.primitive_intersections { - let num_inter = &mut self.data[voxel_id as usize].num_primitive_intersections; + if !shape.primitive_intersections.is_empty() { + vset_intersections.resize(shape.primitive_intersections.len(), 0); + for (voxel_id, prim_id) in shape.primitive_intersections { + let num_inter = &mut shape.data[voxel_id as usize].num_primitive_intersections; vset_intersections[*num_inter as usize] = prim_id; *num_inter += 1; } diff --git a/src/utils/as_bytes.rs b/src/utils/as_bytes.rs index db0e619f..d6d4161c 100644 --- a/src/utils/as_bytes.rs +++ b/src/utils/as_bytes.rs @@ -11,12 +11,12 @@ pub trait AsBytes { } macro_rules! generic_as_bytes_impl( - ($t: ident, $dimension: expr) => ( - impl AsBytes for $t { + ($T: ident, $dimension: expr) => ( + impl AsBytes for $T { #[inline(always)] - fn as_bytes<'a>(&'a self) -> &'a [u8] { + fn as_bytes(&self) -> &[u8] { unsafe { - slice::from_raw_parts(mem::transmute(self), mem::size_of::() * $dimension) + slice::from_raw_parts(self as *const $T as *const u8, mem::size_of::() * $dimension) } } } diff --git a/src/utils/center.rs b/src/utils/center.rs index b414800e..6f9c5209 100644 --- a/src/utils/center.rs +++ b/src/utils/center.rs @@ -5,7 +5,7 @@ use na; #[inline] pub fn center(pts: &[Point]) -> Point { assert!( - pts.len() >= 1, + !pts.is_empty(), "Cannot compute the center of less than 1 point." ); diff --git a/src/utils/cleanup.rs b/src/utils/cleanup.rs index b2e853b9..1c51a146 100644 --- a/src/utils/cleanup.rs +++ b/src/utils/cleanup.rs @@ -4,7 +4,7 @@ use std::iter; /// Given an index buffer, remove from `points` every point that is not indexed. pub fn remove_unused_points(points: &mut Vec>, idx: &mut [[u32; 3]]) { let mut used: Vec = iter::repeat(false).take(points.len()).collect(); - let mut remap: Vec = (0..points.len()).map(|i| i).collect(); + let mut remap: Vec = (0..points.len()).collect(); let used = &mut used[..]; let remap = &mut remap[..]; @@ -21,7 +21,7 @@ pub fn remove_unused_points(points: &mut Vec>, idx: &mut [[u32; 3]]) remap[points.len()] = i; used[i] = used[points.len()]; } else { - i = i + 1; + i += 1; } } diff --git a/src/utils/consts.rs b/src/utils/consts.rs index 628d451c..2d0797c1 100644 --- a/src/utils/consts.rs +++ b/src/utils/consts.rs @@ -1,3 +1,5 @@ +#![allow(clippy::excessive_precision)] // Clippy will complain in f32 mode, but we also need these consts for f64. + use crate::math::Real; // pub(crate) const SIN_10_DEGREES: Real = 0.17364817766; diff --git a/src/utils/deterministic_state.rs b/src/utils/deterministic_state.rs index c5816952..1c782006 100644 --- a/src/utils/deterministic_state.rs +++ b/src/utils/deterministic_state.rs @@ -2,6 +2,7 @@ use std::collections::hash_map::DefaultHasher; use std::hash::BuildHasher; /// A hasher builder that creates `DefaultHasher` with default keys. +#[derive(Default)] pub struct DeterministicState; impl DeterministicState { diff --git a/src/utils/hashmap.rs b/src/utils/hashmap.rs index 934b980e..364ae380 100644 --- a/src/utils/hashmap.rs +++ b/src/utils/hashmap.rs @@ -86,18 +86,18 @@ impl std::hash::Hasher for FxHasher32 { let mut hash = FxHasher32 { hash: self.hash }; assert!(std::mem::size_of::() <= 8); while bytes.len() >= std::mem::size_of::() { - hash.add_to_hash(read_u32(bytes) as u32); + hash.add_to_hash(read_u32(bytes)); bytes = &bytes[std::mem::size_of::()..]; } if (std::mem::size_of::() > 4) && (bytes.len() >= 4) { - hash.add_to_hash(u32::from_ne_bytes(bytes[..4].try_into().unwrap()) as u32); + hash.add_to_hash(u32::from_ne_bytes(bytes[..4].try_into().unwrap())); bytes = &bytes[4..]; } if (std::mem::size_of::() > 2) && bytes.len() >= 2 { hash.add_to_hash(u16::from_ne_bytes(bytes[..2].try_into().unwrap()) as u32); bytes = &bytes[2..]; } - if (std::mem::size_of::() > 1) && bytes.len() >= 1 { + if (std::mem::size_of::() > 1) && !bytes.is_empty() { hash.add_to_hash(bytes[0] as u32); } self.hash = hash.hash; @@ -115,7 +115,7 @@ impl std::hash::Hasher for FxHasher32 { #[inline] fn write_u32(&mut self, i: u32) { - self.add_to_hash(i as u32); + self.add_to_hash(i); } #[inline] diff --git a/src/utils/interval.rs b/src/utils/interval.rs index 03f593b9..a6add575 100644 --- a/src/utils/interval.rs +++ b/src/utils/interval.rs @@ -77,17 +77,15 @@ pub fn find_root_intervals_to( let prev_width = candidate.width(); - for new_candidate in new_candidates.iter() { - if let Some(new_candidate) = new_candidate { - if new_candidate.width() > prev_width * na::convert(0.75) { - // If the new candidate range is still quite big compared to - // new candidate, split it to accelerate the search. - let [a, b] = new_candidate.split(); - push_candidate(a, recursion, results, candidates); - push_candidate(b, recursion, results, candidates); - } else { - push_candidate(*new_candidate, recursion, results, candidates); - } + for new_candidate in new_candidates.iter().flatten() { + if new_candidate.width() > prev_width * na::convert(0.75) { + // If the new candidate range is still quite big compared to + // new candidate, split it to accelerate the search. + let [a, b] = new_candidate.split(); + push_candidate(a, recursion, results, candidates); + push_candidate(b, recursion, results, candidates); + } else { + push_candidate(*new_candidate, recursion, results, candidates); } } } @@ -359,14 +357,12 @@ where } else { Interval(a1 * b2, a2 * b2) } + } else if b2 <= T::zero() { + Interval(a2 * b1, a1 * b2) + } else if b1 < T::zero() { + Interval(a2 * b1, a2 * b2) } else { - if b2 <= T::zero() { - Interval(a2 * b1, a1 * b2) - } else if b1 < T::zero() { - Interval(a2 * b1, a2 * b2) - } else { - Interval(a1 * b1, a2 * b2) - } + Interval(a1 * b1, a2 * b2) } } } @@ -403,38 +399,32 @@ where } } else if a1 <= T::zero() { (Interval(-infinity, infinity), None) + } else if b2 == T::zero() { + (Interval(-infinity, a1 / b1), None) + } else if b1 != T::zero() { + ( + Interval(-infinity, a1 / b1), + Some(Interval(a1 / b2, infinity)), + ) } else { - if b2 == T::zero() { - (Interval(-infinity, a1 / b1), None) - } else if b1 != T::zero() { - ( - Interval(-infinity, a1 / b1), - Some(Interval(a1 / b2, infinity)), - ) - } else { - (Interval(a1 / b2, infinity), None) - } + (Interval(a1 / b2, infinity), None) } - } else { - if a2 <= T::zero() { - if b2 < T::zero() { - (Interval(a2 / b1, a1 / b2), None) - } else { - (Interval(a1 / b1, a2 / b2), None) - } - } else if a1 < T::zero() { - if b2 < T::zero() { - (Interval(a2 / b2, a1 / b2), None) - } else { - (Interval(a1 / b1, a2 / b1), None) - } + } else if a2 <= T::zero() { + if b2 < T::zero() { + (Interval(a2 / b1, a1 / b2), None) } else { - if b2 < T::zero() { - (Interval(a2 / b2, a1 / b1), None) - } else { - (Interval(a1 / b2, a2 / b1), None) - } + (Interval(a1 / b1, a2 / b2), None) + } + } else if a1 < T::zero() { + if b2 < T::zero() { + (Interval(a2 / b2, a1 / b2), None) + } else { + (Interval(a1 / b1, a2 / b1), None) } + } else if b2 < T::zero() { + (Interval(a2 / b2, a1 / b1), None) + } else { + (Interval(a1 / b2, a2 / b1), None) } } } diff --git a/src/utils/median.rs b/src/utils/median.rs index 9eaed961..c4dd542e 100644 --- a/src/utils/median.rs +++ b/src/utils/median.rs @@ -4,7 +4,10 @@ use na; /// Computes the median of a set of values. #[inline] pub fn median(vals: &mut [Real]) -> Real { - assert!(vals.len() > 0, "Cannot compute the median of zero values."); + assert!( + !vals.is_empty(), + "Cannot compute the median of zero values." + ); vals.sort_by(|a, b| a.partial_cmp(b).unwrap()); diff --git a/src/utils/point_cloud_support_point.rs b/src/utils/point_cloud_support_point.rs index 686cbd4d..e4be18aa 100644 --- a/src/utils/point_cloud_support_point.rs +++ b/src/utils/point_cloud_support_point.rs @@ -6,8 +6,7 @@ pub fn point_cloud_support_point_id(dir: &Vector, points: &[Point]) let mut best_pt = 0; let mut best_dot = points[0].coords.dot(dir); - for i in 1..points.len() { - let p = &points[i]; + for (i, p) in points.iter().enumerate().skip(1) { let dot = p.coords.dot(dir); if dot > best_dot { diff --git a/src/utils/point_in_poly2d.rs b/src/utils/point_in_poly2d.rs index c92eb305..b14633d4 100644 --- a/src/utils/point_in_poly2d.rs +++ b/src/utils/point_in_poly2d.rs @@ -4,7 +4,7 @@ use num::Zero; /// Tests if the given point is inside of a polygon with arbitrary orientation. pub fn point_in_poly2d(pt: &Point2, poly: &[Point2]) -> bool { - if poly.len() == 0 { + if poly.is_empty() { false } else { let mut sign = 0.0; diff --git a/src/utils/ref_with_cost.rs b/src/utils/ref_with_cost.rs index 4b501ac0..cf65480d 100644 --- a/src/utils/ref_with_cost.rs +++ b/src/utils/ref_with_cost.rs @@ -22,7 +22,7 @@ impl<'a, Real: PartialEq, T> Eq for RefWithCost<'a, Real, T> {} impl<'a, Real: PartialOrd, T> PartialOrd for RefWithCost<'a, Real, T> { #[inline] fn partial_cmp(&self, other: &RefWithCost<'a, Real, T>) -> Option { - self.cost.partial_cmp(&other.cost) + Some(self.cmp(other)) } } diff --git a/src/utils/weighted_value.rs b/src/utils/weighted_value.rs index ba2667e2..2e54258e 100644 --- a/src/utils/weighted_value.rs +++ b/src/utils/weighted_value.rs @@ -27,7 +27,7 @@ impl Eq for WeightedValue {} impl PartialOrd for WeightedValue { #[inline] fn partial_cmp(&self, other: &WeightedValue) -> Option { - self.cost.partial_cmp(&other.cost) + Some(self.cmp(other)) } }