diff options
author | Joe Crayne <joe@jerkface.net> | 2019-06-13 20:51:27 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-06-13 20:51:27 -0400 |
commit | b2001473ed37cb228190b4b3c37e598deea88f5b (patch) | |
tree | 8be6254cd2875b9c0190cc14fa7bf087b8589f5c | |
parent | f41806fb911f17e5102be3ef20a74d0b033fa2a9 (diff) |
crayne parser: shadow_obj and trace_obj
-rw-r--r-- | src/Wavefront.hs | 36 |
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 | |||
602 | sanitizeOBJFilename :: L.ByteString -> S.ByteString | ||
603 | sanitizeOBJFilename 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 | ||