summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-06-13 20:51:27 -0400
committerJoe Crayne <joe@jerkface.net>2019-06-13 20:51:27 -0400
commitb2001473ed37cb228190b4b3c37e598deea88f5b (patch)
tree8be6254cd2875b9c0190cc14fa7bf087b8589f5c
parentf41806fb911f17e5102be3ef20a74d0b033fa2a9 (diff)
crayne parser: shadow_obj and trace_obj
-rw-r--r--src/Wavefront.hs36
1 files changed, 29 insertions, 7 deletions
diff --git a/src/Wavefront.hs b/src/Wavefront.hs
index 208e5bf..6378d08 100644
--- a/src/Wavefront.hs
+++ b/src/Wavefront.hs
@@ -46,6 +46,8 @@ data ObjBuilder m = ObjBuilder
46 , maplib :: [S.ByteString] -> m () 46 , maplib :: [S.ByteString] -> m ()
47 , c_interp :: Bool -> m () 47 , c_interp :: Bool -> m ()
48 , d_interp :: Bool -> m () 48 , d_interp :: Bool -> m ()
49 , trace_obj :: S.ByteString -> m ()
50 , shadow_obj :: S.ByteString -> m ()
49 , badToken :: L.ByteString -> m () 51 , badToken :: L.ByteString -> m ()
50 } 52 }
51 53
@@ -85,6 +87,8 @@ nullBuilder = ObjBuilder
85 , maplib = \fns -> pure () 87 , maplib = \fns -> pure ()
86 , c_interp = \b -> pure () 88 , c_interp = \b -> pure ()
87 , d_interp = \b -> pure () 89 , d_interp = \b -> pure ()
90 , trace_obj = \obj -> pure ()
91 , shadow_obj = \obj -> pure ()
88 , badToken = \bs -> pure () 92 , badToken = \bs -> pure ()
89 } 93 }
90 94
@@ -202,12 +206,12 @@ findNewLine ps o@(ObjConfig args) bs = case L.break (\c -> c=='\n' || c=='\\' ||
202 28 x res 206 28 x res
203 29 s 207 29 s
204 30 scrv 208 30 scrv
205 31 x shadow_obj 209 31 shadow_obj
206 32 sp 210 32 sp
207 33 stech -- for all except these, 211 33 stech -- for all except these,
208 34 step -- Two chars suffice to distinguish 212 34 step -- Two chars suffice to distinguish
209 35 surf 213 35 surf
210 36 x trace_obj -- for all except these, 214 36 trace_obj -- for all except these,
211 37 trim -- Two chars suffice to distinguish 215 37 trim -- Two chars suffice to distinguish
212 38 usemap -- for all except these, 216 38 usemap -- for all except these,
213 39 usemtl -- Two chars suffice to distinguish 217 39 usemtl -- Two chars suffice to distinguish
@@ -460,6 +464,8 @@ parseOBJ builder args bs0
460 parseCurveSpecs (findToken args) (next 2 bs) $ \ss bs' -> do 464 parseCurveSpecs (findToken args) (next 2 bs) $ \ss bs' -> do
461 specialCurves builder ss 465 specialCurves builder ss
462 parseOBJ builder args bs' 466 parseOBJ builder args bs'
467 "sh" -> -- shadow_obj
468 parseO shadow_obj 10
463 "sp" -> parseI specialPoints 3 469 "sp" -> parseI specialPoints 3
464 "st" -> -- stech or step 470 "st" -> -- stech or step
465 if lengthLessThan 4 bs then bad bs 471 if lengthLessThan 4 bs then bad bs
@@ -505,10 +511,16 @@ parseOBJ builder args bs0
505 let u0:u1:v0:v1:_ = fs ++ repeat 0 511 let u0:u1:v0:v1:_ = fs ++ repeat 0
506 surf builder u0 u1 v0 v1 ts 512 surf builder u0 u1 v0 v1 ts
507 parseOBJ builder args bs'' 513 parseOBJ builder args bs''
508 "tr" -> -- trim 514 "tr" -> -- trip or trace_obj
509 parseCurveSpecs (findToken args) (next 2 bs) $ \ss bs' -> do 515 if lengthLessThan 3 bs
510 trim builder ss 516 then bad bs
511 parseOBJ builder args bs' 517 else case L.index bs 2 of
518 'a' -> -- trace_obj
519 parseO trace_obj 9
520 _ -> -- trim
521 parseCurveSpecs (findToken args) (next 2 bs) $ \ss bs' -> do
522 trim builder ss
523 parseOBJ builder args bs'
512 "us" -> -- usemtl or usemap 524 "us" -> -- usemtl or usemap
513 if lengthLessThan 5 bs 525 if lengthLessThan 5 bs
514 then bad bs 526 then bad bs
@@ -554,13 +566,17 @@ parseOBJ builder args bs0
554 _ -> bad bs 566 _ -> bad bs
555 where 567 where
556 bs = findToken args bs0 568 bs = findToken args bs0
557 bad bs = case L.break (=='\n') bs of 569 bad bs = case findNewLine [] args bs of
558 (x,bs') -> do badToken builder x 570 (x,bs') -> do badToken builder x
559 parseOBJ builder args bs' 571 parseOBJ builder args bs'
560 next n xs = nextToken (findToken args) $ L.drop n xs 572 next n xs = nextToken (findToken args) $ L.drop n xs
561 parseChar c tok cont = case L.uncons tok of 573 parseChar c tok cont = case L.uncons tok of
562 Just (x,cs) | x==c -> cont True $ next 0 cs 574 Just (x,cs) | x==c -> cont True $ next 0 cs
563 _ -> cont False tok 575 _ -> cont False tok
576 parseO build n = case findNewLine [] args $ L.drop n bs of
577 (fn,bs') -> do
578 build builder $ sanitizeOBJFilename fn
579 parseOBJ builder args bs'
564 parseUV tok cont = parseChar 'u' tok $ \isU bs' -> do 580 parseUV tok cont = parseChar 'u' tok $ \isU bs' -> do
565 cont (if isU then ParamU else ParamV) 581 cont (if isU then ParamU else ParamV)
566 (if isU then bs' else L.drop 1 bs') 582 (if isU then bs' else L.drop 1 bs')
@@ -582,3 +598,9 @@ parseOBJ builder args bs0
582 _ | lengthLessThan 2 tok -> (0,tok) 598 _ | lengthLessThan 2 tok -> (0,tok)
583 _ -> (if L.index tok 1 == 'f' then 0 else 1, next 1 tok) 599 _ -> (if L.index tok 1 == 'f' then 0 else 1, next 1 tok)
584 cont sg bs'' 600 cont sg bs''
601
602sanitizeOBJFilename :: L.ByteString -> S.ByteString
603sanitizeOBJFilename fn = case S.breakEnd isSpace $ L.toStrict $ L.dropWhile isSpace fn of
604 (stripped,_) -> case S.breakEnd (=='.') stripped of
605 (basename,ext) | S.null basename -> ext <> ".obj"
606 | otherwise -> stripped