![]() |
SWMMVis
6.0.0-alpha.4
Qt6/C++ GIS-based graphical user interface for the SWMMVis engine (6.0.0-alpha.4)
|
#include <QtGlobal>#include <functional>Go to the source code of this file.
Classes | |
| struct | mesh::RefineHook |
Callbacks consulted by Triangle's -u user test. More... | |
| class | mesh::RefineHookGuard |
Installs hook as the active refinement hook for the current thread. More... | |
Namespaces | |
| namespace | mesh |
Functions | |
| bool | mesh::refineHookWasCancelled () noexcept |
| True if the hook active on this thread observed cancellation. | |
| qint64 | mesh::refineHookTestCount () noexcept |
| Number of triunsuitable() invocations since the active guard was constructed. Useful for logging refinement cost. | |
Triangle refinement hook — cancellation, progress, and graded element sizing without modifying vendor/triangle/.
Shewchuk's Triangle exposes exactly one extension point during quality refinement: the triunsuitable() callback, invoked from testtriangle() for every candidate triangle when the -u switch is present. Upstream sanctions supplying it externally by defining EXTERNAL_TEST (see the comment block at triangle.c:1363-1384), which is how it is wired here — triangle.c itself is untouched.
Three things ride on this one hook:
CANCELLATION. Triangle's refinement loop is otherwise uninterruptible: a long -q/-a run cannot be stopped, so the GUI's Stop button is dead for its whole duration. The hook polls a caller-supplied predicate and, once cancelled, reports every triangle as suitable. The bad-triangle queue then drains and Triangle returns through its normal exit path.
This is deliberately NOT a longjmp out of triangulate(). Triangle's memory pools are freed by triangledeinit() at the very end of triangulate(); jumping out past it leaks them, and they are the dominant allocation in the whole pipeline (~200 bytes per output vertex). Draining is slightly slower to respond but leaks nothing.
-a<area> cap forces the SAME element size everywhere, which is the primary driver of output vertex count on large domains. A size function lets the caller ask for fine elements only where they matter and coarse ones elsewhere. This is the largest available lever on final mesh size.NOTE: triunsuitable() takes no user-data pointer, so the active hook has to be reachable from a free function. It is stored thread-locally rather than globally so that triangulating several domains (or, later, several tiles) concurrently stays correct.