pub enum FillMode {
SurfaceOnly,
FloodFill {
detect_cavities: bool,
detect_self_intersections: bool,
},
}Expand description
Controls how voxelization determines which voxels are filled vs empty.
The fill mode is a critical parameter that determines the structure of the resulting voxel set. Choose the appropriate mode based on whether you need just the surface boundary or a solid volume.
§Variants
§SurfaceOnly
Only voxels that intersect the input surface boundary (triangle mesh in 3D, polyline in 2D) are marked as filled. This creates a hollow shell representation.
Use this when:
- You only need the surface boundary
- Memory is limited (fewer voxels to store)
- You’re approximating a thin shell or surface
Example:
use parry3d::transformation::voxelization::{FillMode, VoxelSet};
use parry3d::shape::Ball;
///
let ball = Ball::new(1.0);
let (vertices, indices) = ball.to_trimesh(20, 20);
let surface_voxels = VoxelSet::voxelize(
&vertices,
&indices,
10,
FillMode::SurfaceOnly, // Only the shell
false,
);
// All voxels are on the surface
assert!(surface_voxels.voxels().iter().all(|v| v.is_on_surface));§FloodFill
Marks surface voxels AND all interior voxels as filled, creating a solid volume. Uses a flood-fill algorithm starting from outside the shape to determine inside vs outside.
Fields:
-
detect_cavities: Iftrue, properly detects and preserves internal cavities/holes. Iffalse, all enclosed spaces are filled (faster but may fill unintended regions). -
detect_self_intersections(2D only): Iftrue, attempts to handle self-intersecting polylines correctly. More expensive but more robust.
Use this when:
- You need volume information (mass properties, volume computation)
- You want a solid representation for collision detection
- You need to distinguish between interior and surface voxels
Example:
use parry3d::transformation::voxelization::{FillMode, VoxelSet};
use parry3d::shape::Ball;
///
let ball = Ball::new(1.0);
let (vertices, indices) = ball.to_trimesh(20, 20);
let solid_voxels = VoxelSet::voxelize(
&vertices,
&indices,
15,
FillMode::FloodFill {
detect_cavities: false, // No cavities in a sphere
},
false,
);
// Mix of surface and interior voxels
let surface_count = solid_voxels.voxels().iter().filter(|v| v.is_on_surface).count();
let interior_count = solid_voxels.voxels().iter().filter(|v| !v.is_on_surface).count();
assert!(surface_count > 0 && interior_count > 0);§Performance Notes
SurfaceOnlyis faster and uses less memory thanFloodFilldetect_cavities = trueadds computational overhead but gives more accurate results- For simple convex shapes,
detect_cavities = falseis usually sufficient
Variants§
SurfaceOnly
Only consider full the voxels intersecting the surface of the shape being voxelized.
FloodFill
Use a flood-fill technique to consider fill the voxels intersecting the surface of the shape being voxelized, as well as all the voxels bounded of them.
Trait Implementations§
impl Copy for FillMode
impl Eq for FillMode
impl StructuralPartialEq for FillMode
Auto Trait Implementations§
impl Freeze for FillMode
impl RefUnwindSafe for FillMode
impl Send for FillMode
impl Sync for FillMode
impl Unpin for FillMode
impl UnwindSafe for FillMode
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.