The smooth offset potential Phi, and the offset defined as its level set Phi = c.
More...
|
| | SmoothOffsetPotential (const MatrixXd &V, const MatrixXi &E, const MatrixXi &F, const std::vector< int > &P, double delta, double dhat_factor) |
| | Build the potential of a fixed complex.
|
| |
| double | value (const VecD &p) const override |
| |
| VecD | gradient (const VecD &p) const override |
| |
| MatD | hessian (const VecD &p) const override |
| |
| double | residual_length (const VecD &p) const override |
| | First-order distance from p to the level set Phi = c, in length units.
|
| |
| bool | within_support (const VecD &p) const override |
| | Whether p is inside the support at all, i.e. Phi(p) > 0.
|
| |
| bool | is_inside_offset (const VecD &p) const override |
| | Phi decreases with distance, so the offset region is where it is still above the level.
|
| |
| std::string | describe_active (const VecD &p) const override |
| |
| virtual | ~OffsetPotential () |
| |
|
double | target_level () const |
| | The level value the offset boundary is placed on.
|
| |
|
double | delta () const |
| | The offset distance the field is calibrated to.
|
| |
| double | dhat () const |
| |
| double | level_set_slope () const |
| | |d(field)/d(distance)| at the level set on a flat stretch of input.
|
| |
| virtual bool | is_euclidean () const |
| | The Euclidean field: value() is the distance, so a distance residual is the plain one.
|
| |
template<int DIM>
class wmtk::components::topological_offset::SmoothOffsetPotential< DIM >
The smooth offset potential Phi, and the offset defined as its level set Phi = c.
Phi is C^2 with an analytic gradient and Hessian, so placing a vertex on the offset is an ordinary term in the smoothing objective and the front is smoothed by the same code path as every other vertex.
What Phi is: the offset geometric contact potential of ipc-toolkit's high_order_contact subtree, evaluated at a point q against the input complex,
Phi(q) = sum over active primitives P of b( dist(q, P), dhat )
b(d, dhat) = -(d/dhat - 1)^2 * log(d/dhat) for d < dhat, 0 otherwise
(ipc::NormalizedClampedLogBarrier). "Active" is the OGC feasible-region rule: a triangle is active at q when q projects into its interior, an edge when q projects into its interior and lies outside the wedges its incident triangles claim, a vertex when q lies in its Voronoi region. Away from features exactly one primitive contributes and Phi is a monotone function of the Euclidean distance alone; at a reentrant feature several contribute, their barriers add, and the level set bulges outward. So Phi = c is a smoothed offset, not the Euclidean one, and that difference is deliberate; the Euclidean distance is still reported as a diagnostic.
Calibration: c is not a free parameter. It is Phi at perpendicular distance delta from one large flat primitive – one active pair, no feature interaction – computed at construction through this same class, so it cannot drift from a hand-kept analytic formula. Both dimensions therefore calibrate to the same c for the same delta and dhat_factor, which tests/test_offset_potential.cpp asserts.
dhat, the support radius beyond which Phi and every derivative are identically zero, is dhat_factor * delta. delta must sit strictly inside the support (at exactly dhat the potential and its gradient are both 0, so a vertex there gets no direction to move in) and the support must not be so wide that distant parts of the complex reach the level set. A vertex beyond dhat is a hard error – see TopoOffsetTriMesh::check_offset_within_support() and its 3D twin.
Threading: an evaluation writes the query point into a scratch vertex matrix and builds a collision set around it, so it holds per-thread state; value, gradient and hessian are const and safe to call concurrently from the smoothing pass.