diff options
author | Joe Crayne <joe@jerkface.net> | 2019-06-13 16:02:54 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-06-13 16:02:54 -0400 |
commit | 76e4b1bd5310f65608521967db653570bb73ecbe (patch) | |
tree | 48b85b2400e98cda9a67e73e5cb94a3291a305df | |
parent | 3e342655168472ead7e6fd38ef4a21d6132401af (diff) |
crayne parser: step and p
-rw-r--r-- | src/Wavefront.hs | 181 |
1 files changed, 99 insertions, 82 deletions
diff --git a/src/Wavefront.hs b/src/Wavefront.hs index 5cef6dc..74d0b39 100644 --- a/src/Wavefront.hs +++ b/src/Wavefront.hs | |||
@@ -40,40 +40,44 @@ data ObjBuilder m = ObjBuilder | |||
40 | , mtllib :: [S.ByteString] -> m () | 40 | , mtllib :: [S.ByteString] -> m () |
41 | , objectName :: S.ByteString -> m () | 41 | , objectName :: S.ByteString -> m () |
42 | , bmat :: ParamSpec -> [Double] -> m () | 42 | , bmat :: ParamSpec -> [Double] -> m () |
43 | , step :: [Int] -> m () | ||
44 | , points :: [Int] -> m () | ||
43 | , badToken :: L.ByteString -> m () | 45 | , badToken :: L.ByteString -> m () |
44 | } | 46 | } |
45 | 47 | ||
46 | nullBuilder :: Applicative m => ObjBuilder m | 48 | nullBuilder :: Applicative m => ObjBuilder m |
47 | nullBuilder = ObjBuilder | 49 | nullBuilder = ObjBuilder |
48 | { vertex = \vs -> pure () | 50 | { vertex = \vs -> pure () |
49 | , vertexT = \vs -> pure () | 51 | , vertexT = \vs -> pure () |
50 | , vertexN = \vs -> pure () | 52 | , vertexN = \vs -> pure () |
51 | , vertexP = \vs -> pure () | 53 | , vertexP = \vs -> pure () |
52 | , face = \is -> pure () | 54 | , face = \is -> pure () |
53 | , cstype = \isRat typ -> pure () | 55 | , cstype = \isRat typ -> pure () |
54 | , curv2 = \is -> pure () | 56 | , curv2 = \is -> pure () |
55 | , curv = \u0 v0 is -> pure () | 57 | , curv = \u0 v0 is -> pure () |
56 | , parm = \uv is -> pure () | 58 | , parm = \uv is -> pure () |
57 | , specialPoints = \is -> pure () | 59 | , specialPoints = \is -> pure () |
58 | , endFreeForm = pure () | 60 | , endFreeForm = pure () |
59 | , ctech = \approx -> pure () | 61 | , ctech = \approx -> pure () |
60 | , stech = \approx -> pure () | 62 | , stech = \approx -> pure () |
61 | , deg = \is -> pure () | 63 | , deg = \is -> pure () |
62 | , surf = \u0 u1 v0 v1 ts -> pure () | 64 | , surf = \u0 u1 v0 v1 ts -> pure () |
63 | , trim = \ss -> pure () | 65 | , trim = \ss -> pure () |
64 | , hole = \ss -> pure () | 66 | , hole = \ss -> pure () |
65 | , specialCurves = \ss -> pure () | 67 | , specialCurves = \ss -> pure () |
66 | , equivalentCurves = \ccs -> pure () | 68 | , equivalentCurves = \ccs -> pure () |
67 | , groups = \gs -> pure () | 69 | , groups = \gs -> pure () |
68 | , smoothingGroup = \sg -> pure () | 70 | , smoothingGroup = \sg -> pure () |
69 | , mergingGroup = \mg δ -> pure () | 71 | , mergingGroup = \mg δ -> pure () |
70 | , usemtl = \mtl -> pure () | 72 | , usemtl = \mtl -> pure () |
71 | , deprecated_cdc = \is -> pure () | 73 | , deprecated_cdc = \is -> pure () |
72 | , deprecated_bzp = \is -> pure () | 74 | , deprecated_bzp = \is -> pure () |
73 | , mtllib = \fns -> pure () | 75 | , mtllib = \fns -> pure () |
74 | , objectName = \obn -> pure () | 76 | , objectName = \obn -> pure () |
75 | , bmat = \uv fs -> pure () | 77 | , bmat = \uv fs -> pure () |
76 | , badToken = \bs -> pure () | 78 | , step = \is -> pure () |
79 | , points = \is -> pure () | ||
80 | , badToken = \bs -> pure () | ||
77 | } | 81 | } |
78 | 82 | ||
79 | 83 | ||
@@ -168,22 +172,23 @@ findToken (ObjConfig args) bs = case L.dropWhile (\c -> isSpace c || c=='\\') bs | |||
168 | 21 mg | 172 | 21 mg |
169 | 22 mtllib | 173 | 22 mtllib |
170 | 23 o | 174 | 23 o |
171 | 24 parm | 175 | 24 p |
172 | 25 s | 176 | 25 parm |
173 | 26 scrv | 177 | 26 s |
174 | 27 x shadow_obj | 178 | 27 scrv |
175 | 28 sp | 179 | 28 x shadow_obj |
176 | 29 stech -- for all except these, | 180 | 29 sp |
177 | 30 x step -- Two chars suffice to distinguish | 181 | 30 stech -- for all except these, |
178 | 31 surf | 182 | 31 step -- Two chars suffice to distinguish |
179 | 32 x trace_obj -- for all except these, | 183 | 32 surf |
180 | 33 trim -- Two chars suffice to distinguish | 184 | 33 x trace_obj -- for all except these, |
181 | 34 x usemap -- for all except these, | 185 | 34 trim -- Two chars suffice to distinguish |
182 | 35 usemtl -- Two chars suffice to distinguish | 186 | 35 x usemap -- for all except these, |
183 | 36 v | 187 | 36 usemtl -- Two chars suffice to distinguish |
184 | 37 vn | 188 | 37 v |
185 | 38 vp | 189 | 38 vn |
186 | 39 vt | 190 | 39 vp |
191 | 40 vt | ||
187 | 192 | ||
188 | -} | 193 | -} |
189 | 194 | ||
@@ -322,7 +327,8 @@ parseOBJ builder args bs0 | |||
322 | (objn,bs') -> do | 327 | (objn,bs') -> do |
323 | objectName builder (L.toStrict objn) | 328 | objectName builder (L.toStrict objn) |
324 | parseOBJ builder args bs' | 329 | parseOBJ builder args bs' |
325 | _ -> badToken builder bs | 330 | 'p' -> parseI points 2 |
331 | _ -> bad bs | ||
326 | | otherwise = case L.take 2 bs of | 332 | | otherwise = case L.take 2 bs of |
327 | "vt" -> parseV vertexT 3 | 333 | "vt" -> parseV vertexT 3 |
328 | "vn" -> parseV vertexN 3 | 334 | "vn" -> parseV vertexN 3 |
@@ -340,14 +346,14 @@ parseOBJ builder args bs0 | |||
340 | parseOBJ builder args bs' | 346 | parseOBJ builder args bs' |
341 | "cs" -> -- cstype | 347 | "cs" -> -- cstype |
342 | let parseRat = parseChar 'r' | 348 | let parseRat = parseChar 'r' |
343 | parseTyp tok cont | lengthLessThan 3 tok = badToken builder tok | 349 | parseTyp tok cont | lengthLessThan 3 tok = bad tok |
344 | | otherwise = case L.index tok 2 of | 350 | | otherwise = case L.index tok 2 of |
345 | 'a' -> cont Bmatrix $ next 3 tok | 351 | 'a' -> cont Bmatrix $ next 3 tok |
346 | 'z' -> cont Bezier $ next 3 tok | 352 | 'z' -> cont Bezier $ next 3 tok |
347 | 'p' -> cont Bspline $ next 3 tok | 353 | 'p' -> cont Bspline $ next 3 tok |
348 | 'r' -> cont Cardinal $ next 3 tok | 354 | 'r' -> cont Cardinal $ next 3 tok |
349 | 'y' -> cont Taylor $ next 3 tok | 355 | 'y' -> cont Taylor $ next 3 tok |
350 | _ -> badToken builder tok | 356 | _ -> bad tok |
351 | in parseRat (next 2 bs) $ \isRat bs' -> do | 357 | in parseRat (next 2 bs) $ \isRat bs' -> do |
352 | parseTyp bs' $ \typ bs'' -> do | 358 | parseTyp bs' $ \typ bs'' -> do |
353 | cstype builder isRat typ | 359 | cstype builder isRat typ |
@@ -355,7 +361,7 @@ parseOBJ builder args bs0 | |||
355 | "ct" -> -- ctech | 361 | "ct" -> -- ctech |
356 | let tok = next 2 bs | 362 | let tok = next 2 bs |
357 | in if lengthLessThan 2 tok | 363 | in if lengthLessThan 2 tok |
358 | then badToken builder tok | 364 | then bad tok |
359 | else case L.index tok 1 of | 365 | else case L.index tok 1 of |
360 | 'p' -> -- cparm | 366 | 'p' -> -- cparm |
361 | parseFloats (findToken args) (next 2 tok) $ \is bs' -> do | 367 | parseFloats (findToken args) (next 2 tok) $ \is bs' -> do |
@@ -372,9 +378,9 @@ parseOBJ builder args bs0 | |||
372 | let δ:θ:_ = fs ++ repeat 1.0 | 378 | let δ:θ:_ = fs ++ repeat 1.0 |
373 | ctech builder (CurvatureBasedPolygon δ θ) | 379 | ctech builder (CurvatureBasedPolygon δ θ) |
374 | parseOBJ builder args bs' | 380 | parseOBJ builder args bs' |
375 | _ -> badToken builder tok | 381 | _ -> bad tok |
376 | "cu" -> if lengthLessThan 5 bs | 382 | "cu" -> if lengthLessThan 5 bs |
377 | then badToken builder bs | 383 | then bad bs |
378 | else if L.index bs 4 == '2' | 384 | else if L.index bs 4 == '2' |
379 | then parseI curv2 5 -- curv2 | 385 | then parseI curv2 5 -- curv2 |
380 | else do -- curv | 386 | else do -- curv |
@@ -404,36 +410,44 @@ parseOBJ builder args bs0 | |||
404 | specialCurves builder ss | 410 | specialCurves builder ss |
405 | parseOBJ builder args bs' | 411 | parseOBJ builder args bs' |
406 | "sp" -> parseI specialPoints 3 | 412 | "sp" -> parseI specialPoints 3 |
407 | "st" -> -- stech | 413 | "st" -> -- stech or step |
408 | let tok = next 2 bs | 414 | if lengthLessThan 4 bs then bad bs |
409 | in if lengthLessThan 2 tok | 415 | else case L.index bs 3 of |
410 | then badToken builder tok | 416 | 'c' -> |
411 | else case L.index tok 1 of | 417 | -- stech |
412 | 'p' -> -- cparma/cparmb | 418 | let tok = next 2 bs |
413 | if lengthLessThan 6 tok | 419 | in if lengthLessThan 2 tok |
414 | then badToken builder tok | 420 | then bad tok |
415 | else if L.index tok 5 == 'b' | 421 | else case L.index tok 1 of |
416 | then -- cparmb | 422 | 'p' -> -- cparma/cparmb |
417 | parseFloats (findToken args) (next 5 tok) $ \is bs' -> do | 423 | if lengthLessThan 6 tok |
418 | let x:_ = is ++ [0] | 424 | then bad tok |
419 | stech builder (UniformAfterTrimming x) | 425 | else if L.index tok 5 == 'b' |
420 | parseOBJ builder args bs' | 426 | then -- cparmb |
421 | else -- cparma | 427 | parseFloats (findToken args) (next 5 tok) $ \is bs' -> do |
422 | parseFloats (findToken args) (next 5 tok) $ \is bs' -> do | 428 | let x:_ = is ++ [0] |
423 | let x:y:_ = is ++ [0] | 429 | stech builder (UniformAfterTrimming x) |
424 | stech builder (UniformIsoparametric x y) | 430 | parseOBJ builder args bs' |
425 | parseOBJ builder args bs' | 431 | else -- cparma |
426 | 's' -> -- cspace | 432 | parseFloats (findToken args) (next 5 tok) $ \is bs' -> do |
427 | parseFloats (findToken args) (next 2 tok) $ \fs bs' -> do | 433 | let x:y:_ = is ++ [0] |
428 | let x:_ = fs ++ [1.0] | 434 | stech builder (UniformIsoparametric x y) |
429 | stech builder (MaxLengthPolytopal x) | 435 | parseOBJ builder args bs' |
430 | parseOBJ builder args bs' | 436 | 's' -> -- cspace |
431 | 'u' -> -- curv | 437 | parseFloats (findToken args) (next 2 tok) $ \fs bs' -> do |
432 | parseFloats (findToken args) (next 2 tok) $ \fs bs' -> do | 438 | let x:_ = fs ++ [1.0] |
433 | let δ:θ:_ = fs ++ repeat 1.0 | 439 | stech builder (MaxLengthPolytopal x) |
434 | stech builder (CurvatureBasedPolytope δ θ) | 440 | parseOBJ builder args bs' |
435 | parseOBJ builder args bs' | 441 | 'u' -> -- curv |
436 | _ -> badToken builder tok | 442 | parseFloats (findToken args) (next 2 tok) $ \fs bs' -> do |
443 | let δ:θ:_ = fs ++ repeat 1.0 | ||
444 | stech builder (CurvatureBasedPolytope δ θ) | ||
445 | parseOBJ builder args bs' | ||
446 | _ -> bad tok | ||
447 | |||
448 | _ -> -- step | ||
449 | parseI step 4 | ||
450 | |||
437 | "su" -> -- surf | 451 | "su" -> -- surf |
438 | parseFloatsN 4 (findToken args) (next 2 bs) $ \fs bs' -> do | 452 | parseFloatsN 4 (findToken args) (next 2 bs) $ \fs bs' -> do |
439 | parseTriples (findToken args) bs' $ \ts bs'' -> do | 453 | parseTriples (findToken args) bs' $ \ts bs'' -> do |
@@ -463,10 +477,13 @@ parseOBJ builder args bs0 | |||
463 | in (fn <> L.take 1 ext <> f) : fs | 477 | in (fn <> L.take 1 ext <> f) : fs |
464 | mtllib builder (map L.toStrict $ slurp fnn) | 478 | mtllib builder (map L.toStrict $ slurp fnn) |
465 | parseOBJ builder args bs' | 479 | parseOBJ builder args bs' |
466 | -- TODO: call,csh,step,c_interp,d_interp,lod,shadow_obj,trace_obj,bevel | 480 | -- TODO: call,csh,c_interp,d_interp,lod,shadow_obj,trace_obj,bevel |
467 | _ -> badToken builder bs | 481 | _ -> bad bs |
468 | where | 482 | where |
469 | bs = findToken args bs0 | 483 | bs = findToken args bs0 |
484 | bad bs = case L.break (=='\n') bs of | ||
485 | (x,bs') -> do badToken builder x | ||
486 | parseOBJ builder args bs' | ||
470 | next n xs = nextToken (findToken args) $ L.drop n xs | 487 | next n xs = nextToken (findToken args) $ L.drop n xs |
471 | parseChar c tok cont = case L.uncons tok of | 488 | parseChar c tok cont = case L.uncons tok of |
472 | Just (x,cs) | x==c -> cont True $ next 0 cs | 489 | Just (x,cs) | x==c -> cont True $ next 0 cs |