Smith.Inspection (Smith v0.4.0)

Copy Markdown View Source

Named geometry snapshots, explicit checks, and reports for scripts and agents.

run/2 evaluates named sources once and records their revisions, bounds, validity, area, volume, and topology counts. Checks return measured values and tolerances; failed requirements are :failed, while missing geometry, invalid checks, and kernel failures are :error. Neither is a passing check. A successful {:ok, report} means the report was produced: inspect its status.

Names describe snapshots you supply, not persistent face identities. Rebuild selections after edits. topology/3 exposes bounded pages of geometry metadata without native resource handles. No renderer or Livebook is required.

See inspection and validation for a complete script.

Summary

Functions

Computes added and removed solid material between two stages.

Serializes a report as JSON without native handles or renderer dependencies.

Inspects a nonempty map of named sources and evaluates ordered checks.

Returns a bounded page of face or edge metadata for a source snapshot.

Writes a report and headless PNG views into a new directory beneath root.

Types

check()

@type check() ::
  {:topology, name(), :solids | :faces | :edges | :vertices, keyword()}
  | {:bounds, name(), OCEx.bounds3(), keyword()}
  | {:contained | :clearance, name(), name(), keyword()}
  | {:measurement, name(), Smith.Measure.t(), keyword()}

name()

@type name() :: atom() | String.t()

t()

@opaque t()

Functions

compare(before_source, after_source)

@spec compare(Smith.Measure.source(), Smith.Measure.source()) ::
  {:ok, map()} | {:error, term()}

Computes added and removed solid material between two stages.

Returns added and removed as evaluated results, their volumes in mm³, and both source revisions. Empty differences are valid results with zero volume. Both stages must contain solids. Boolean comparison can be expensive for coincident spline surfaces; this performs actual geometry operations, not a bounding-box or mesh comparison.

json(report)

@spec json(t()) :: {:ok, String.t()} | {:error, term()}

Serializes a report as JSON without native handles or renderer dependencies.

Includes schema version 1, millimeter units, status, source revisions, model summaries, and check outcomes. Coordinates become arrays. The report revision identifies its named geometry set, not its checks or artifact options.

run(sources, opts \\ [])

@spec run(%{required(name()) => Smith.Measure.source()}, keyword()) ::
  {:ok, t()} | {:error, term()}

Inspects a nonempty map of named sources and evaluates ordered checks.

Options: checks: []. Supported checks (all tolerances are explicit):

  • {:bounds, name, {low, high}, tolerance: mm} — the model's native bounding box must stay inside that envelope, allowing the stated margin.
  • {:contained, candidate, container, tolerance: amount} — subtracts the container and measures excess volume (mm³), area (mm²), or length (mm), according to the candidate's highest dimension. The container must have solids. Empty candidates are an error, not vacuously contained.
  • {:clearance, a, b, minimum: mm, tolerance: mm} — minimum material distance, allowing the linear tolerance. Both inputs must contain solids. Positive interference volume also fails, using volume_tolerance: mm3 (default 1.0e-7). Zero distance alone cannot distinguish contact from overlap.
  • {:topology, name, :solids | :faces | :edges | :vertices, expected: count} — requires an exact topology count, useful for one solid or a connected section represented by one face. Counts are representation-dependent.

  • {:measurement, name, measurement, expected: number, tolerance: number} — compares a Smith.Measure to its target in the measurement's units. The measurement revision must match the named source.

Names normalize to strings; atom/string duplicates are rejected. Invalid options and source evaluation failures return {:error, reason}. Failures while executing a check are recorded with their reason in the report. Each check includes elapsed_ms to expose expensive validations. No defaults silently relax geometric requirements.

topology(source, kind, opts \\ [])

@spec topology(Smith.Measure.source(), :faces | :edges, keyword()) ::
  {:ok, map()} | {:error, term()}

Returns a bounded page of face or edge metadata for a source snapshot.

Options are selector: :all, offset: 0, and limit: 20 (1–100). Returns revision, total matches, items, and next_offset (nil at the end). Items follow native topology order; offsets are meaningful only within the same revision. Each includes a zero-based index and geometry metadata. Refine selectors to keep inspection output small. Callback exceptions propagate.

write(report, root, opts \\ [])

@spec write(t(), String.t(), keyword()) :: {:ok, map()} | {:error, term()}

Writes a report and headless PNG views into a new directory beneath root.

Options: views: [:isometric], width: 640, height: 480, and sections: [] (a list of Smith.Plane values). Each source receives each view. Sections are evaluated with Smith.section/2 and rendered separately. Excess material from failed containment checks receives a red diagnostic image. The JSON manifest links every artifact to its geometry revision.

Returns {:ok, %{directory: path, report: path, artifacts: list}}. A unique subdirectory prevents a later run from overwriting an earlier report. On failure, no report.json is written, though partial images may remain. Model names never become filesystem paths. PNGs are tessellated observations; report measurements come from the BREP.