module Data.Obj3D ( ObjModel(..) , processObj , loadObj , loadObjFile , Vertex , VertexNormal , TexCoord , FaceVertex , Face , SourceName , ParseError ) where import Control.Arrow import Control.Monad import Data.Maybe import Data.Obj3D.Parser data ObjModel = ObjModel { objVertices :: [Vertex] , objTexCoords :: [TexCoord] , objNormals :: [VertexNormal] , objFaces :: [[Face]] } deriving Show processObj :: [ObjLine] -> ObjModel processObj objlines = ObjModel { objVertices = vertices , objTexCoords = texcoords , objNormals = normals , objFaces = faces } where vertices = catMaybes $ map vertex objlines vertex (VertexLine v) = Just v vertex _ = Nothing texcoords = catMaybes $ map texcoord objlines texcoord (TexCoordLine v) = Just v texcoord _ = Nothing normals = catMaybes $ map normal objlines normal (VertexNormalLine n) = Just n normal _ = Nothing faces = filter (not . null) $ map (catMaybes . map face) $ splitLines objlines face (FaceLine f) = Just f face _ = Nothing splitLines [] = [] splitLines l = let (l1, l2) = break isObjectLine l in l1 : (if null l2 then [] else splitLines $ tail l2) isObjectLine (ObjectLine _) = True isObjectLine _ = False loadObj :: SourceName -> String -> Either ParseError ObjModel loadObj fname = right processObj . parseObj fname loadObjFile :: SourceName -> IO (Either ParseError ObjModel) loadObjFile fname = liftM (loadObj fname) $ readFile fname