watermark::TriangleRatio

Layer 3: a watermark in the area ratios of adjacent triangle pairs.

Declared in src/libs/libwatermark/watermark/methods/TriangleRatio.hpp
Group watermark

Detailed description

embed() writes each bit into the area ratios of a number of triangle pairs. A ratio above or below 1 by more than the threshold carries the sign of the bit, multiplied by a spread sequence that the key generates. To get the target ratio, the class moves the vertices of a triangle by no more than a fraction of its edge length. Options sets the threshold, that fraction, and the number of pairs for each bit.

A ratio does not change when the mesh is scaled, rotated or moved, so the mark survives these transforms and a format conversion. Remeshing, decimation and heavy noise remove it.

detect() does not work yet: see the note on that function.

Member function documentation

detect

watermark::Result<watermark::TriangleRatio::DetectResult> TriangleRatio::detect(const stl::Mesh &mesh, const watermark::Key &key, int expectedLength = 0)

⚠ BLIND DETECTION IS NOT IMPLEMENTED HERE EITHER.

This has the same hole as `VertexDisplacement::detect()`, which carries the long form of the explanation. There is no reference estimate of what the triangle ratios WOULD have been without the watermark, so the correlation runs on the received ratios themselves rather than on a residual. The length header therefore decodes to noise — 0 in `testTriangleDetectBasic` — and the function returns `NotDetected`.

Named here so that the next reader does not conclude the method works and only the threshold is wrong. `testTriangleDetectBasic` and `testTriangleRoundTrip` carry a matching QEXPECT_FAIL.

The function looks for the mark of key in mesh. expectedLength is the payload length in bytes, or 0 to read the length from the header. Returns the detection result, or an error for an empty mesh, an invalid key or a mesh with too few triangles.