diff --git a/Graphics/Implicit/ExtOpenScad/Primitives.hs b/Graphics/Implicit/ExtOpenScad/Primitives.hs index cb9112e..0cb3b69 100644 --- a/Graphics/Implicit/ExtOpenScad/Primitives.hs +++ b/Graphics/Implicit/ExtOpenScad/Primitives.hs @@ -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 diff --git a/Graphics/Implicit/ExtOpenScad/Util/OVal.hs b/Graphics/Implicit/ExtOpenScad/Util/OVal.hs index 3c15473..ba3927c 100644 --- a/Graphics/Implicit/ExtOpenScad/Util/OVal.hs +++ b/Graphics/Implicit/ExtOpenScad/Util/OVal.hs @@ -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