Conversation
BreakNonManifoldEdges() walks the corners around each pivot vertex and, for every edge, scans the list of edges already seen around that pivot for one with the same sink vertex. The scan makes the walk quadratic in the valence of the pivot. A hub vertex with a high valence is enough to make it the slowest stage of CornerTable::Init(). The list is replaced by a table indexed by sink vertex. An entry keeps the first two corners stored for its sink vertex in the current walk. The scan takes the first matching corner that is not the opposite of the current edge corner, and the stored corners are all different, so the first two are the only ones it can take. The table is sized once by the vertex count and a walk counter marks which entries belong to the current pivot, so nothing is cleared between pivots. The TODO above the restart loop is left as it is. That loop runs at most a few sweeps on the meshes we measured. The cost is in the scan. Encoding a closed fan with two hubs of valence 100000 takes 2.5 s before and 0.22 s after (Release, MSVC). The output is byte-identical on the fan, on the test meshes including test_nm.obj and non_manifold_wrap.obj at several compression levels, and the corner tables are identical on 6000 random triangle soups, 3858 of which have edges broken. The second slot keeps the result exact when two edges with the same sink vertex were stored before a match, but the random soups never reached it.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BreakNonManifoldEdges() walks the corners around each pivot vertex and, for every edge, scans the list of edges already seen around that pivot for one with the same sink vertex. The scan makes the walk quadratic in the valence of the pivot, and a single hub vertex with a high valence is enough to make it the slowest stage of CornerTable::Init().
This replaces the list with a table indexed by sink vertex. An entry keeps the first two corners stored for its sink vertex in the current walk. The scan takes the first matching corner that is not the opposite of the current edge corner, and the stored corners are all different, so the first two are the only ones it can take. The table is sized once by the vertex count and a walk counter marks which entries belong to the current pivot, so nothing is cleared between pivots.
The TODO above the restart loop is left as it is. That loop runs at most a few sweeps on the meshes I measured. The cost is in the scan.
Measurements, Release build with MSVC, encoding a closed fan with two hubs:
Verification: