Deferred planar outlines with optional cutouts and corner rounding.
Build an outline with rectangle/3, circle/2, polygon/2, or
profile/2. Coordinates are local to a Smith.Plane; standalone
sketches default to XY at Z=0. Distances are millimeters.
iex> outline =
...> Smith.Sketch.rectangle(40, 20) |> Smith.Sketch.cut(Smith.Sketch.circle(3))
iex> {:ok, face} = Smith.evaluate(outline)
iex> OCEx.shape_type(face.shape)
{:ok, :face}Use Smith.extrude/2, Smith.revolve/4, Smith.loft/2, or
Smith.sweep/3 to build solid model recipes. A bare sketch evaluates to one face and cannot be
exported as a printable bundle.
Sketches have no constraint solver. Their local coordinates, dimensions, and cuts come from ordinary Elixir calculations. Validation runs when evaluated, and cuts must retain one connected face. Rounding belongs to the original outline and is always applied before its cuts.
See sketches and planes for coordinate conventions and examples of side planes, holes, and solid generation.
Summary
Functions
Returns a directed circular-arc description for profile/2.
Describes a circle by radius in local millimeters.
Subtracts a sketch or ordered list of sketches from this region.
Sets a common corner radius on the original rectangle or convex polygon.
Returns a directed line description for profile/2.
Places a sketch on a new plane, preserving its local coordinates.
Describes a closed polygon from at least three local {u, v} points.
Describes a closed outline made from local lines, circular arcs, and interpolated splines.
Describes a rectangle with a width and height in local millimeters.
Describes a rectangle with four circular corner rounds of radius mm.
Describes a straight slot along local X with semicircular ends.
Returns a nonperiodic interpolated B-spline description for profile/2.
Types
Functions
Returns a directed circular-arc description for profile/2.
center is a local {u, v} point and radius is in millimeters.
start is measured from local +X in degrees. Positive sweep turns
counterclockwise from local +X toward +Y; negative sweep reverses the turn.
At evaluation, radius must exceed 1.0e-7 mm, and the absolute sweep must be greater than 1.0e-9 and at most 360 degrees. This returns an arc description tuple, not a sketch or native edge.
Describes a circle by radius in local millimeters.
Radius must exceed the native tolerance of 1.0e-7 mm at evaluation.
Supports the options of rectangle/3, defaulting to centered alignment.
:at therefore places the circle center unless another alignment is
chosen. align: :none retains a center at local zero before adding :at.
The sketch evaluates to a disk face. Use cut/2 to make a ring, or
Smith.extrude/2 to make a cylinder.
Subtracts a sketch or ordered list of sketches from this region.
A cutter without an explicit plane inherits the parent's frame, including
in nested cuts. Its :at is relative to that frame's origin, not the
parent's anchor or center. Explicit cutter planes must be coplanar; there
is no projection from another plane.
Cuts may overlap, contain holes, reach the outside edge, or miss the
parent. Repeated subtraction does not remove material twice. An empty
list returns the original sketch. After every cut the result must be one
face: removing it entirely fails with :empty_sketch, splitting it
fails with :disconnected_sketch, and mismatched planes fail with
:non_coplanar_sketches.
iex> ring = Smith.Sketch.circle(5) |> Smith.Sketch.cut(Smith.Sketch.circle(3))
iex> {:ok, part} = ring |> Smith.extrude(2) |> Smith.evaluate()
iex> {:ok, volume} = OCEx.volume(part.shape)
iex> abs(volume - 32 * :math.pi()) < 1.0e-6
true
Sets a common corner radius on the original rectangle or convex polygon.
Accepts only radius:, a positive distance in millimeters. Each corner
is replaced by a tangent circular arc; adjacent arcs must leave a positive
straight segment. Concave, collinear, degenerate, or overlarge fillets
fail with :invalid_fillet. Circles and authored arc profiles return
:unsupported_sketch_fillet.
Calling this again replaces the earlier radius. Rounding is applied
before all sketch cuts, regardless of pipeline order; it does not
round corners introduced by a cutter. For edges on an evaluated solid
recipe use Smith.fillet/2.
Returns a directed line description for profile/2.
from and to are local {u, v} points. Their separation must
exceed 1.0e-7 mm when evaluated. This returns {:line, from, to}, not
a sketch or a native edge.
@spec on(t(), Smith.Plane.t()) :: t()
Places a sketch on a new plane, preserving its local coordinates.
Overrides both its original :on option and any earlier call to
on/2. The original sketch is unchanged. Cutters without an explicit
plane inherit this new frame. Explicitly placed cutters retain their
world placement and must still be coplanar.
iex> outline = Smith.Sketch.rectangle(4, 6)
iex> model =
...> outline |> Smith.Sketch.on(Smith.Plane.yz(x: 10)) |> Smith.extrude(2)
iex> {:ok, part} = Smith.evaluate(model)
iex> {:ok, {x, y, z}} = OCEx.center_of_mass(part.shape)
iex> abs(x - 11) < 1.0e-6 and abs(y) < 1.0e-6 and abs(z) < 1.0e-6
true
Describes a closed polygon from at least three local {u, v} points.
Closure is implicit; do not repeat the first point. The outline must
enclose nonzero area and form a valid face. Concave polygons are allowed
without fillet/2.
Supports :on, :at, and :align as in rectangle/3. Alignment
defaults to :none: supplied coordinates are retained, then shifted by
:at. Explicit alignment uses the bounds of those coordinates.
Describes a closed outline made from local lines, circular arcs, and interpolated splines.
Supply a nonempty list of line/2, arc/4, and spline/2 descriptions in connected
boundary order. Options are :on and :at as in rectangle/3.
Coordinates are retained and shifted by :at; :align is not accepted.
Open, disconnected, and invalid boundaries fail during evaluation.
iex> sketch =
...> Smith.Sketch.profile([
...> Smith.Sketch.arc({0, 0}, 2, 0, 180),
...> Smith.Sketch.line({-2, 0}, {2, 0})
...> ])
iex> {:ok, face} = Smith.evaluate(sketch)
iex> {:ok, area} = OCEx.area(face.shape)
iex> abs(area - 2 * :math.pi()) < 1.0e-6
true
Describes a rectangle with a width and height in local millimeters.
Both dimensions must be positive; native size tolerances apply at
evaluation. The default bounds are centered on local {0, 0}.
Options
:on— aSmith.Plane. A standalone sketch defaults to XY at Z=0.:at— local anchor{u, v}, default{0, 0}.:align—{x_alignment, y_alignment}, each:min,:center, or:max. Defaults to{:center, :center}. The chosen point of the local bounds lands at:at.
align: :none uses the unaligned rectangle {0, 0}..{width, height},
then adds :at. Unknown/duplicate options return
:invalid_sketch_options at evaluation; unsupported alignments return
:invalid_alignment.
iex> sketch = Smith.Sketch.rectangle(4, 6, align: {:min, :max}, at: {10, 20})
iex> {:ok, face} = Smith.evaluate(sketch)
iex> OCEx.bounds(face.shape)
{:ok, {{10.0, 14.0, 0.0}, {14.0, 20.0, 0.0}}}
Describes a rectangle with four circular corner rounds of radius mm.
Supports the placement options of rectangle/3. Equivalent to a rectangle
followed by fillet/2; rounding precedes subsequent cutouts. Radius must
be positive and smaller than half either dimension, allowing for native
tolerance. Use slot/3 for semicircular ends meeting at the full width.
Describes a straight slot along local X with semicircular ends.
length is the overall end-to-end dimension; width is the diameter
of each end, both in mm. Length must be at least width, and width must
exceed 1.0e-7 mm. A nonzero straight span (length minus width) must also
exceed the native edge tolerance of 1.0e-7 mm. Equal dimensions produce
a circle. Smaller length or
invalid dimensions fail with :invalid_sketch at evaluation.
Supports :on, :at, and :align as in rectangle/3, defaulting
to centered alignment. align: :none also retains a centered outline.
Use cut/2 to subtract this sketch from another outline.
@spec spline( [{number(), number()}], {{number(), number()}, {number(), number()}} | nil ) :: tuple()
Returns a nonperiodic interpolated B-spline description for profile/2.
Supply at least two distinct local {u, v} points in traversal order.
The curve passes through these points, not through a control polygon.
Optional tangents is a pair of nonzero local direction vectors at the
first and last point. Directions are mapped through the sketch plane
without translation; OCCT chooses their derivative magnitudes.
The curve need not remain inside the points' bounds. Invalid points, tangents, and degenerate interpolation fail during sketch evaluation. Close the outline with other edges before extruding or sweeping it.