add multmatrix scad primitive

Closes #397.
This commit is contained in:
Richard Marko 2022-04-22 19:45:42 +02:00
parent 0e795013ea
commit 8ea479929f
2 changed files with 25 additions and 3 deletions

View File

@ -31,13 +31,13 @@ import Graphics.Implicit.ExtOpenScad.Util.OVal (OTypeMirror, caseOType, divideOb
import Graphics.Implicit.ExtOpenScad.Util.StateC (errorC)
-- Note the use of a qualified import, so we don't have the functions in this file conflict with what we're importing.
import qualified Graphics.Implicit.Primitives as Prim (withRounding, sphere, rect3, rect, translate, circle, polygon, extrude, cylinder2, union, unionR, intersect, intersectR, difference, differenceR, rotate, rotate3V, rotate3, scale, extrudeM, rotateExtrude, shell, mirror, pack3, pack2)
import qualified Graphics.Implicit.Primitives as Prim (withRounding, sphere, rect3, rect, translate, circle, polygon, extrude, cylinder2, union, unionR, intersect, intersectR, difference, differenceR, rotate, rotate3V, rotate3, transform3, scale, extrudeM, rotateExtrude, shell, mirror, pack3, pack2)
import Control.Monad (when, mplus)
import Data.Text.Lazy (Text)
import Linear ( V3(V3), V2(V2) )
import Linear (M34, M44, V2(V2), V3(V3), V4(V4))
import Linear.Affine (qdA)
default ()
@ -69,6 +69,7 @@ primitiveModules =
, onModIze pack [([("size", noDefault), ("sep", noDefault)], requiredSuite)]
, onModIze unit [([("unit", noDefault)], requiredSuite)]
, onModIze mirror [([("x", noDefault), ("y", noDefault), ("z", noDefault)], requiredSuite), ([("v", noDefault)], requiredSuite)]
, onModIze multmatrix [([("m", noDefault)], requiredSuite)]
]
where
hasDefault = True
@ -588,6 +589,20 @@ mirror = moduleWithSuite "mirror" $ \_ children -> do
pure $ pure $
objMap (Prim.mirror (V2 x y)) (Prim.mirror (V3 x y z)) children
multmatrix :: (Symbol, SourcePosition -> [OVal] -> ArgParser (StateC [OVal]))
multmatrix = moduleWithSuite "multmatrix" $ \_ children -> do
example "multmatrix (m=[[1,0,0,0],[0,1,0,0],[0,0,1,0]]) cube(3);"
example "multmatrix (m=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]) cube(3);"
m <-
do
m :: Either (M34 ) (M44 ) <- argument "m"
`doc` "3x4 or 4x4 matrix representing affine transformation";
pure $ case m of
Left (V3 a b c) -> V4 a b c (V4 0 0 0 1)
Right m44 -> m44
pure $ pure $
objMap id (Prim.transform3 m) children
---------------
(<|>) :: ArgParser a -> ArgParser a -> ArgParser a

View File

@ -33,7 +33,7 @@ import Data.Text.Lazy (Text)
import Control.Parallel.Strategies (runEval, rpar, rseq)
-- To build vectors of s.
import Linear (V2(V2), V3(V3))
import Linear (V2(V2), V3(V3), V4(V4))
-- Convert OVals (and Lists of OVals) into a given Haskell type
class OTypeMirror a where
@ -109,6 +109,13 @@ instance (OTypeMirror a) => OTypeMirror (V3 a) where
{-# INLINABLE fromOObj #-}
toOObj (V3 a b c) = OList [toOObj a, toOObj b, toOObj c]
instance (OTypeMirror a) => OTypeMirror (V4 a) where
fromOObj (OList [fromOObj -> Just a,fromOObj -> Just b,fromOObj -> Just c,fromOObj -> Just d]) =
Just (V4 a b c d)
fromOObj _ = Nothing
{-# INLINABLE fromOObj #-}
toOObj (V4 a b c d) = OList [toOObj a, toOObj b, toOObj c, toOObj d]
instance (OTypeMirror a, OTypeMirror b) => OTypeMirror (a -> b) where
fromOObj (OFunc f) = Just $ \input ->
let