elm-obj-file supports triangular meshes that may have normal vectors and/or texture coordinates, polylines and points.
By default, the geometrical data is returned in the ObjCoordinates coordinate system.
It's also possible to transform coordinates if desired.
Note that all primitive decoders require at least one element and will fail if no elements are found.
Decode just the plain positions. Use with Scene3d.Mesh.indexedTriangles and Scene3d.Mesh.indexedFacets from elm-3d-scene.
Decode positions and normal vectors. Use with Scene3d.Mesh.indexedFaces.
Decode positions and UV (texture) coordinates.
Use with Scene3d.Mesh.texturedTriangles or Scene3d.Mesh.texturedFacets.
Decode positions, UV and normal vectors. Use with Scene3d.Mesh.texturedFaces.
Decode positions, UV, normal vectors and tangents. Use with Scene3d.Mesh.bumpyFaces.
Run the decoder on the string. Takes a function, that knows how to convert float coordinates into physical units.
decodeString Length.meters triangles string == Ok (TriangularMesh {...})
decodeString Length.meters triangles string == Err "Line 1: Invalid OBJ syntax '...'"Load a mesh from an HTTP request.
type Msg
= GotMesh (Result Http.Error (TriangularMesh (Point3d Meters ObjCoordinates)))
getMesh : Cmd Msg
getMesh =
Http.get
{ url = "Pod.obj.txt"
, expect =
expectObj GotMesh
Length.meters
triangles
}Note: the .txt extension is required to work with elm reactor.
Primitives within OBJ files can be tagged with metadata such as object name, group names and materials.
Using the filtering decoders, you can selectively decode based on this metadata.
For advanced filtering rules check the filter decoder.
Decode data for the given object name.
wheels : Decoder (TriangularMesh (Point3d Meters ObjCoordinates))
wheels =
object "wheels" trianglesDecode data for the default group. This group has a special meaning, all elements are assigned to it if a group is not specified.
defaultGroup =
group "default"Decode a sorted list of object names.
Decode a sorted list of group names.
Decode a sorted list of material names.
Transform the decoder. For example, if you need to decode triangles’ vertices:
vertices : Decoder (List (Point3d Meters ObjCoordinates))
vertices =
map
(\triangularMesh ->
triangularMesh
|> TriangularMesh.vertices
|> Array.toList
)
trianglesJoin the result from two decoders. This lets you extract parts of the same OBJ file into separate meshes.
type alias Car =
{ wheels : TriangularMesh (Point3d Meters ObjCoordinates)
, base : TriangularMesh (Point3d Meters ObjCoordinates)
}
carDecoder : Decoder Car
carDecoder =
map2 Car
(object "wheels" triangles)
(object "base" triangles)Filter what should be decoded. For example, to implement the group decoder from above:
group name =
filter
(\properties ->
List.member name properties.groups
)Try a bunch of different decoders. You will get the result from the first one that succeeds.
A decoder that always fails with a given error message. Use it in case you need custom error messages.
A decoder that always succeeds with the result. May be useful in combination with oneOf to
provide a placeholder mesh if decoding fails.
Run one decoder and then run another decoder. Useful when you first want to look at metadata, and then filter based on that.
Combine multiple decoders together. For example, to extract meshes for all materials:
type alias MeshWithMaterial =
( String, TriangularMesh (Point3d Meters ObjCoordinates) )
trianglesForMaterials : String -> Decode (List MeshWithMaterial)
trianglesForMaterials names =
names
|> List.map
(\materialName ->
material materialName triangles
|> map (\mesh -> ( materialName, mesh ))
)
|> combine
-- Decode material names, and then decode
-- triangles for these materials
withMaterials : Decode (List MeshWithMaterial)
withMaterials =
materialNames |> andThen trianglesForMaterialsCoordinate system for decoded meshes.
Transform coordinates when decoding. For example, if you need to render a mesh with Z-up, but it was exported with Y-up:
type ZUpCoords
= ZUpCoords
yUpToZUpFrame : Frame3d Meters ZUpCoords { defines : ObjCoordinates }
yUpToZUpFrame =
Frame3d.atOrigin
|> Frame3d.rotateAround
Axis3d.x
(Angle.degrees 90)
zUpTriangles : Decoder (TriangularMesh (Point3d Meters ZUpCoords))
zUpTriangles =
trianglesIn yUpToZUpFrame
A value that knows how to decode information from the OBJ file format