Smith.Drawing (Smith v0.1.0)

Copy Markdown View Source

Orthographic line drawings with visible and hidden edges.

A drawing is a snapshot of evaluated geometry in a chosen view plane. OCEx computes visibility from the BREP and retains native curves. SVG and DXF export sample those curves into polylines; changing export tolerances does not recalculate visibility or change the drawing.

iex> {:ok, drawing} = Smith.Drawing.new(Smith.box(20, 10, 4), on: :xy)
iex> {:ok, svg} = Smith.Drawing.svg(drawing, hidden: false)
iex> String.starts_with?(svg, "<svg")
true

Use Smith.Kino.render/2 for a rotatable 3D preview. In Livebook, display a drawing with Kino.Image.new(svg, :svg). See the drawing guide for view orientation and file export.

Summary

Functions

Serializes a drawing to ASCII DXF (AutoCAD 2000 / AC1015).

Evaluates a source and computes its orthographic drawing.

Samples drawing curves into view-local XY polylines.

Serializes a drawing to a standalone SVG binary.

Writes an SVG or DXF file, inferring the format from its extension.

Types

source()

t()

@opaque t()

Functions

dxf(drawing, opts \\ [])

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

Serializes a drawing to ASCII DXF (AutoCAD 2000 / AC1015).

Options are those in polylines/2. Coordinates retain local X/Y orientation with Z=0. $INSUNITS is 4 (millimeters). Each sampled edge becomes an LWPOLYLINE on the VISIBLE or HIDDEN layer. Closed edges use the closed flag and omit the duplicate endpoint. Curves are polylines, not DXF ARC, CIRCLE, or SPLINE entities.

VISIBLE uses continuous lines. HIDDEN uses a 2 mm dash / 1 mm gap linetype. Readers may apply their own display scaling to that pattern. Empty drawings produce a valid file without entities. This writer does not add dimensions, text, blocks, paper layouts, or toolpaths.

Returns {:ok, binary}; options and native errors follow polylines/2.

new(source, opts \\ [])

@spec new(source(), keyword()) :: {:ok, t()} | {:error, term()}

Evaluates a source and computes its orthographic drawing.

Returns {:ok, drawing}. An existing result skips recipe evaluation; its BREP revision is checked before use. The drawing's source_revision identifies that source, while visible and hidden hold new native edge collections. Treat these fields as read-only.

Options:

  • :on:xy (default), :xz, :yz, or a Smith.Plane.
  • :tangents — include smooth G1 boundaries between faces; default false.

The viewer looks along the plane's negative normal. Plane-local X points right and local Y points up. Coordinates are millimeters relative to its origin; moving the origin only along the normal has no effect. Surface seams and isoparametric lines are excluded. Coincident projected edges may remain; the drawing is not a joined cutting contour.

Assemblies show installed manufactured parts, excluding references and printable extras. To draw an exploded or display pose, pass the result of Smith.Assembly.view/2. Fetch a reference explicitly to draw it.

Unknown/duplicate options return :invalid_options, invalid frames return :invalid_plane, and stale input results return :revision_mismatch. Recipe and native geometry errors propagate.

polylines(drawing, opts \\ [])

@spec polylines(t(), keyword()) ::
  {:ok, %{visible: [[{float(), float()}]], hidden: [[{float(), float()}]]}}
  | {:error, term()}

Samples drawing curves into view-local XY polylines.

Returns {:ok, %{visible: polylines, hidden: polylines}}. Each polyline is a list of {x, y} points for one native edge, including both endpoints. Closed curves repeat the starting point. Separate edges are not stitched or deduplicated.

Options shared by SVG and DXF export:

  • :tolerance — linear deflection in mm, default 0.03.
  • :angular_tolerance — angular deflection in radians, default 0.1.
  • :hidden — include hidden edges, default true.

Both deflections must exceed 1.0e-7. Sampling uses OCEx.polylines/3; tolerances control that algorithm and are not a certified global error bound for arbitrary splines. Empty layers return empty lists. Invalid options return :invalid_options; native failures propagate. Passing something other than a drawing returns :invalid_argument.

svg(drawing, opts \\ [])

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

Serializes a drawing to a standalone SVG binary.

Supports the sampling options in polylines/2, plus:

  • :padding — nonnegative margin in mm, default 5.
  • :stroke_width — positive line width in mm, default 0.25.
  • :title — XML text for the accessible title, default "Smith drawing".

SVG has explicit millimeter width/height and a viewBox matching drawing units. Its extent includes padding and half the stroke width at each boundary. Coordinates are reflected vertically for SVG's downward Y axis; the underlying drawing coordinates remain unchanged. Visible edges are solid black; hidden edges are gray with a 2 mm dash and 1 mm gap, painted first. There are no fills, scripts, external assets, or dimensions.

Returns {:ok, binary}, or {:error, :empty_drawing} when the selected layers contain no points. Options and native errors follow polylines/2. Title text is escaped; invalid XML characters fail.

write(drawing, path, opts \\ [])

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

Writes an SVG or DXF file, inferring the format from its extension.

Returns {:ok, path}. Options belong to the selected serializer. The parent directory must exist; an existing file is overwritten only after serialization succeeds. File-system failures return their reason. Other extensions return :unsupported_format. This writes a single drawing file without a model bundle, print validation, or manifest.