Skip to content

feature: Shape::empty() #214

@mkovaxx

Description

@mkovaxx

Summary

An empty Shape would help simplify many constructions. For example, when a Shape collection is combined with union, either in a for loop, or via a higher-order function like Iterator::fold().

Bikeshed

Alternative names I can think of:

  • Shape::nothing()
  • Shape::null()
  • Shape::new()
  • Shape::void()

Might be possible to expose an associated constant Shape::EMPTY instead?

Practical Example

With Shape::empty() we'd be able to write the following:

let mut composite = Shape::empty();

for part in shape_iterator {
    composite = composite.union(part).into_shape();
}

Or for the functionally inclined among us, like this:

let composite = shape_iterator.fold(Shape::empty(), |acc, item| acc.union(item).into_shape());

Currently we have to write this:

let mut composite: Option<Shape> = None;

for part in shape_iterator {
    if let Some(shape) = &mut composite {
        *shape = shape.union(part).into_shape();
    } else {
        composite = Some(part);
    }
}

Theoretical Background

In general, a neutral element for an associative binary operation is a big win for ease of use. The numbers 0 and 1 make it easier to define sums and products, the empty string helps work with concatenation, a value of infinity simplifies the definition of minimum, etc. These are all examples of an algebraic structure called a monoid, which is closely tied to the notion of folding a sequence or some other "traversable" container such as a tree.

In our case, the associative binary operation is union, and Shape::empty() would be its neutral element.

Implementation

It's already possible, along these lines:

fn empty_shape() -> Shape {
    let shape = Shape::cube(1.0);
    shape.subtract(&shape).into_shape()
}

But it would be nice to instead expose the constructor TopoDS_Shape() which "Creates a NULL Shape referring to nothing."

I'd be happy to take this on. :)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions