 {0 OSCADml}

In conjunction with {{:https://github.com/OCADml/OCADml} [OCADml]}, this library
provides an OCaml front-end to the {{:https://openscad.org/} OpenSCAD} solid
modelling language. All SCAD primitives and transformation functions are made
available.

{1 Notable differences from the OpenSCAD language}

- Angles are represented in radians (and converted to degrees when compiling to
  OpenSCAD).
- [linear_extrude] and [rotate_extrude] have been renamed to
  {{!OSCADml.Scad.extrude} [extrude]} and {{!OSCADml.Scad.revolve} [revolve]}
- The dimensional system (2D or 3D) each shape inhabits is tracked by the type
  system. This is used to restrict the operations that can be legally applied
  (e.g. 2D shapes cannot be moved off of the xy plane,
  {{!OSCADml.Scad.extrude} [Scad.extrude]} can only be applied to 2D shapes)
  and enforcing non-mixing of 2D and 3D shapes during boolean operations.

{1 Usage}

{[
  open OCADml
  open OSCADml

  let () =
    let scad_logo =
      let rad = 5.
      and fn = 720 in
      let cyl = Scad.cylinder ~fn ~center:true ~height:(rad *. 2.3) (rad /. 2.) in
      let cross_cyl = Scad.rotate (v3 0. (Float.pi /. 2.) 0.) cyl in
      Scad.union
        [ Scad.difference
            (Scad.sphere ~fn rad)
            [ cyl; cross_cyl; Scad.rotate (v3 0. 0. (Float.pi /. 2.)) cross_cyl ]
        ; Scad.color ~alpha:0.25 Color.Magenta cross_cyl
        ]
    in
    Scad.to_file "scad_logo.scad" scad_logo
]}

{%html: <img src="_assets/scad_logo.png" style="width:125mm;" /> %}

Generated [.scad] scripts can then be viewed with the
{{:https://openscad.org/downloads.html} OpenSCAD viewer} as you normally would, or
directly exporting {{!OSCADml.Scad.t} [Scad.t]} into other model formats or PNGs with
{{!OSCADml.Scad.export} [Scad.export]} and {{!OSCADml.Scad.snapshot} [Scad.snapshot]}
respectively.

{1:api API}

{!module-OSCADml} -- top level library interface

{2 Core DSL}
- {{!OSCADml.Scad} [Scad]} -- well-typed dimension aware OpenSCAD models
- {{!OSCADml.Text} [Text]} -- {{!OSCADml.Scad.text} [Scad.text]} configuration types
- {{!OSCADml.Color} [Color]} -- {{!OSCADml.Scad.color} [Scad.color]} configuration type

{2 Utilities}
- {{!OSCADml.Export} [Export]} -- exporting [.scad] scripts via OpenSCAD CLI
- {{!OSCADml.Debug} [Debug]} -- helpers for simple viewing of OCADml types

{1:ocadml OCADml documentation}
The {{:https://github.com/OCADml/OCADml} [OCADml]} library features prominently in the
following examples, infact they can largely be considered part of [OCADml]'s
extended documentation. Thus in working through them, as well as using
[OSCADml], the {{:https://OCADml.github.io/OCADml/OCADml/index.html} OCADml manual}
should serve as a helpful reference.

{1:examples Examples}

{2 Paths and Sweeps}
- {{!page-"offset_and_rounding"} {b Offset and roundovers}}
- {{!page-"default_vs_euler_sweeps"} {b Default vs euler path transformation reference}}
- {{!page-"bespoke_sweeps"} {b Bespoke sweep transforms (with direct affine transform generation)}}
- {{!page-"spline"} {b Cubic spline}}
- {{!page-"arc_points"} {b Arcing paths}}
- {{!page-"helices"} {b Helical paths and extrusions}}
- {{!page-"resampled_path"} {b Path resampling and scaling/twisting sweeps}}

{2 Rounded Extrusions}
- {{!page-"rounded_polyhole_sweep"} {b Rounded sweeps}}
- {{!page-"rounded_prisms"} {b Continuous curvature rounded prisms}}
- {{!page-"rounded_text"} {b Rounded extrusion of cairo imported polygonal font}}

{2 Skins and Morphs}
- {{!page-"profile_skinning"} {b Profile skinning}}
- {{!page-"spline_skinning"} {b Continuous skinning with BÃ©zier splines}}
- {{!page-"morphing_sweeps"} {b Morphing sweeps and extrusions}}

{2 Function Plotting}
- {{!page-"polar_rose"} {b Rose polar plot}}
- {{!page-"cartesian_gravity_well"} {b Cartesian gravity well}}
- {{!page-"axial_chalice"} {b Axial chalice}}

{1:ppx \[@@deriving cad\]}

There is a companion ppx, {{:https://github.com/OCADml/ppx_deriving_cad} \[@@deriving cad\]}
for generating transformation functions for user-defined records and abstract
types made up of the {{!OSCADml.Scad.t} [Scad.t]}, along with their
corresponding vector ({{!OCADml.V2.t} [V2.t]} or {{!OCADml.V3.t} [V3.t]})
types (and those composed of them) provided in by {{:https://github.com/OCADml/OCADml} OCADml}.

{1:auto_generation Generating models on write}

For a more pleasant modelling experience, it is highly recommended to setup
{{:https://github.com/ocaml/dune} dune} to automate writing your models to file
whenever the source files are saved. To do so, add a
{{:https://dune.readthedocs.io/en/latest/dune-files.html#rule} dune rule} that runs
your projects executable after it is built. For example, in [your_project/bin/dune]:

{[
(executable
 (public_name your_project)
 (name main)
 (libraries OCADml OSCADml))

(rule
 (alias model)
 (action
  (run your_project)))
]}

Then start {b dune} in {{:https://dune.readthedocs.io/en/latest/usage.html#watch-mode} watch mode}
with [dune build -w @model].
