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

Add Cycle validation #1686

Merged
merged 7 commits into from
Mar 16, 2023
Merged

Add Cycle validation #1686

merged 7 commits into from
Mar 16, 2023

Conversation

A-Walrus
Copy link
Contributor

Add basic checks to ensure that Cycles contain at least 2 half-edges, and that all half-edges are connected to each-other.

@A-Walrus A-Walrus requested a review from hannobraun as a code owner March 16, 2023 05:17
Copy link
Owner

@hannobraun hannobraun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this pull request, @A-Walrus! We used to have a validation check for that, but it seems like it got lost during my recent clean-up, and I missed that. Thank you for adding it back!

I've left some comments. Only one of them is critical (the one about HalfEdge::end_position). The other ones would be nice-to-have, but I'd be perfectly happy to merge this PR without them being addressed.

Comment on lines 91 to 93
// Computing the surface position from the curve position is fine.
// `HalfEdge` "owns" its end position. There is no competing code that
// could compute the surface position from slightly different data.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is completely false, and dangerously so. It used to be true for the start position (from where it was adapted), but by adding this method, you add the competing code that the comments in both methods claim doesn't exist.

This is a problem, because sooner or later someone is going to call this method to compare it to the start position of the next half-edge in the cycle, or use it in some scenario where it's assumed that both positions are going to be equal.

I think this method shouldn't exist. It's still possible to make the same mistake doing exactly what the method does internally, but at the very least we shouldn't make that easy. (And there should be better documentation around this, but that's a separate issue.)

However, what the new validation check does is perfectly fine, as it uses an epsilon value (config.identical_max_distance) for the comparison. I think it would be best to inline the body of this method into the validation check.

Comment on lines 54 to 58
// If there are no half edges
if cycle.half_edges().next().is_none() {
errors.push(Self::NotEnoughHalfEdges.into());
return;
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine as-is, but I think it would be even better, if this check had its own method. Then there would be an easy 1:1 relationship between error conditions and methods. I think this would be slightly clearer.

Comment on lines 61 to 64
// Chain the first half_edge so that we make sure that the last connects to the first.
// This unwrap will never fail because we checked before that there are enough half_edges.
.chain(std::iter::once(cycle.half_edges().next().unwrap()))
.tuple_windows()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also fine as-is, but there's an easier (and less panicky) way to do the same thing:

Suggested change
// Chain the first half_edge so that we make sure that the last connects to the first.
// This unwrap will never fail because we checked before that there are enough half_edges.
.chain(std::iter::once(cycle.half_edges().next().unwrap()))
.tuple_windows()
.circular_tuple_windows()

))
));

Ok(())
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not strictly necessary, but it would be nicer to also have a test that checks for the second validation error (NotEnoughHalfEdges).

Copy link
Owner

@hannobraun hannobraun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the changes, @A-Walrus!

Looks like HalfEdge::end_position still exists in the final version. If you can remove it, then this is ready to merge.

Copy link
Owner

@hannobraun hannobraun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again, @A-Walrus. Looks great now!

Forgot about the fact that a single circle counts as a cycle
 - Inlined the `end_position` function to not expose potentially error-
   prone behaviour.
 - Seperate empty check to new method.
 - Switch to `circular_tuple_windows`
 - Add test for empty cycle
@hannobraun hannobraun enabled auto-merge March 16, 2023 16:30
@hannobraun hannobraun merged commit c4343ab into hannobraun:main Mar 16, 2023
@A-Walrus A-Walrus deleted the cycle_validation branch September 25, 2023 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants