Skip to main content
Glama

geometry_inspect

Idempotent

Reads and cooks a Houdini node's geometry to verify its output, including point counts, attributes, bounds, volumes, groups, and comparisons against another node.

Instructions

Read the geometry that a node produces. This cooks the node.

Modes: summary, points, prims, attrib, groups, group_members, bbox, intrinsics, nearest, skeleton, compare, try, volume_stats, volume_voxels, volume_sample, volume_compare, image, volume, export, fingerprint, stretch, inside, crossings, distance, changes.

Use it to confirm that a node made what you expected: the point count, an
attribute that a wrangle wrote, the shape of a volume, the size of the
bounding box.

Do not use it to read parameters: node_inspect does that.

mode:
    "summary"        — counts, attributes, groups, volumes, bounds. Start
                       here. An empty result carries the errors and the
                       warnings of the node, which is where the reason is.
    "points"         — `count` points from `start`, with `attribs`.
    "prims"          — `count` primitives from `start`.
    "attrib"         — the values of `attrib_name` on `attrib_class`
                       ("point", "prim", "vertex", "detail"): min, max
                       and mean of each component over every element,
                       and `limit` (10) values from `start`. A vector
                       attribute keeps its shape. unique=True returns each
                       value that occurs and how many elements carry it,
                       which is how you find the pieces in a geometry.
    "groups"         — the groups of `group_type`.
    "group_members"  — the members of `group_name`.
    "bbox"           — the bounding box.
    "intrinsics"     — the intrinsic values of primitive `prim_index`.
    "nearest"        — the point nearest to `position`, for example [0,1,0].
    "skeleton"       — a KineFX skeleton: each joint with its name, its
                       parent and its transform. `pattern` keeps the names
                       that match ("|" between alternatives, * as a
                       wildcard). A KineFX import holds the skeletons on
                       output 1 and 2: give `output`.
    "compare"        — the difference from the node at `against`. Points are
                       matched by `match_attrib` ("name" by default), not by
                       their order. Use it to prove that a new node gives
                       the result of the node it replaces.
    "try"            — run `steps`, a list of
                       {"node_type": ..., "parameters": {...}}, on the
                       geometry of `path` as verbs. Nothing changes in the
                       scene. Use it to learn what a node would make. A
                       menu takes its token ("poly") or its index. A type
                       with no verb, such as an asset, runs as a temporary
                       node in a hidden network that is then deleted.
                       `attrib_name` reads that attribute on the result,
                       as mode "attrib" does, `unique` included.
    "volume_stats"   — every volume or VDB: resolution, voxel size, the
                       extremes, the mean, the sum, percentiles. `name`
                       reads one, `bins` adds a histogram, `threshold`
                       counts the voxels below and above it and gives the
                       world box of the voxels above it.
    "volume_voxels"  — one field as an array indexed [z][y][x], with its
                       shape and its transform. `name` is the field.
                       `reduce` gives one answer instead: "sum", "mean",
                       "max", "min", or "project_x", "project_y",
                       "project_z" (the sum along that axis, a 2D array).
                       An array past `limit` numbers is thinned.
    "volume_sample"  — read `names` (fields) at `positions`, or at the
                       points of `from_node`, with no node added to the
                       scene. Returns min, max, mean, percentiles, a
                       histogram of `bins` (10), the counts on each side of
                       `threshold`, and the values when there are at most
                       `limit` (1000).
    "volume_compare" — how much of the field `name` sits in each band of the
                       field `against`. The answer to "how much smoke is
                       inside the collider". `from_node` holds `against`
                       when another node does, such as the collider SDF.
    "image"          — a COP node: resolution, planes, and `plane_name`.
    "volume"         — the VDB grids in a COP node.
    "export"         — write the geometry to disk. `format` is "obj",
                       "bgeo" or another that Houdini writes, and `file`
                       is the file path. A file that is there is
                       overwritten. The other modes write nothing.
    "fingerprint"    — for each node of `path` and each frame: counts,
                       bounds, a hash of P and of the attribute names.
                       `name` saves it. After a refactor, call it again
                       with `against` (the saved name) and `renamed`, and
                       read `compare`: what differs, or same=true.
    "stretch"        — how much each edge grew against the same edge of
                       the rest mesh `against`: max, percentiles, the
                       count over `threshold`, the worst edges and the
                       places where they are, on the rest mesh.
    "inside"         — the points of `path` inside the closed mesh
                       `against`: the count, the depth, where they are.
                       Run it before a cloth sim.
    "crossings"      — the points where the surfaces of `path` cross,
                       themselves or `against`, counted for each pair of
                       parts of `split_by`. A part with itself is a self
                       crossing.
    "distance"       — the distance from each point to the surface of
                       `against`: min, max, mean, a histogram of `bins`,
                       and the point numbers farther than `threshold`.
                       With `frames`, one answer for each frame.
    "changes"        — cook over `frames` (two or more, step 1 to see
                       pops) and return a table: counts, box size and
                       center, and the mean, min and max of `attribs`
                       for each frame. `jumps` lists the frames where a
                       number changes by more than `threshold` (0.2)
                       from the frame before: pops, flicker and hard
                       stops that one frame does not show.

Returns JSON. A large read is slow: keep `count` small and page with
`start`.

Input Schema

NameRequiredDescriptionDefault
binsNovolume_stats, volume_sample, volume_compare: a count of equal bands, or a list of band edges, for example [-1, 0, 0.05, 0.15, 0.25].
fileNoexport: the file path to write.
modeNoOne of "summary", "points", "prims", "attrib", "groups", "group_members", "bbox", "intrinsics", "nearest", "skeleton", "compare", "try", "volume_stats", "volume_voxels", "volume_sample", "volume_compare", "image", "volume", "export", "fingerprint", "stretch", "inside", "crossings", "distance", "changes".summary
nameNovolume_stats: one volume to read. volume_voxels, volume_compare: the field. fingerprint: save the result under this name.
pathYesThe SOP or COP node to read, or a list. A list keeps going after a node that fails, and each result names its path.
countNopoints, prims: how many elements. Keep it small: a large read is slow.
limitNoattrib: how many values (10). volume_voxels: how many numbers before the array is thinned. volume_sample: return the values when there are at most this many (1000). stretch: how many of the worst edges (10).
namesNovolume_sample: the fields to read.
startNopoints, prims, attrib: the first element. Page with it.
stepsNotry: a list of {"node_type": ..., "parameters": {...}} to run on the geometry. A menu takes its token or its index. Nothing changes in the scene.
formatNoexport: the file type, for example "obj" or "bgeo".obj
framesNoRead at other frames, without moving the playbar: one frame, a list, or {"start": 1001, "end": 1010, "step": 2}. One answer for each frame.
outputNoThe output of the node to read, 0 by default. A KineFX import has the mesh on 0, the rest skeleton on 1, the animated skeleton on 2.
reduceNovolume_voxels: one answer instead of the array: "sum", "mean", "max", "min", "project_x", "project_y" or "project_z".
uniqueNoattrib: return each value that occurs and how many elements carry it. That is how you find the pieces in a geometry.
againstNocompare: the node to compare with. distance: the node to measure to. volume_compare: the field whose bands hold the field `name`. fingerprint: the name of a saved fingerprint to compare with. stretch: the rest mesh. inside: the closed mesh. crossings: a second geometry, such as the body.
attribsNopoints: the attributes to return, for example ["P", "Cd"]. changes: the attributes whose mean, min and max to follow.
patternNoskeleton: keep the joints whose name matches.
renamedNofingerprint: {"old path": "new path"} for the nodes that a refactor renamed or moved.
positionNonearest: [x, y, z].
split_byNocrossings: a prim attribute, such as "name", whose values are the parts that the count pairs.
from_nodeNovolume_sample: read at the points of this node. volume_compare: the node that holds `against`, such as a collider SDF.
positionsNovolume_sample: the [x, y, z] points to read at.
thresholdNovolume_stats, volume_sample: count the voxels below and above it. volume_stats also gives the world box of the voxels above it. stretch: the growth to count, 0.1 (10 %) by default. inside: count the points deeper than this distance. distance: list the points farther than it. changes: the ratio of change from one frame to the next that counts as a jump (0.2).
group_nameNogroup_members: the group to read.
group_typeNogroups, group_members: "point", "prim", "vertex" or "edge".point
plane_nameNoimage: the COP plane to read, for example "C".C
prim_indexNointrinsics: the primitive to read.
attrib_nameNoattrib, try: the attribute to read. try reads it on the result.
attrib_classNoattrib, try: "point", "prim", "vertex" or "detail".point
match_attribNocompare: the attribute that pairs the points of the two nodes, not their order.name

