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

UVAtlas is quadratic in the number of boundaries #58

Closed
bitonic opened this issue Mar 1, 2021 · 3 comments
Closed

UVAtlas is quadratic in the number of boundaries #58

bitonic opened this issue Mar 1, 2021 · 3 comments

Comments

@bitonic
Copy link

bitonic commented Mar 1, 2021

In the PrepareProcessing step, this loop

while (!m_currentChartHeap.empty())
will essentially run once per boundary. A bit below in the stack, this function
HRESULT CIsochartMesh::CalMinPathBetweenBoundaries(
will run, calculating the minimum path for each boundaries. Moreover, CalMinPathToOtherBoundary loops through all the vertices multiple times.

This makes the complexity of the prepare step O(number_of_boundaries * number_of_boundaries * number_of_vertices)

I have attached a mesh made out of ~150000 vertices and ~5000 boundaries (mostly composed of 0-area holes, but I don't think that matters). In this case the runtime of PrepareProcessing is unbearably slow (I let it run for 4hrs and it did not terminate). The flame graph looks something like this:

Screenshot from 2021-03-01 07-41-33

I might give a shot at fixing this myself, but I wanted to report this behavior for other users first.

mesh-clean.zip

@bitonic bitonic changed the title UVAtlas performs poorly for meshes with many sub-meshes (and therefore many boundaries) UVAtlas is quadratic in the number of boundaries Mar 1, 2021
@bitonic
Copy link
Author

bitonic commented Mar 1, 2021

Possible more precise implementation idea:

  • Store the information about boundaries (allBoundaryList, boundaryRecord, distance between boundary extrema) per-component, rather than globally;
  • When cutting a chart by joining two boundary extrema, invalidate only the information for the boundaries in the same component.

This would avoid recomputing boundary distances globally -- you only need to recompute the distances within the same component. This is correct since cutting a chart will only affect boundary distances within the same component.

This would fix the pathological behavior in my case, since it's not the case that a single connected component has 5k boundaries. I suspect this will be the case for most meshes, although I'm not sure. It would definitely be an improvement.

@bitonic
Copy link
Author

bitonic commented Mar 1, 2021

Actually, even more generally: we can store the boundary information per-chart, and then invalidate information within the same chart.

@walbourn
Copy link
Member

If you have a pull request with this optimization, I'd be happy to take a look at it.

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