STL
is a library for reading and analyzing ASCII STL 3D model files.
NOTE: Library does not support binary STL files.
NOTE: Library does not support facet normal vector calculation. Normal vectors are currently always data read from file.
For more information on the STL files and the STL spec, see the wikipedia page.
If using in an existing Elixir project:
def deps do
[{:stl, github: "cjfreeze/stl"}]
end
# or
def deps do
[{:stl, "~> 0.1.0"}]
end
If experimenting with standalone:
git clone git@github.com:cjfreeze/stl.git
cd stl
mix deps.get
mix iex -S mix
STL generates %STL{}
structs from ASCII STL files or binaries.
For more information on any of the functions mentioned below, be sure to check out the docs!
To use, call either STL.parse!(stl_binary)
or STL.parse_file!(stl_filename)
to build a struct from your data:
iex> stl = STL.parse!(stl_binary)
%STL{name: "MYSTL", ...}
# or
iex> stl = STL.parse_file!("my.stl")
%STL{name: "MYSTL", ...}
This struct can be used with the analysis functions triangle_count/1
, bounding_box/1
, and surface_area/1
to get basic information about your file:
iex> STL.triangle_count(stl)
1000
iex> STL.surface_area(stl)
1000.0
iex> STL.bounding_box(stl)
[
{1.0, 1.0, 1.0},
{1.0, 1.0, -1.0},
{1.0, -1.0, 1.0},
{1.0, -1.0, -1.0},
{-1.0, 1.0, 1.0},
{-1.0, 1.0, -1.0},
{-1.0, -1.0, 1.0},
{-1.0, -1.0, -1.0}
]
You can also work directly with the STL
struct, which has data such as :name
, and a list of :facets
defined in the STL file:
iex> name = stl.name
"MYSTL"
iex> first_facet = hd(stl.facets)
%STL.Facet{...}
You can write your own parser by implementing the STL.Parser
behaviour, and setting the following config value:
config :stl, :parser, MyApp.MySTLParser # defaults to STL.Parser.Stream
As an experiment, I wrote another parser using NimbleParsec, called STL.Parser.Nimble
. It has some quirks, but feel free to experiment with it. You can set the parser at runtime to easily experiment by providing it as an optional second argument to either parse!
function:
iex> STL.parse_file!("my.stl", STL.Parser.Nimble)
# or
iex> STL.parse!(stl_binary, STL.Parser.Nimble)