Detect incorrectly merged perimeters MUCH faster. #841 [rebuild] [release]

This commit is contained in:
Dustin Carlino 2022-02-26 20:24:32 +00:00
parent ed1602ab40
commit 23cf7c8d0c
2 changed files with 24 additions and 6 deletions

View File

@ -264,17 +264,34 @@ impl Perimeter {
// Make sure we didn't wind up with any internal dead-ends // Make sure we didn't wind up with any internal dead-ends
self.collapse_deadends(); self.collapse_deadends();
// TODO This is an expensive sanity check needed for // TODO Something in this method is buggy and produces invalid merges. Use a lightweight
// https://github.com/a-b-street/abstreet/issues/841 // detection and bail out for now. https://github.com/a-b-street/abstreet/issues/841
if LOSSLESS_BLOCKFINDING && self.clone().to_block(map).is_err() { if LOSSLESS_BLOCKFINDING {
if let Err(err) = self.check_continuity(map) {
error!(
"A merged perimeter couldn't be blockified: {}. {:?}",
err, self
);
*self = orig_self; *self = orig_self;
*other = orig_other; *other = orig_other;
return false; return false;
} }
}
true true
} }
fn check_continuity(&self, map: &Map) -> Result<()> {
for pair in self.roads.windows(2) {
let r1 = map.get_r(pair[0].road);
let r2 = map.get_r(pair[1].road);
if r1.common_endpoint(r2) == CommonEndpoint::None {
bail!("Part of the perimeter goes from {:?} to {:?}, but they don't share a common endpoint", pair[0], pair[1]);
}
}
Ok(())
}
/// Try to merge all given perimeters. If successful, only one perimeter will be returned. /// Try to merge all given perimeters. If successful, only one perimeter will be returned.
/// Perimeters are never "destroyed" -- if not merged, they'll appear in the results. If /// Perimeters are never "destroyed" -- if not merged, they'll appear in the results. If
/// `stepwise_debug` is true, returns after performing just one merge. /// `stepwise_debug` is true, returns after performing just one merge.

View File

@ -303,6 +303,7 @@ impl Lane {
} }
} }
#[derive(PartialEq)]
pub enum CommonEndpoint { pub enum CommonEndpoint {
/// Two lanes/roads share one endpoint /// Two lanes/roads share one endpoint
One(IntersectionID), One(IntersectionID),