{
  "type": "object",
  "description": "Rebuilds the map between an application's input surface and its output from the history the application recorded (history_output): one bijective local map per operation, composed in order. operation selects what to do with it: report on it (info), map points (map), carry fields (transfer), follow feature points (features), or do the same through a tet mesh's volume (volume, map_volume).",
  "properties": {
    "application": {
      "type": "string",
      "description": "Application name must be tracking.",
      "enum": [
        "tracking"
      ]
    },
    "history": {
      "type": "string",
      "description": "A history, recorded by an application's history_output, from which the map is rebuilt: a surface's (isotropic_remeshing, qslim, shortest_edge_collapse, tetwild, simwild) or curves' (triwild); the history says which. On the file route the file it wrote, on the memory route the bytes it returned in its report as history (a JSON binary value, bytes in Python; wm.read_history reads them from a file). The memory route never takes a file name here."
    },
    "input": {
      "type": "string",
      "description": "transfer: the surface the history starts from -- the same triangles in the same order: a gmsh file, as io::read_mesh (wm.read_mesh) reads it, whose triangle fields are carried onto the output -- per face (labels), or per corner (uv and normal, three values per corner, corner after corner: texture coordinates) -- or a triangle mesh of another format, as read, with none. Empty: the input files of the application that recorded the history, from its parameters -- refused for a history recorded on the memory route, whose input was a mesh. Every output face gets input_face too, the input face its centroid maps to. On the memory route: the key of the mesh the history starts from, which a transfer needs; the output surface is returned as mesh.",
      "default": ""
    },
    "output": {
      "type": "string",
      "description": "transfer: the output surface, written as a gmsh file through io::write_mesh, the carried fields as attributes of its triangles: what wm.read_mesh reads.",
      "default": "out.msh"
    },
    "output_obj": {
      "type": "string",
      "description": "transfer: also write the output as a textured Wavefront OBJ, with uv_field as its texture coordinates and a material mapping `texture`. Empty: not written. Not on the memory route, which writes no files.",
      "default": ""
    },
    "uv_field": {
      "type": "string",
      "description": "transfer: the per-corner field output_obj takes its texture coordinates from (the first two values of each corner).",
      "default": "uv"
    },
    "texture": {
      "type": "string",
      "description": "transfer: the image the material of output_obj maps.",
      "default": "checker.png"
    },
    "input_dir": {
      "type": "string",
      "description": "Directory where the input files are located. This is injected by the application and should not be set by the user.",
      "default": ""
    },
    "operation": {
      "type": "string",
      "description": "info: build the map and report what it holds, where it stops being a bijection, and how far the output's face centroids (segment midpoints, for curves) move when mapped to the input and back. transfer (surfaces): carry every field of `input`'s triangles onto the output surface and write it to `output` (on the memory route: return it as mesh). map: map the points of the file `points` to the output (direction to_output) or back to the input (to_input), and write them to `output_points`; file route only. features (curves): write the input's feature points -- curve ends, junctions, input points -- to `output_points`, one `input_vertex output_vertex` per line: a vertex of the input files (the curve files' vertices, in order, then the point files', from 0) and the output vertex it ended at, -1 for none; on the memory route the report holds them instead, as feature_points, a list of such pairs. volume (tet meshes): build the map of the volume from volume_history, and check it on `samples` points near the tracked surface of tet_mesh (the mesh the volume history starts from: <output>_history_input.msh, the output mesh history_input on the memory route): how far they move, the map's conformal distortion and Jacobian there, whether they end in the same region of output_tet_mesh (the mesh it ends at: simwild's <output>.msh, tetwild's <output>_history_output.msh -- on the memory route the output meshes mesh and history_output), and how close the inverse brings them back; the report holds what it finds. Without tet_mesh, every operation's map is built. map_volume: map the points of `points` through the volume, to the output (direction to_output) or back (to_input), and write them to output_points: `x y z` per line, written back with the tags of their region; or `tet b0 b1 b2 b3`, a tet of tet_mesh (to_output) or output_tet_mesh (to_input) -- a row of the file's tets, as io::read_mesh (wm.read_mesh) gives them -- and barycentric coordinates in its corners' order, written back as a tet of the other mesh, of the point's own region, -1 for none; file route only.",
      "default": "info",
      "enum": [
        "info",
        "transfer",
        "map",
        "features",
        "volume",
        "map_volume"
      ]
    },
    "log_file": {
      "type": "string",
      "description": "Logs are not just printed on the terminal but also saved in this file.",
      "default": ""
    },
    "tet_mesh": {
      "type": "string",
      "description": "transfer: the tet mesh (gmsh) the history's application wrote, whose tracked surface is where the history ends. With output_tet_mesh, the fields are written onto it: a copy of it, with the tracked surface as rows of its triangle block, on its own vertices by the ids the history saved, carrying the fields. A tracked face the block has already (a face tag of simwild's) takes the fields on its row; the others are rows added after them. A row that is no tracked face gets 0, and input_face -1. volume: the tet mesh the volume history starts from, sampled near its tracked surface; on the memory route the key of a mesh given.",
      "default": ""
    },
    "output_tet_mesh": {
      "type": "string",
      "description": "transfer: where to write tet_mesh with the fields on its tracked surface. On the memory route tet_mesh is the key of a mesh, and the result is returned as tet_mesh; nothing is written. volume: the tet mesh the volume history ends at, which each sampled point is checked to end in its region of; on the memory route the key of a mesh given.",
      "default": ""
    },
    "points": {
      "type": "string",
      "description": "map: a text file of points, one per line, numbers separated by blanks, '#' starting a comment. On the input (direction to_output): `face b0 b1 b2`, a triangle of the input files -- the triangles of all of them, in order, as the files hold them, from 0 -- and barycentric coordinates with respect to its corners in file order; for a history that starts at a tet mesh's tracked surface (simwild on a .msh input), `v0 v1 v2 b0 b1 b2`, three vertices of the tet mesh the history starts from (<output>_history_input.msh) at the corners of a tracked face, in any order, with barycentric coordinates in that order. On the output (direction to_input): `face b0 b1 b2`, a triangle of the output file, for an application whose output is a surface (isotropic_remeshing); `v0 v1 v2 b0 b1 b2`, three vertices of the output tet mesh at the corners of a tracked face, in any order, with barycentric coordinates in that order, for one whose output is a tet mesh (tetwild, simwild). On curves (triwild): `segment b0 b1` on the input, a segment of the input curve files -- the segments of all of them, in order, a polyline's consecutive vertex pairs, from 0 -- with barycentric coordinates with respect to its ends in file order; `v0 v1 b0 b1` on the output, two vertices of the output mesh at the ends of a tracked edge, in either order, with barycentric coordinates in that order.",
      "default": ""
    },
    "output_points": {
      "type": "string",
      "description": "map: where to write the mapped points, one line per point of `points`, in the same order, as described for `points` on the side they are mapped to, relative to input_dir as `points` is. A point with no image has the id -1. features: where to write the feature points, relative to input_dir too.",
      "default": ""
    },
    "direction": {
      "type": "string",
      "description": "map: to_output maps points on the input to the output; to_input maps points on the output back to the input, the inverse map.",
      "default": "to_output",
      "enum": [
        "to_output",
        "to_input"
      ]
    },
    "smoothing": {
      "type": "string",
      "description": "How the map follows a vertex smoothing step. flatten: the vertex's star before and after the move is flattened jointly, so points stay where they were on the surface, at one SLIM solve per move; on curves, points keep their place along the curve, by arc length. barycentric: points keep their face (segment) and barycentric coordinates, riding along with the vertex by at most its step, at no cost, as BijectiveRemesh does.",
      "default": "flatten",
      "enum": [
        "flatten",
        "barycentric"
      ]
    },
    "scaffold": {
      "type": "string",
      "description": "The scaffold of each local map's joint flattening, which keeps the outline the two patches share a simple polygon while SLIM lowers their distortion. box: the region between the outline and a box three times the patch, triangulated anew before every iteration, as in BijectiveRemesh; it follows the patch wherever the flattening takes it. ring: one ring of triangles out to a fixed copy of the outline; about 2.4 times faster, but it pulls the outline back and keeps it from stretching, so local maps are more distorted.",
      "default": "box",
      "enum": [
        "box",
        "ring"
      ]
    },
    "collapse_patch": {
      "type": "string",
      "description": "The faces each collapse's local map flattens. both_stars: the stars of both ends of the edge before, onto the survivor's star after; the least distorted surface map. removed_star: the removed vertex's star before, onto the faces it becomes, with the survivor on the outline: more distorted on the surface, but it changes only the faces the collapse changes, which is what a map of the volume around the surface needs. Where those faces after are not a disk on the same outline (a vertex of the boundary or a curve collapsed into one off it), both stars.",
      "default": "both_stars",
      "enum": [
        "both_stars",
        "removed_star"
      ]
    },
    "volume_history": {
      "type": "string",
      "description": "volume, map_volume: the volume history (an application's volume_history_output) recorded with `history`, the surface history. On the file route the file it wrote, on the memory route the bytes it returned in its report as volume_history (a JSON binary value, bytes in Python; wm.read_history reads them from a file).",
      "default": ""
    },
    "samples": {
      "type": "integer",
      "description": "volume: how many points to sample near the tracked surface of tet_mesh.",
      "default": 1000
    },
    "$schema": {
      "type": "string"
    }
  },
  "required": [
    "application",
    "history"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://wildmeshing.github.io/wildmeshing-toolkit/schemas/tracking.json",
  "title": "tracking",
  "additionalProperties": false
}
