Grease Pencil might be a good tool for that, but - ashamed to admit - I still have to learn it. I figured simple poly curves could be used to mark start and end of such marks, and then Geometry Nodes could use the shortest path between them, which for short enough segments should work:
- The first frame removes triangles just to make it less common for the shortest path to go wrong way; obviously if you want to mark a path through a triangle (which wouldn't really be a loop-path), you would need to mute the green node inside orange frame.
- The yellow frame subdivides, where all new edges are the all possible loops.
- The red frame deletes all but the new edges, to only keep the loops. This again improves reliability and makes it easier to position the curve endpoints to get a correct path, as well as increases maximum path length, before the shortest path algorithm goes sideways.
- The green frame converts faces to points at their centers and snaps the endpoints to these face-centers-points, because apparently Blender doesn't provide such an option (only edge centers).
- The Fuchsia frame finds the index of the nearest endpoint and assigns it to the points mentioned above; only one, the nearest point will be stored in the attribute, so you can't assign multiple endpoints to a single face; could change that by moving instanced copies apart together with their respective curves and only then associate endpoints.
- The pink frame checks the distance to actually mark the face-centers-points as start/end; this and previous frame could be combined using "Store Named Attribute" which supports selection.
- 2nd green frame duplicates the mesh for each curve, because otherwise I don't think I could change "End Vertex" based on "Star Vertex".
- Light blue frame could maybe be more readable if it would check captured endpoint index → modulo 2 → equal 0 (first point of a spline = start) AND index → evaluate on domain: spline → equal captured instance index AND the boolean attribute.
- Dark blue frame likewise could check with modulo equal 1.
- Violet frame takes a normal of nearest surface to push the curve outside, which is important as sometimes triangulation may hide the curves snapped to quads…
- Then just bevel the curve and done:
For a normal usage one probably would use much shorter curves, but I wanted to show roughly the maximum possible length of the curves before the shortest path algorithm fails (by finding the shortest path instead of the loop). Also, it is the user's responsibility to position the endpoints correctly, displayed by orange, L-shaped path.
The look could be improved using e.g. new Blur node (default 1,1 endpoints → boolean not could be used as weight to not move the ends), or converting to mesh, subdivision surface and converting back, or setting the spline type to bezier and handle types to auto… Arrows could be positioned on caps (again using endpoints and align to euler to tangent) or radius could be suddenly increased and slowly decreased to 0 near the ends… I figured it's all too easy, subjective and unnecessary noise both in the node tree and effect, naked curves communicate the flow well enough. Similarly ensuring the curves don't overlap is fancy but is it really needed?:
("Delete Original Edges" → Sample Nearest Point: Index → Group ID of Accumulate Field Node, add "Trailing" to the scale of the Set Position: offset)