Output Schema

NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changedv0.8.1
    • changedInput schema / properties / against / description
      Previous value: -"compare: the node to compare with. volume_compare: the field whose bands hold the field `name`. fingerprint: the name of a saved fingerprint to compare with. stretch: the rest mesh. inside: the closed mesh. crossings: a second geometry, such as the body."New value: +"compare: the node to compare with. distance: the node to measure to. volume_compare: the field whose bands hold the field `name`. fingerprint: the name of a saved fingerprint to compare with. stretch: the rest mesh. inside: the closed mesh. crossings: a second geometry, such as the body."
    • changedInput schema / properties / attribs / description
      Previous value: -"points: the attributes to return, for example [\"P\", \"Cd\"]."New value: +"points: the attributes to return, for example [\"P\", \"Cd\"]. changes: the attributes whose mean, min and max to follow."
    • changedInput schema / properties / mode / description
      Previous value: -"One of \"summary\", \"points\", \"prims\", \"attrib\", \"groups\", \"group_members\", \"bbox\", \"intrinsics\", \"nearest\", \"skeleton\", \"compare\", \"try\", \"volume_stats\", \"volume_voxels\", \"volume_sample\", \"volume_compare\", \"image\", \"volume\", \"export\", \"fingerprint\", \"stretch\", \"inside\", \"crossings\"."New value: +"One of \"summary\", \"points\", \"prims\", \"attrib\", \"groups\", \"group_members\", \"bbox\", \"intrinsics\", \"nearest\", \"skeleton\", \"compare\", \"try\", \"volume_stats\", \"volume_voxels\", \"volume_sample\", \"volume_compare\", \"image\", \"volume\", \"export\", \"fingerprint\", \"stretch\", \"inside\", \"crossings\", \"distance\", \"changes\"."
    • changedInput schema / properties / threshold / description
      Previous value: -"volume_stats, volume_sample: count the voxels below and above it. volume_stats also gives the world box of the voxels above it. stretch: the growth to count, 0.1 (10 %) by default. inside: count the points deeper than this distance."New value: +"volume_stats, volume_sample: count the voxels below and above it. volume_stats also gives the world box of the voxels above it. stretch: the growth to count, 0.1 (10 %) by default. inside: count the points deeper than this distance. distance: list the points farther than it. changes: the ratio of change from one frame to the next that counts as a jump (0.2)."
  2. Changed14 schema fields changedv0.8.0
    • changedInput schema / properties / against / description
      Previous value: -"compare: the node to compare with. volume_compare: the field whose bands hold the field `name`."New value: +"compare: the node to compare with. volume_compare: the field whose bands hold the field `name`. fingerprint: the name of a saved fingerprint to compare with. stretch: the rest mesh. inside: the closed mesh. crossings: a second geometry, such as the body."
    • changedInput schema / properties / attrib_class / description
      Previous value: -"attrib: \"point\", \"prim\", \"vertex\" or \"detail\"."New value: +"attrib, try: \"point\", \"prim\", \"vertex\" or \"detail\"."
    • changedInput schema / properties / attrib_name / description
      Previous value: -"attrib: the attribute to read."New value: +"attrib, try: the attribute to read. try reads it on the result."
    • addedInput schema / properties / file
      Added value: +{
      +  "description": "export: the file path to write.",
      +  "type": "string"
      +}
    • changedInput schema / properties / limit / description
      Previous value: -"attrib: how many values (10). volume_voxels: how many numbers before the array is thinned. volume_sample: return the values when there are at most this many (1000)."New value: +"attrib: how many values (10). volume_voxels: how many numbers before the array is thinned. volume_sample: return the values when there are at most this many (1000). stretch: how many of the worst edges (10)."
    • changedInput schema / properties / mode / description
      Previous value: -"One of \"summary\", \"points\", \"prims\", \"attrib\", \"groups\", \"group_members\", \"bbox\", \"intrinsics\", \"nearest\", \"skeleton\", \"compare\", \"try\", \"volume_stats\", \"volume_voxels\", \"volume_sample\", \"volume_compare\", \"image\", \"volume\", \"export\"."New value: +"One of \"summary\", \"points\", \"prims\", \"attrib\", \"groups\", \"group_members\", \"bbox\", \"intrinsics\", \"nearest\", \"skeleton\", \"compare\", \"try\", \"volume_stats\", \"volume_voxels\", \"volume_sample\", \"volume_compare\", \"image\", \"volume\", \"export\", \"fingerprint\", \"stretch\", \"inside\", \"crossings\"."
    • changedInput schema / properties / name / description
      Previous value: -"volume_stats: one volume to read. volume_voxels, volume_compare: the field."New value: +"volume_stats: one volume to read. volume_voxels, volume_compare: the field. fingerprint: save the result under this name."
    • addedInput schema / properties / output / anyOf
      Added value: +[
      +  {
      +    "type": "integer"
      +  },
      +  {
      +    "type": "string"
      +  }
      +]
    • changedInput schema / properties / output / description
      Previous value: -"export: the file path to write."New value: +"The output of the node to read, 0 by default. A KineFX import has the mesh on 0, the rest skeleton on 1, the animated skeleton on 2."
    • removedInput schema / properties / output / type
      Removed value: -"string"
    • addedInput schema / properties / renamed
      Added value: +{
      +  "additionalProperties": {
      +    "type": "string"
      +  },
      +  "description": "fingerprint: {\"old path\": \"new path\"} for the nodes that a refactor renamed or moved.",
      +  "type": "object"
      +}
    • addedInput schema / properties / split_by
      Added value: +{
      +  "description": "crossings: a prim attribute, such as \"name\", whose values are the parts that the count pairs.",
      +  "type": "string"
      +}
    • changedInput schema / properties / steps / description
      Previous value: -"try: a list of {\"node_type\": ..., \"parameters\": {...}} to run on the geometry as verbs. Nothing changes in the scene."New value: +"try: a list of {\"node_type\": ..., \"parameters\": {...}} to run on the geometry. A menu takes its token or its index. Nothing changes in the scene."
    • changedInput schema / properties / threshold / description
      Previous value: -"volume_stats, volume_sample: count the voxels below and above it. volume_stats also gives the world box of the voxels above it."New value: +"volume_stats, volume_sample: count the voxels below and above it. volume_stats also gives the world box of the voxels above it. stretch: the growth to count, 0.1 (10 %) by default. inside: count the points deeper than this distance."
  3. Changed131 schema fields changedv0.7.3
    • removedInput schema / properties / against / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / against / default
      Removed value: -null
    • addedInput schema / properties / against / description
      Added value: +"compare: the node to compare with. volume_compare: the field whose bands hold the field `name`."
    • removedInput schema / properties / against / title
      Removed value: -"Against"
    • addedInput schema / properties / against / type
      Added value: +"string"
    • removedInput schema / properties / attrib_class / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / attrib_class / description
      Added value: +"attrib: \"point\", \"prim\", \"vertex\" or \"detail\"."
    • removedInput schema / properties / attrib_class / title
      Removed value: -"Attrib Class"
    • addedInput schema / properties / attrib_class / type
      Added value: +"string"
    • removedInput schema / properties / attrib_name / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / attrib_name / default
      Removed value: -null
    • addedInput schema / properties / attrib_name / description
      Added value: +"attrib: the attribute to read."
    • removedInput schema / properties / attrib_name / title
      Removed value: -"Attrib Name"
    • addedInput schema / properties / attrib_name / type
      Added value: +"string"
    • removedInput schema / properties / attribs / anyOf
      Removed value: -[
      -  {
      -    "items": {
      -      "type": "string"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / attribs / default
      Removed value: -null
    • addedInput schema / properties / attribs / description
      Added value: +"points: the attributes to return, for example [\"P\", \"Cd\"]."
    • addedInput schema / properties / attribs / items
      Added value: +{
      +  "type": "string"
      +}
    • removedInput schema / properties / attribs / title
      Removed value: -"Attribs"
    • addedInput schema / properties / attribs / type
      Added value: +"array"
    • changedInput schema / properties / bins / anyOf
      Previous value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "items": {
      -      "type": "number"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "type": "integer"
      +  },
      +  {
      +    "items": {
      +      "type": "number"
      +    },
      +    "type": "array"
      +  }
      +]
    • removedInput schema / properties / bins / default
      Removed value: -null
    • addedInput schema / properties / bins / description
      Added value: +"volume_stats, volume_sample, volume_compare: a count of equal bands, or a list of band edges, for example [-1, 0, 0.05, 0.15, 0.25]."
    • removedInput schema / properties / bins / title
      Removed value: -"Bins"
    • removedInput schema / properties / count / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / count / description
      Added value: +"points, prims: how many elements. Keep it small: a large read is slow."
    • removedInput schema / properties / count / title
      Removed value: -"Count"
    • addedInput schema / properties / count / type
      Added value: +"integer"
    • removedInput schema / properties / format / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / format / description
      Added value: +"export: the file type, for example \"obj\" or \"bgeo\"."
    • removedInput schema / properties / format / title
      Removed value: -"Format"
    • addedInput schema / properties / format / type
      Added value: +"string"
    • changedInput schema / properties / frames / anyOf
      Previous value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "items": {
      -      "type": "number"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "additionalProperties": {
      -      "type": "number"
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "type": "number"
      +  },
      +  {
      +    "items": {
      +      "type": "number"
      +    },
      +    "type": "array"
      +  },
      +  {
      +    "additionalProperties": {
      +      "type": "number"
      +    },
      +    "type": "object"
      +  }
      +]
    • removedInput schema / properties / frames / default
      Removed value: -null
    • addedInput schema / properties / frames / description
      Added value: +"Read at other frames, without moving the playbar: one frame, a list, or {\"start\": 1001, \"end\": 1010, \"step\": 2}. One answer for each frame."
    • removedInput schema / properties / frames / title
      Removed value: -"Frames"
    • removedInput schema / properties / from_node / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / from_node / default
      Removed value: -null
    • addedInput schema / properties / from_node / description
      Added value: +"volume_sample: read at the points of this node. volume_compare: the node that holds `against`, such as a collider SDF."
    • removedInput schema / properties / from_node / title
      Removed value: -"From Node"
    • addedInput schema / properties / from_node / type
      Added value: +"string"
    • removedInput schema / properties / group_name / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / group_name / default
      Removed value: -null
    • addedInput schema / properties / group_name / description
      Added value: +"group_members: the group to read."
    • removedInput schema / properties / group_name / title
      Removed value: -"Group Name"
    • addedInput schema / properties / group_name / type
      Added value: +"string"
    • removedInput schema / properties / group_type / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / group_type / description
      Added value: +"groups, group_members: \"point\", \"prim\", \"vertex\" or \"edge\"."
    • removedInput schema / properties / group_type / title
      Removed value: -"Group Type"
    • addedInput schema / properties / group_type / type
      Added value: +"string"
    • removedInput schema / properties / limit / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / limit / default
      Removed value: -null
    • addedInput schema / properties / limit / description
      Added value: +"attrib: how many values (10). volume_voxels: how many numbers before the array is thinned. volume_sample: return the values when there are at most this many (1000)."
    • removedInput schema / properties / limit / title
      Removed value: -"Limit"
    • addedInput schema / properties / limit / type
      Added value: +"integer"
    • removedInput schema / properties / match_attrib / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / match_attrib / description
      Added value: +"compare: the attribute that pairs the points of the two nodes, not their order."
    • removedInput schema / properties / match_attrib / title
      Removed value: -"Match Attrib"
    • addedInput schema / properties / match_attrib / type
      Added value: +"string"
    • removedInput schema / properties / mode / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / mode / description
      Added value: +"One of \"summary\", \"points\", \"prims\", \"attrib\", \"groups\", \"group_members\", \"bbox\", \"intrinsics\", \"nearest\", \"skeleton\", \"compare\", \"try\", \"volume_stats\", \"volume_voxels\", \"volume_sample\", \"volume_compare\", \"image\", \"volume\", \"export\"."
    • removedInput schema / properties / mode / title
      Removed value: -"Mode"
    • addedInput schema / properties / mode / type
      Added value: +"string"
    • removedInput schema / properties / name / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / name / default
      Removed value: -null
    • addedInput schema / properties / name / description
      Added value: +"volume_stats: one volume to read. volume_voxels, volume_compare: the field."
    • removedInput schema / properties / name / title
      Removed value: -"Name"
    • addedInput schema / properties / name / type
      Added value: +"string"
    • removedInput schema / properties / names / anyOf
      Removed value: -[
      -  {
      -    "items": {
      -      "type": "string"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / names / default
      Removed value: -null
    • addedInput schema / properties / names / description
      Added value: +"volume_sample: the fields to read."
    • addedInput schema / properties / names / items
      Added value: +{
      +  "type": "string"
      +}
    • removedInput schema / properties / names / title
      Removed value: -"Names"
    • addedInput schema / properties / names / type
      Added value: +"array"
    • removedInput schema / properties / output / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / output / default
      Removed value: -null
    • addedInput schema / properties / output / description
      Added value: +"export: the file path to write."
    • removedInput schema / properties / output / title
      Removed value: -"Output"
    • addedInput schema / properties / output / type
      Added value: +"string"
    • addedInput schema / properties / path / description
      Added value: +"The SOP or COP node to read, or a list. A list keeps going after a node that fails, and each result names its path."
    • removedInput schema / properties / path / title
      Removed value: -"Path"
    • removedInput schema / properties / pattern / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / pattern / default
      Removed value: -null
    • addedInput schema / properties / pattern / description
      Added value: +"skeleton: keep the joints whose name matches."
    • removedInput schema / properties / pattern / title
      Removed value: -"Pattern"
    • addedInput schema / properties / pattern / type
      Added value: +"string"
    • removedInput schema / properties / plane_name / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / plane_name / description
      Added value: +"image: the COP plane to read, for example \"C\"."
    • removedInput schema / properties / plane_name / title
      Removed value: -"Plane Name"
    • addedInput schema / properties / plane_name / type
      Added value: +"string"
    • removedInput schema / properties / position / anyOf
      Removed value: -[
      -  {
      -    "items": {
      -      "type": "number"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / position / default
      Removed value: -null
    • addedInput schema / properties / position / description
      Added value: +"nearest: [x, y, z]."
    • addedInput schema / properties / position / items
      Added value: +{
      +  "type": "number"
      +}
    • removedInput schema / properties / position / title
      Removed value: -"Position"
    • addedInput schema / properties / position / type
      Added value: +"array"
    • removedInput schema / properties / positions / anyOf
      Removed value: -[
      -  {
      -    "items": {
      -      "items": {
      -        "type": "number"
      -      },
      -      "type": "array"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / positions / default
      Removed value: -null
    • addedInput schema / properties / positions / description
      Added value: +"volume_sample: the [x, y, z] points to read at."
    • addedInput schema / properties / positions / items
      Added value: +{
      +  "items": {
      +    "type": "number"
      +  },
      +  "type": "array"
      +}
    • removedInput schema / properties / positions / title
      Removed value: -"Positions"
    • addedInput schema / properties / positions / type
      Added value: +"array"
    • removedInput schema / properties / prim_index / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / prim_index / description
      Added value: +"intrinsics: the primitive to read."
    • removedInput schema / properties / prim_index / title
      Removed value: -"Prim Index"
    • addedInput schema / properties / prim_index / type
      Added value: +"integer"
    • removedInput schema / properties / reduce / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / reduce / default
      Removed value: -null
    • addedInput schema / properties / reduce / description
      Added value: +"volume_voxels: one answer instead of the array: \"sum\", \"mean\", \"max\", \"min\", \"project_x\", \"project_y\" or \"project_z\"."
    • removedInput schema / properties / reduce / title
      Removed value: -"Reduce"
    • addedInput schema / properties / reduce / type
      Added value: +"string"
    • removedInput schema / properties / start / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / start / description
      Added value: +"points, prims, attrib: the first element. Page with it."
    • removedInput schema / properties / start / title
      Removed value: -"Start"
    • addedInput schema / properties / start / type
      Added value: +"integer"
    • removedInput schema / properties / steps / anyOf
      Removed value: -[
      -  {
      -    "items": {
      -      "additionalProperties": true,
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / steps / default
      Removed value: -null
    • addedInput schema / properties / steps / description
      Added value: +"try: a list of {\"node_type\": ..., \"parameters\": {...}} to run on the geometry as verbs. Nothing changes in the scene."
    • addedInput schema / properties / steps / items
      Added value: +{
      +  "additionalProperties": true,
      +  "type": "object"
      +}
    • removedInput schema / properties / steps / title
      Removed value: -"Steps"
    • addedInput schema / properties / steps / type
      Added value: +"array"
    • removedInput schema / properties / threshold / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedInput schema / properties / threshold / default
      Removed value: -null
    • addedInput schema / properties / threshold / description
      Added value: +"volume_stats, volume_sample: count the voxels below and above it. volume_stats also gives the world box of the voxels above it."
    • removedInput schema / properties / threshold / title
      Removed value: -"Threshold"
    • addedInput schema / properties / threshold / type
      Added value: +"number"
    • removedInput schema / properties / unique / anyOf
      Removed value: -[
      -  {
      -    "type": "boolean"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / unique / description
      Added value: +"attrib: return each value that occurs and how many elements carry it. That is how you find the pieces in a geometry."
    • removedInput schema / properties / unique / title
      Removed value: -"Unique"
    • addedInput schema / properties / unique / type
      Added value: +"boolean"
    • removedInput schema / title
      Removed value: -"toolArguments"
  4. Addedv0.1.1

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well past the annotations by disclosing that the tool cooks the node, that "try" runs verbs or temporary hidden nodes with no scene change, and that only "export" writes and silently overwrites an existing file while all other modes write nothing. Read-only-looking usage is thus clearly scoped. Minor deduction: the overwrite behavior sits in tension with destructiveHint=false and is buried in one mode's paragraph rather than flagged near the top.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Long but front-loaded: purpose and the sibling exclusion come first, then a mode catalogue with per-mode paragraphs. The full 25-mode list is repeated verbatim from the schema's mode enum, which is redundant weight, but the structure is otherwise disciplined and each mode paragraph earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 25-mode, 31-parameter tool, the description covers every mode's intent, key parameter, notable defaults, and the paging/performance caveat ("keep count small and page with start"). An output schema exists, so return shapes need not be explained, and the remaining complexity is handled.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds genuine cross-parameter guidance: which parameters each mode consumes (bins for the volume modes, limit for attrib/voxels/stretch, threshold with different defaults per mode), the "token or index" rule for menu values in steps, and wildcard syntax for pattern. Most of this duplicates the schema text, which keeps it below 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Read the geometry that a node produces. This cooks the node." names a specific verb and resource, and immediately states the side effect. It explicitly contrasts itself with node_inspect (parameters vs geometry), so an agent can route without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States when to use it ("confirm that a node made what you expected: the point count, an attribute a wrangle wrote, the shape of a volume") and when not to ("Do not use it to read parameters: node_inspect does that"). It also names a default entry point, "summary" — "Start here."

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.