Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose mutations for removing topology in views. #18

Open
olson-sean-k opened this issue Aug 28, 2018 · 4 comments
Open

Expose mutations for removing topology in views. #18

olson-sean-k opened this issue Aug 28, 2018 · 4 comments

Comments

@olson-sean-k
Copy link
Owner

Currently, the mutation API is strictly internal and is not accessible to user code. It is also the only API that directly exposes basic topological operations, including removals. As this API matures, I've considered exposing it directly to enable more advanced usage of Plexus, but I'd like to expose most necessary operations directly via views using a topologically sound API that avoids low-level operations.

At the moment, views do not expose any operations resulting in a net loss of topological structures and provide no direct removal operations. It's not too clear to me how best to accomplish this, but views should expose some way to remove topology! This is deceptively complex. For example, what exactly should happen if a half-edge is removed? When should a removal affect other topological structures? For example, when a face is removed, should only the face be removed, or also its edges and vertices? How does topology collapse or recompose?

@virtualritz
Copy link

Have you looked at OpenMesh and He_Mesh? They both use the half edge data structure and could serve as inspiration for this.

@olson-sean-k
Copy link
Owner Author

olson-sean-k commented Jan 30, 2019

So far, I'm experimenting with a simple hierarchical model for removals. When topology is removed, any and all dependent topology is also removed. This means that removing faces is the least destructive and removing vertices is the most destructive; no topology depends on faces, but all other topology depends on vertices (transiently or otherwise).

Some such removals have been implemented in views by 8cc191c and 38c0a88. Additionally, certain operations also result in removals and often compose a removal with insertions, such as collapsing edges or joining adjacent faces over an edge.

This differs from OpenMesh, which allows topology to be removed individually. I'd like to avoid that model, because it can easily leave a graph in an inconsistent state and one of the design goals of Plexus is to avoid that kind of API. (This is not entirely out of the question; there's a chance that the internal mutation API, which behaves this way, may be exposed.)

This can be more cumbersome, but should ultimately allow for the same mutations. OpenMesh provides a simple example that removes topology from a cube.

In this example we delete all faces except one and the corresponding vertices.

That may look something like this in Plexus:

let mut graph = Cube::new()
    .polygons_with_position_from(Bounds::unit_radius())
    .collect_with_indexer::<MeshGraph<Point3<f64>>, _>(HashIndexer::default())?;
// Preserve the target face "abc".
let abc = graph.faces().nth(0).unwrap().key();
let (x, y) = {
    // Traverse from the target face to its opposite face.
    let face = graph
        .face(abc)
        .unwrap()
        .into_arc()
        .into_opposite_arc()
        .into_next_arc()
        .into_next_arc()
        .into_opposite_arc()
        .into_face()
        .expect("cube");
    // Traverse the opposite face to opposing vertices.
    let mut vertices = face.vertices().map(|vertex| vertex.key()).step_by(2);
    (
        vertices.next().expect("cube"),
        vertices.next().expect("cube"),
    )
};
// Remove the vertices (along with their associated edges and faces).
graph.vertex_mut(x).unwrap().remove()?;
graph.vertex_mut(y).expect("cube").remove()?;

@olson-sean-k
Copy link
Owner Author

This differs from OpenMesh, which allows topology to be removed individually.

Hmm, that's not quite right. In the linked example, removing vertices in OpenMesh implicitly removes their associated edges. Only faces are removed beforehand.

@olson-sean-k
Copy link
Owner Author

This is nearly fixed; only vertex removal is yet unimplemented and there is a remaining bug in arc removals. Removals are destructive, and will always remove any dependent topology.

There are still some related questions to be answered though. For example, should disjoint vertices be allowed? I've so far designed around the idea that they should not. Disjoint vertices seem degenerate in a directed graph. If this is not allowed, then topological dependencies become a bit more complicated. Still, I think this will lead to a workable design. Hopefully this issue can be closed soon. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants