pub struct RefinementParameters<S: SpadeNum + Float> { /* private fields */ }
Expand description

Controls how Delaunay refinement is performed.

Refer to ConstrainedDelaunayTriangulation::refine and methods implemented by this type for more details about which parameters are supported.

Example

use spade::{AngleLimit, ConstrainedDelaunayTriangulation, Point2, RefinementParameters};

fn refine_cdt(cdt: &mut ConstrainedDelaunayTriangulation<Point2<f64>>) {
    let params = RefinementParameters::<f64>::new()
        .exclude_outer_faces(true)
        .keep_constraint_edges()
        .with_min_required_area(0.0001)
        .with_max_allowed_area(0.5)
        .with_angle_limit(AngleLimit::from_deg(25.0));

    cdt.refine(params);
}

Implementations§

source§

impl<S: SpadeNum + Float> RefinementParameters<S>

source

pub fn new() -> Self

Creates a new set of RefinementParameters.

The following values will be used by new and Self::default:

  • exclude_outer_faces: disabled - all faces are used for refinement
  • keep_constraint_edges: disabled
  • min_required_area: disabled - no lower area limit is used
  • max_allowed_area: disabled - no upper area limit is used
  • angle_limit: 30 degrees by default.
  • num_additional_vertices: 10 times the number of vertices in the triangulation
source

pub fn with_angle_limit(self, angle_limit: AngleLimit) -> Self

Specifies the smallest allowed inner angle in a refined triangulation.

The refinement algorithm will attempt to insert additional points (called steiner points) until the minimum angle is larger than the angle bound specified by the refinement parameters.

Defaults to 30 degrees.

Note that angle limits much larger than 30 degrees may not always terminate successfully - consider checking RefinementResult::refinement_complete to make sure that the angle limit could actually be applied everywhere.

Examples of different angle limits
0° (no angle refinement)20°30°34°

See also ConstrainedDelaunayTriangulation::refine

source

pub fn with_min_required_area(self, min_area: S) -> Self

Specifies a lower bound for a triangles area.

The algorithm will attempt to ignore any triangle with an area below this limit. This can also prevent an exhaustion of additionally available vertices (see Self::with_max_additional_vertices).

Note that there is no guarantee that no face below this area bound will be kept intact - in some cases, a split will still be required to restore the triangulation’s Delaunay property. Also, this value does not specify a lower bound for the smallest possible triangle in the triangulation.

Should be set to something lower than Self::with_max_allowed_area. If this method is not called, no lower bound check will be performed.

source

pub fn with_max_allowed_area(self, max_area: S) -> Self

Specifies an upper bound for triangle areas in the triangulation.

By default, the refinement tries to be conservative in how many vertices it adds. This will lead to an uneven triangle size distribution - areas with larger input features will contain fewer, larger triangles whereas regions with small features will contain more densely packed triangles. By specifying an upper area bound for triangles, the resulting triangle sizes can be made more similar as any large triangle above the bound will be split into smaller parts.

Examples of different maximum area values
No max area Max area: 200 Max area: 100

Should be set to something larger than Self::with_min_required_area. If this method is not called, no upper area bound check will be performed.

source

pub fn with_max_additional_vertices( self, max_additional_vertices: usize ) -> Self

Specifies how many additional vertices may be inserted during Delaunay refinement.

Refinement may, in some cases, fail to terminate if the angle limit is set too high (see with_angle_limit). Simply stopping the refinement after a certain number of vertices has been inserted is an easy way to enforce termination. However, the resulting mesh may exhibit very poor quality in this case - some areas may have become overly refined, others might be overlooked completely. Consider changing the parameters (most notably the angle limit) if the refinement runs out of vertices.

Use RefinementResult::refinement_complete to check if the number of additional vertices was sufficient.

source

pub fn keep_constraint_edges(self) -> Self

Prevents constraint edges from being split during refinement.

By default, constraint edges may be split in order to restore the triangulation’s Delaunay property. The resulting two new edges will become new constraint edges, hence the original shape outlined by constraint edges remains the same - no “gaps” or deviations are introduced.

Enabling this option will, in general, reduce the quality of the resulting mesh - it is not necessarily Delaunay anymore and faces adjacent to long constraint edges may violate the configured AngleLimit.

source

pub fn exclude_outer_faces(self, exclude: bool) -> Self

Allows to exclude outer faces from the refinement process.

This is useful if the constraint edges form a closed shape with a clearly defined inner and outer part. Spade will determine inner and outer faces by identifying which faces can be reached from the outer face without “crossing” a constraint edge, similar to a flood fill algorithm.

Any holes in the triangulation will also be excluded. More specifically, any point with an odd winding number is considered to be inner (see e.g. Wikipedia).

Note that excluded faces may still be subdivided if a neighboring edge needs to be split. However, they will never be the cause for a subdivision - their angle and area is ignored.

The resulting outer faces of the triangulation are returned by the call to refine, see RefinementResult::excluded_faces.

Example
UnrefinedRefined

A refinement operation configured to exclude outer faces. All colored faces are considered outer faces and are ignored during refinement. Note that the inner part of the “A” shape forms a hole and is also excluded.

Trait Implementations§

source§

impl<S: Clone + SpadeNum + Float> Clone for RefinementParameters<S>

source§

fn clone(&self) -> RefinementParameters<S>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<S: Debug + SpadeNum + Float> Debug for RefinementParameters<S>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<S: SpadeNum + Float> Default for RefinementParameters<S>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<S: PartialEq + SpadeNum + Float> PartialEq for RefinementParameters<S>

source§

fn eq(&self, other: &RefinementParameters<S>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<S: SpadeNum + Float> StructuralPartialEq for RefinementParameters<S>

Auto Trait Implementations§

§

impl<S> RefUnwindSafe for RefinementParameters<S>
where S: RefUnwindSafe,

§

impl<S> Send for RefinementParameters<S>
where S: Send,

§

impl<S> Sync for RefinementParameters<S>
where S: Sync,

§

impl<S> Unpin for RefinementParameters<S>
where S: Unpin,

§

impl<S> UnwindSafe for RefinementParameters<S>
where S: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.