wavefront 0.4.0.1 → 0.5
raw patch · 6 files changed
+69/−29 lines, 6 filesdep +semigroups
Dependencies added: semigroups
Files
- CHANGELOG.md +14/−2
- src/Codec/Wavefront/Face.hs +14/−8
- src/Codec/Wavefront/Lexer.hs +1/−1
- src/Codec/Wavefront/Line.hs +9/−7
- src/Codec/Wavefront/Token.hs +29/−10
- wavefront.cabal +2/−1
CHANGELOG.md view
@@ -1,5 +1,17 @@-### 0.4.0.1+# 0.5 +#### Breaking changes++- `objFaces` now contain structured faces of type `Face`. A `Face` can be:+ * a `Triangle` ;+ * a `Quad` ;+ * an arbritrary `Polygon`.+ Whatever the shape of the face, it holds several `FaceIndex` used to reference locations, normals+ and texture coordinates.+- Ditto for `objLines`.++### 0.4.0.1+ - Fixed a bug in the implementation of `untilEnd`. # 0.4@@ -24,7 +36,7 @@ #### Breaking changes - Removed `ctxtName`. It was an old function used to implement user-defined- objects, but since we have `Element`, we don’t those anymore.+ objects, but since we have `Element`, we don’t need those anymore. ### 0.1.0.2
src/Codec/Wavefront/Face.hs view
@@ -11,15 +11,21 @@ module Codec.Wavefront.Face where --- |A face is a triplet of indices. @'Face' vi vti vni@ is a face that indexes the locations with--- @vi@, the texture coordinates with @vti@ and the normals with @vni@. An index set to 'Nothing'--- means /no information/. That is, if @vni == 'Nothing'@, then that 'Face' doesn’t have a normal--- associated with.------ Keep in mind that 'Face' doesn’t represent a polygonal face directly. It represents a face index,--- which is a triplet. In theory, a polygonal face is 3 'Face's.-data Face = Face {+import Data.List.NonEmpty ( NonEmpty )+-- |A face index is a triplet of indices. @'FaceIndex' vi vti vni@ is a face that indexes the+-- locations with @vi@, the texture coordinates with @vti@ and the normals with @vni@. An index set+-- to 'Nothing' means /no information/. That is, if @vni == 'Nothing'@, then that 'FaceIndex'+-- doesn’t have a normal associated with.+data FaceIndex = FaceIndex { faceLocIndex :: {-# UNPACK #-} !Int , faceTexCoordIndex :: !(Maybe Int) , faceNorIndex :: !(Maybe Int) } deriving (Eq,Show)++-- |A face gathers several 'FaceIndex' to build up faces, arranged in either 'Triangle', 'Quad' or+-- an arbritatry 'Polygon'.+data Face+ = Triangle FaceIndex FaceIndex FaceIndex+ | Quad FaceIndex FaceIndex FaceIndex FaceIndex+ | Polygon (NonEmpty FaceIndex)+ deriving (Eq,Show)
src/Codec/Wavefront/Lexer.hs view
@@ -86,7 +86,7 @@ modify $ \ctxt -> ctxt { ctxtLines = lns `append` fmap element (fromList l) } TknF f -> do (fcs,element) <- prepareElement ctxtFaces- modify $ \ctxt -> ctxt { ctxtFaces = fcs `append` fmap element (fromList f) }+ modify $ \ctxt -> ctxt { ctxtFaces = fcs `snoc` element f } TknG g -> modify $ \ctxt -> ctxt { ctxtCurrentGroups = g } TknO o -> modify $ \ctxt -> ctxt { ctxtCurrentObject = Just o } TknMtlLib l -> do
src/Codec/Wavefront/Line.hs view
@@ -11,14 +11,16 @@ module Codec.Wavefront.Line where --- |A line is a pair of indexes. @'Line' vi vti@. @vi@ references the locations and @vti@ indexes--- the texture coordinates. If @vti == 'Nothing'@, then that 'Line' doesn’t have texture coordinates--- associated with.------ Keep in mind that 'Line' doesn’t represent a polygonal line directly. It represents a line index,--- which is a pair. In theory, a polygonal line is 2 'Line's.-data Line = Line {+-- |A line index is a pair of indices. @'LineIndex' vi vti@. @vi@ references the locations and @vti@+-- indexes the texture coordinates. If @vti == 'Nothing'@, then that 'LineIndex' doesn’t have+-- texture coordinates associated with.+data LineIndex = LineIndex { lineLocIndex :: {-# UNPACK #-} !Int , lineTexCoordIndex :: !(Maybe Int) } deriving (Eq,Show) +-- A line gathers two line indices accessible by pattern matching or 'lineIndexA' and 'lineIndexB'.+data Line = Line {+ lineIndexA :: LineIndex+ , lineIndexB :: LineIndex+ } deriving (Eq,Show)
src/Codec/Wavefront/Token.hs view
@@ -20,6 +20,7 @@ import Control.Applicative ( Alternative(..) ) import Data.Attoparsec.Text as AP import Data.Char ( isSpace )+import Data.List.NonEmpty ( NonEmpty(..) ) import Data.Maybe ( catMaybes ) import Data.Text ( Text, unpack ) import qualified Data.Text as T ( empty )@@ -34,9 +35,9 @@ | TknVT TexCoord | TknP [Point] | TknL [Line]- | TknF [Face]+ | TknF Face | TknG [Text]- | TknO Text + | TknO Text | TknMtlLib [Text] | TknUseMtl Text deriving (Eq,Show)@@ -54,7 +55,7 @@ , fmap (Just . TknVT) texCoord , fmap (Just . TknP) points , fmap (Just . TknL) lines- , fmap (Just . TknF) faces+ , fmap (Just . TknF) face , fmap (Just . TknG) groups , fmap (Just . TknO) object , fmap (Just . TknMtlLib) mtllib@@ -117,22 +118,40 @@ ---------------------------------------------------------------------------------------------------- -- Lines ----------------------------------------------------------------------------------------------- TODO: ensure we have at least 2 pairs, otherwise it should fail lines :: Parser [Line]-lines = skipSpace *> string "l " *> skipHSpace *> fmap (\(i,k) -> Line i k) parseLinePair `sepBy1` skipHSpace <* eol+lines = do+ skipSpace+ string "l "+ skipHSpace+ pointIndices <- parsePointIndices+ points <- case pointIndices of+ _:_:_ -> pure $ zipWith Line pointIndices (tail pointIndices)+ _ -> fail "line doesn't have at least two points"+ eol+ pure points where+ parsePointIndices = fmap (\(i,j) -> LineIndex i j) parseLinePair `sepBy1` skipHSpace parseLinePair = do v <- decimal slashThenElse (fmap (\vt -> (v, Just vt)) decimal) (pure (v,Nothing)) ---------------------------------------------------------------------------------------------------- -- Faces ----------------------------------------------------------------------------------------------- TODO: ensure we have at least 3 triples, otherwise it should fail-faces :: Parser [Face]-faces = skipSpace *> string "f " *> skipHSpace *> fmap (\(i,k,j) -> Face i k j) parseFaceTriple `sepBy1` skipHSpace <* eol+face :: Parser Face+face = do+ skipSpace+ string "f "+ skipHSpace+ faceIndices <- parseFaceIndices+ f <- case faceIndices of+ [a,b,c] -> pure (Triangle a b c)+ [a,b,c,d] -> pure (Quad a b c d)+ _:_:_:_:_:_ -> pure (Polygon $ head faceIndices :| tail faceIndices)+ _ -> fail "face doesn't have at least three points"+ eol+ pure f where+ parseFaceIndices = fmap (\(i,k,j) -> FaceIndex i k j) parseFaceTriple `sepBy1` skipHSpace parseFaceTriple = do v <- decimal slashThenElse (parseVT v) (pure (v,Nothing,Nothing))
wavefront.cabal view
@@ -1,5 +1,5 @@ name: wavefront-version: 0.4.0.1+version: 0.5 synopsis: Wavefront OBJ loader description: A Wavefront OBJ loader. Currently supports polygonal information. More could be added if needed (like curves and surface) if people contribute. Feel free@@ -45,6 +45,7 @@ , dlist >= 0.7 && < 0.8 , filepath >= 1.4 && < 1.5 , mtl >= 2.2 && < 2.3+ , semigroups >= 0.18 && < 0.19 , text >= 1.2 && < 1.3 , transformers >= 0.4 && < 0.5 , vector >= 0.11 && < 0.12