Closed olson-sean-k closed 4 years ago
There are duplicate keys in the perimeters constructed by FaceSplitSnapshot::snapshot
. This causes this error to be returned.
It looks like a face insertion may be the problem. During a split, two face insertions that each use a perimeter with three vertices are performed. After this operation, an unrelated face is corrupted, and reports having 11 interior arcs. The arcs form a consistent ring, but are clearly nonsense. This could be a deeper problem with arc connectivity...
It seems that some vertices never have a leading arc despite being a part of a ring. Looking at the connectivity set of vertices during face insertions, there are vertices with no connectivity that are part of the connectivity of other vertices! Sure enough, trying to access the leading arc of all vertices in the graph also leads to a panic:
for vertex in graph.vertices() {
let arc = vertex.into_outgoing_arc(); // PANIC!
let _ = arc.key();
}
Implementing #17 likely would have caught this. Test coverage and exercising of the mutation API is not very good, but changing the commit
implementation for VertexMutation
already causes test failures for composite edge splits:
fn commit(self) -> Result<Self::Mutant, Self::Error> {
let VertexMutation {
storage: vertices, ..
} = self;
// Fail if any vertex payloads have no leading arc. FAILS.
for (_, vertex) in vertices.iter() {
let _ = vertex.arc.ok_or_else(|| GraphError::TopologyMalformed)?;
}
Ok(Core::empty().bind(vertices))
}
I believe this is the problematic line of code. It is likely more correct to disconnect vertices from their leading arcs, but the code in split_with_cache
will leave the vertex B without a leading arc when splitting from the arc AB.
This is fixed by 6bfe175 on the mutate
branch. I plan to do more work on that branch to improve the mutation
module.
I've cherry-picked 043abfe from the mutate
branch into master
. That change provides the basic fix. It was lingering on the mutate
branch for a while, but since this is an easy bug to encounter, I wanted to pull it out of mutate
so that it doesn't get held up by other changes.
Triangulating a graph constructed by subdividing a simple face appears to cause corruption. I discovered this while experimenting with the
subdivide
example, which demonstrates this function:Using this function, the following code causes a panic when calling
triangulate
:So far, it seems that the subdivisions work as intended. The number of vertices and faces is correct and so is the arity of the faces. However, triangulation suddenly fails when it encounters a face with arity 11. That's very strange:
I suspect that something is wrong in the mutation API (specifically
FaceSplitSnapshot
andsplit_with_snapshot
), but I'm not sure. For example, maybe the snapshot is failing to identify the perimeters for the two newly inserted faces for the split.