{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE FlexibleInstances #-}
module Waterfall.Transforms
( Transformable
, matTransform
, scale
, uScale
, rotate
, translate
, mirror
) where
import Waterfall.Internal.Solid (Solid (..), acquireSolid, solidFromAcquire)
import Waterfall.Internal.Finalizers (toAcquire, unsafeFromAcquire) 
import Waterfall.Internal.Path.Common (RawPath(..))
import Linear.V3 (V3 (..))
import Linear.V4 (V4 (..))
import Linear (M34, (*^), normalize, dot, (!*), unit, _w, _xyz)
import qualified Linear.Quaternion as Quaternion
import qualified OpenCascade.GP.Trsf as GP.Trsf
import qualified OpenCascade.GP as GP
import qualified OpenCascade.GP.GTrsf as GP.GTrsf
import qualified OpenCascade.GP.Ax1 as GP.Ax1
import qualified OpenCascade.GP.Ax2 as GP.Ax2
import qualified OpenCascade.GP.Dir as GP.Dir
import qualified OpenCascade.GP.Vec as GP.Vec
import qualified OpenCascade.BRepBuilderAPI.Transform  as BRepBuilderAPI.Transform
import qualified OpenCascade.BRepBuilderAPI.GTransform  as BRepBuilderAPI.GTransform
import Control.Monad.IO.Class (liftIO)
import Data.Acquire
import Foreign.Ptr
import Waterfall.Internal.Path (Path(..))
import OpenCascade.Inheritance (upcast, unsafeDowncast)
import Data.Function ((&))
import Control.Lens ((.~))

-- | Typeclass for objects that can be manipulated in 3D space
class Transformable a where
    -- | Directly transform with a transformation matrix
    matTransform :: M34 Double -> a -> a
    -- | Scale by different amounts along the x, y and z axes
    scale :: V3 Double -> a -> a
    -- Uniform Scale
    -- | Scale uniformally along all axes
    uScale :: Double -> a -> a
    -- | Rotate by Axis and Angle (in radians)
    rotate :: V3 Double -> Double -> a -> a
    -- | Translate by a vector in 3D space
    translate :: V3 Double -> a -> a
    -- | Mirror in the plane, which passes through the origin, tangent to the specified vector
    mirror :: V3 Double -> a -> a

fromTrsfSolid :: Acquire (Ptr GP.Trsf) -> Solid -> Solid
fromTrsfSolid :: Acquire (Ptr Trsf) -> Solid -> Solid
fromTrsfSolid Acquire (Ptr Trsf)
mkTrsf Solid
s = Acquire (Ptr Shape) -> Solid
solidFromAcquire (Acquire (Ptr Shape) -> Solid) -> Acquire (Ptr Shape) -> Solid
forall a b. (a -> b) -> a -> b
$ do 
    Ptr Shape
solid <- Solid -> Acquire (Ptr Shape)
acquireSolid Solid
s
    Ptr Trsf
trsf <- Acquire (Ptr Trsf)
mkTrsf 
    Ptr Shape -> Ptr Trsf -> Bool -> Acquire (Ptr Shape)
BRepBuilderAPI.Transform.transform Ptr Shape
solid Ptr Trsf
trsf Bool
True 

fromGTrsfSolid :: Acquire (Maybe (Ptr GP.GTrsf)) -> Solid -> Solid
fromGTrsfSolid :: Acquire (Maybe (Ptr GTrsf)) -> Solid -> Solid
fromGTrsfSolid Acquire (Maybe (Ptr GTrsf))
mkTrsf Solid
s = Acquire (Ptr Shape) -> Solid
solidFromAcquire (Acquire (Ptr Shape) -> Solid) -> Acquire (Ptr Shape) -> Solid
forall a b. (a -> b) -> a -> b
$ do 
    Ptr Shape
solid <- Solid -> Acquire (Ptr Shape)
acquireSolid Solid
s
    Maybe (Ptr GTrsf)
trsfMay <- Acquire (Maybe (Ptr GTrsf))
mkTrsf 
    case Maybe (Ptr GTrsf)
trsfMay of
        Just Ptr GTrsf
trsf -> Ptr Shape -> Ptr GTrsf -> Bool -> Acquire (Ptr Shape)
BRepBuilderAPI.GTransform.gtransform Ptr Shape
solid Ptr GTrsf
trsf Bool
True 
        Maybe (Ptr GTrsf)
Nothing -> Ptr Shape -> Acquire (Ptr Shape)
forall a. a -> Acquire a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Ptr Shape
solid

fromTrsfPath :: (V3 Double -> V3 Double) -> Acquire (Ptr GP.Trsf) -> Path -> Path
fromTrsfPath :: (V3 Double -> V3 Double) -> Acquire (Ptr Trsf) -> Path -> Path
fromTrsfPath V3 Double -> V3 Double
_ Acquire (Ptr Trsf)
mkTrsf (Path (ComplexRawPath Ptr Wire
p)) = RawPath -> Path
Path (RawPath -> Path)
-> (Acquire (Ptr Wire) -> RawPath) -> Acquire (Ptr Wire) -> Path
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Wire -> RawPath
ComplexRawPath (Ptr Wire -> RawPath)
-> (Acquire (Ptr Wire) -> Ptr Wire)
-> Acquire (Ptr Wire)
-> RawPath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Acquire (Ptr Wire) -> Ptr Wire
forall a. Acquire a -> a
unsafeFromAcquire (Acquire (Ptr Wire) -> Path) -> Acquire (Ptr Wire) -> Path
forall a b. (a -> b) -> a -> b
$ do 
    Ptr Wire
path <- Ptr Wire -> Acquire (Ptr Wire)
forall a. a -> Acquire a
toAcquire Ptr Wire
p
    Ptr Trsf
trsf <- Acquire (Ptr Trsf)
mkTrsf 
    (IO (Ptr Wire) -> Acquire (Ptr Wire)
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr Wire) -> Acquire (Ptr Wire))
-> (Ptr Shape -> IO (Ptr Wire)) -> Ptr Shape -> Acquire (Ptr Wire)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Shape -> IO (Ptr Wire)
forall a b. DiscriminatedSubTypeOf a b => Ptr a -> IO (Ptr b)
unsafeDowncast) (Ptr Shape -> Acquire (Ptr Wire))
-> Acquire (Ptr Shape) -> Acquire (Ptr Wire)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr Shape -> Ptr Trsf -> Bool -> Acquire (Ptr Shape)
BRepBuilderAPI.Transform.transform (Ptr Wire -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
upcast Ptr Wire
path) Ptr Trsf
trsf Bool
True 
fromTrsfPath V3 Double -> V3 Double
f Acquire (Ptr Trsf)
_ (Path (SinglePointRawPath V3 Double
v)) = RawPath -> Path
Path (RawPath -> Path) -> (V3 Double -> RawPath) -> V3 Double -> Path
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V3 Double -> RawPath
SinglePointRawPath (V3 Double -> RawPath)
-> (V3 Double -> V3 Double) -> V3 Double -> RawPath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V3 Double -> V3 Double
f (V3 Double -> Path) -> V3 Double -> Path
forall a b. (a -> b) -> a -> b
$ V3 Double
v
fromTrsfPath V3 Double -> V3 Double
_ Acquire (Ptr Trsf)
_ (Path RawPath
EmptyRawPath) = RawPath -> Path
Path RawPath
EmptyRawPath

fromGTrsfPath :: (V3 Double -> V3 Double) -> Acquire (Maybe (Ptr GP.GTrsf)) -> Path -> Path
fromGTrsfPath :: (V3 Double -> V3 Double)
-> Acquire (Maybe (Ptr GTrsf)) -> Path -> Path
fromGTrsfPath V3 Double -> V3 Double
_ Acquire (Maybe (Ptr GTrsf))
mkTrsf (Path (ComplexRawPath Ptr Wire
p)) = RawPath -> Path
Path (RawPath -> Path)
-> (Acquire (Ptr Wire) -> RawPath) -> Acquire (Ptr Wire) -> Path
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Wire -> RawPath
ComplexRawPath (Ptr Wire -> RawPath)
-> (Acquire (Ptr Wire) -> Ptr Wire)
-> Acquire (Ptr Wire)
-> RawPath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Acquire (Ptr Wire) -> Ptr Wire
forall a. Acquire a -> a
unsafeFromAcquire (Acquire (Ptr Wire) -> Path) -> Acquire (Ptr Wire) -> Path
forall a b. (a -> b) -> a -> b
$ do 
    Ptr Wire
path <- Ptr Wire -> Acquire (Ptr Wire)
forall a. a -> Acquire a
toAcquire Ptr Wire
p
    Maybe (Ptr GTrsf)
trsfMay <- Acquire (Maybe (Ptr GTrsf))
mkTrsf 
    case Maybe (Ptr GTrsf)
trsfMay of
        Just Ptr GTrsf
trsf -> (IO (Ptr Wire) -> Acquire (Ptr Wire)
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr Wire) -> Acquire (Ptr Wire))
-> (Ptr Shape -> IO (Ptr Wire)) -> Ptr Shape -> Acquire (Ptr Wire)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Shape -> IO (Ptr Wire)
forall a b. DiscriminatedSubTypeOf a b => Ptr a -> IO (Ptr b)
unsafeDowncast) (Ptr Shape -> Acquire (Ptr Wire))
-> Acquire (Ptr Shape) -> Acquire (Ptr Wire)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr Shape -> Ptr GTrsf -> Bool -> Acquire (Ptr Shape)
BRepBuilderAPI.GTransform.gtransform (Ptr Wire -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
upcast Ptr Wire
path) Ptr GTrsf
trsf Bool
True 
        Maybe (Ptr GTrsf)
Nothing -> Ptr Wire -> Acquire (Ptr Wire)
forall a. a -> Acquire a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Ptr Wire
path
fromGTrsfPath V3 Double -> V3 Double
f Acquire (Maybe (Ptr GTrsf))
_ (Path (SinglePointRawPath V3 Double
v)) = RawPath -> Path
Path (RawPath -> Path) -> (V3 Double -> RawPath) -> V3 Double -> Path
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V3 Double -> RawPath
SinglePointRawPath (V3 Double -> RawPath)
-> (V3 Double -> V3 Double) -> V3 Double -> RawPath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V3 Double -> V3 Double
f (V3 Double -> Path) -> V3 Double -> Path
forall a b. (a -> b) -> a -> b
$ V3 Double
v
fromGTrsfPath V3 Double -> V3 Double
_ Acquire (Maybe (Ptr GTrsf))
_ (Path RawPath
EmptyRawPath) = RawPath -> Path
Path RawPath
EmptyRawPath


scaleTrsf :: V3 Double -> Acquire (Maybe (Ptr GP.GTrsf))
scaleTrsf :: V3 Double -> Acquire (Maybe (Ptr GTrsf))
scaleTrsf v :: V3 Double
v@(V3 Double
x Double
y Double
z ) = 
    if V3 Double
v V3 Double -> V3 Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double -> Double -> Double -> V3 Double
forall a. a -> a -> a -> V3 a
V3 Double
1 Double
1 Double
1 
        then Maybe (Ptr GTrsf) -> Acquire (Maybe (Ptr GTrsf))
forall a. a -> Acquire a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Ptr GTrsf)
forall a. Maybe a
Nothing
        else do
            Ptr GTrsf
trsf <- Acquire (Ptr GTrsf)
GP.GTrsf.new 
            IO (Maybe (Ptr GTrsf)) -> Acquire (Maybe (Ptr GTrsf))
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe (Ptr GTrsf)) -> Acquire (Maybe (Ptr GTrsf)))
-> IO (Maybe (Ptr GTrsf)) -> Acquire (Maybe (Ptr GTrsf))
forall a b. (a -> b) -> a -> b
$ do
                Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
1 Int
1 Double
x
                Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
2 Int
2 Double
y
                Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
3 Int
3 Double
z
                Ptr GTrsf -> IO ()
GP.GTrsf.setForm Ptr GTrsf
trsf
                Maybe (Ptr GTrsf) -> IO (Maybe (Ptr GTrsf))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Ptr GTrsf) -> IO (Maybe (Ptr GTrsf)))
-> (Ptr GTrsf -> Maybe (Ptr GTrsf))
-> Ptr GTrsf
-> IO (Maybe (Ptr GTrsf))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr GTrsf -> Maybe (Ptr GTrsf)
forall a. a -> Maybe a
Just (Ptr GTrsf -> IO (Maybe (Ptr GTrsf)))
-> Ptr GTrsf -> IO (Maybe (Ptr GTrsf))
forall a b. (a -> b) -> a -> b
$ Ptr GTrsf
trsf

uScaleTrsf :: Double -> Acquire (Ptr GP.Trsf)
uScaleTrsf :: Double -> Acquire (Ptr Trsf)
uScaleTrsf Double
factor = do
    Ptr Trsf
trsf <- Acquire (Ptr Trsf)
GP.Trsf.new
    Ptr Pnt
o <- Acquire (Ptr Pnt)
GP.origin
    IO () -> Acquire ()
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Acquire ()) -> IO () -> Acquire ()
forall a b. (a -> b) -> a -> b
$ Ptr Trsf -> Ptr Pnt -> Double -> IO ()
GP.Trsf.setScale Ptr Trsf
trsf Ptr Pnt
o Double
factor 
    Ptr Trsf -> Acquire (Ptr Trsf)
forall a. a -> Acquire a
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr Trsf
trsf

rotateTrsf :: V3 Double -> Double -> Acquire (Ptr GP.Trsf)
rotateTrsf :: V3 Double -> Double -> Acquire (Ptr Trsf)
rotateTrsf (V3 Double
ax Double
ay Double
az) Double
angle = do
    Ptr Trsf
trsf <- Acquire (Ptr Trsf)
GP.Trsf.new
    Ptr Pnt
o <- Acquire (Ptr Pnt)
GP.origin
    Ptr Dir
dir <- Double -> Double -> Double -> Acquire (Ptr Dir)
GP.Dir.new Double
ax Double
ay Double
az
    Ptr Ax1
axis <- Ptr Pnt -> Ptr Dir -> Acquire (Ptr Ax1)
GP.Ax1.new Ptr Pnt
o Ptr Dir
dir
    IO () -> Acquire ()
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Acquire ()) -> IO () -> Acquire ()
forall a b. (a -> b) -> a -> b
$ Ptr Trsf -> Ptr Ax1 -> Double -> IO ()
GP.Trsf.setRotationAboutAxisAngle Ptr Trsf
trsf Ptr Ax1
axis Double
angle
    Ptr Trsf -> Acquire (Ptr Trsf)
forall a. a -> Acquire a
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr Trsf
trsf

translateTrsf :: V3 Double -> Acquire (Ptr GP.Trsf)
translateTrsf :: V3 Double -> Acquire (Ptr Trsf)
translateTrsf (V3 Double
x Double
y Double
z) = do
    Ptr Trsf
trsf <- Acquire (Ptr Trsf)
GP.Trsf.new
    Ptr Vec
vec <- Double -> Double -> Double -> Acquire (Ptr Vec)
GP.Vec.new Double
x Double
y Double
z
    IO () -> Acquire ()
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Acquire ()) -> IO () -> Acquire ()
forall a b. (a -> b) -> a -> b
$ Ptr Trsf -> Ptr Vec -> IO ()
GP.Trsf.setTranslation Ptr Trsf
trsf Ptr Vec
vec
    Ptr Trsf -> Acquire (Ptr Trsf)
forall a. a -> Acquire a
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr Trsf
trsf

mirrorTrsf :: V3 Double -> Acquire (Ptr GP.Trsf)
mirrorTrsf :: V3 Double -> Acquire (Ptr Trsf)
mirrorTrsf (V3 Double
x Double
y Double
z) = do
    Ptr Trsf
trsf <- Acquire (Ptr Trsf)
GP.Trsf.new
    Ptr Dir
dir <- Double -> Double -> Double -> Acquire (Ptr Dir)
GP.Dir.new Double
x Double
y Double
z
    Ptr Ax2
axis <- Acquire (Ptr Ax2)
GP.xoy
    IO () -> Acquire ()
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Acquire ()) -> IO () -> Acquire ()
forall a b. (a -> b) -> a -> b
$ do 
        Ptr Ax2 -> Ptr Dir -> IO ()
GP.Ax2.setDirection Ptr Ax2
axis Ptr Dir
dir
        Ptr Trsf -> Ptr Ax2 -> IO ()
GP.Trsf.setMirrorAboutAx2 Ptr Trsf
trsf Ptr Ax2
axis
    Ptr Trsf -> Acquire (Ptr Trsf)
forall a. a -> Acquire a
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr Trsf
trsf

matrixGTrsf :: M34 Double -> Acquire (Maybe (Ptr GP.GTrsf))
matrixGTrsf :: M34 Double -> Acquire (Maybe (Ptr GTrsf))
matrixGTrsf (V3 (V4 Double
1 Double
0 Double
0 Double
0) (V4 Double
0 Double
1 Double
0 Double
0) (V4 Double
0 Double
0 Double
1 Double
0)) = Maybe (Ptr GTrsf) -> Acquire (Maybe (Ptr GTrsf))
forall a. a -> Acquire a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Ptr GTrsf)
forall a. Maybe a
Nothing
matrixGTrsf (V3 (V4 Double
v11 Double
v12 Double
v13 Double
v14) (V4 Double
v21 Double
v22 Double
v23 Double
v24) (V4 Double
v31 Double
v32 Double
v33 Double
v34)) = do
    Ptr GTrsf
trsf <- Acquire (Ptr GTrsf)
GP.GTrsf.new
    IO (Maybe (Ptr GTrsf)) -> Acquire (Maybe (Ptr GTrsf))
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe (Ptr GTrsf)) -> Acquire (Maybe (Ptr GTrsf)))
-> IO (Maybe (Ptr GTrsf)) -> Acquire (Maybe (Ptr GTrsf))
forall a b. (a -> b) -> a -> b
$ do  
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
1 Int
1 Double
v11
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
1 Int
2 Double
v12
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
1 Int
3 Double
v13
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
1 Int
4 Double
v14
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
2 Int
1 Double
v21
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
2 Int
2 Double
v22
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
2 Int
3 Double
v23
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
2 Int
4 Double
v24
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
3 Int
1 Double
v31
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
3 Int
2 Double
v32
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
3 Int
3 Double
v33
        Ptr GTrsf -> Int -> Int -> Double -> IO ()
GP.GTrsf.setValue Ptr GTrsf
trsf Int
3 Int
4 Double
v34
        Ptr GTrsf -> IO ()
GP.GTrsf.setForm Ptr GTrsf
trsf
        Maybe (Ptr GTrsf) -> IO (Maybe (Ptr GTrsf))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Ptr GTrsf) -> IO (Maybe (Ptr GTrsf)))
-> (Ptr GTrsf -> Maybe (Ptr GTrsf))
-> Ptr GTrsf
-> IO (Maybe (Ptr GTrsf))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr GTrsf -> Maybe (Ptr GTrsf)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ptr GTrsf -> IO (Maybe (Ptr GTrsf)))
-> Ptr GTrsf -> IO (Maybe (Ptr GTrsf))
forall a b. (a -> b) -> a -> b
$ Ptr GTrsf
trsf
    
instance Transformable Solid where
    matTransform :: M34 Double -> Solid -> Solid
    matTransform :: M34 Double -> Solid -> Solid
matTransform = Acquire (Maybe (Ptr GTrsf)) -> Solid -> Solid
fromGTrsfSolid (Acquire (Maybe (Ptr GTrsf)) -> Solid -> Solid)
-> (M34 Double -> Acquire (Maybe (Ptr GTrsf)))
-> M34 Double
-> Solid
-> Solid
forall b c a. (b -> c) -> (a -> b) -> a -> c
. M34 Double -> Acquire (Maybe (Ptr GTrsf))
matrixGTrsf 
    
    scale :: V3 Double -> Solid -> Solid
    scale :: V3 Double -> Solid -> Solid
scale = Acquire (Maybe (Ptr GTrsf)) -> Solid -> Solid
fromGTrsfSolid (Acquire (Maybe (Ptr GTrsf)) -> Solid -> Solid)
-> (V3 Double -> Acquire (Maybe (Ptr GTrsf)))
-> V3 Double
-> Solid
-> Solid
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V3 Double -> Acquire (Maybe (Ptr GTrsf))
scaleTrsf

    uScale :: Double -> Solid -> Solid
    uScale :: Double -> Solid -> Solid
uScale = Acquire (Ptr Trsf) -> Solid -> Solid
fromTrsfSolid (Acquire (Ptr Trsf) -> Solid -> Solid)
-> (Double -> Acquire (Ptr Trsf)) -> Double -> Solid -> Solid
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Acquire (Ptr Trsf)
uScaleTrsf

    rotate :: V3 Double -> Double -> Solid -> Solid
    rotate :: V3 Double -> Double -> Solid -> Solid
rotate V3 Double
axis Double
angle = Acquire (Ptr Trsf) -> Solid -> Solid
fromTrsfSolid (V3 Double -> Double -> Acquire (Ptr Trsf)
rotateTrsf V3 Double
axis Double
angle)

    translate :: V3 Double -> Solid -> Solid
    translate :: V3 Double -> Solid -> Solid
translate = Acquire (Ptr Trsf) -> Solid -> Solid
fromTrsfSolid (Acquire (Ptr Trsf) -> Solid -> Solid)
-> (V3 Double -> Acquire (Ptr Trsf)) -> V3 Double -> Solid -> Solid
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V3 Double -> Acquire (Ptr Trsf)
translateTrsf

    mirror :: V3 Double -> Solid -> Solid
    mirror :: V3 Double -> Solid -> Solid
mirror = Acquire (Ptr Trsf) -> Solid -> Solid
fromTrsfSolid (Acquire (Ptr Trsf) -> Solid -> Solid)
-> (V3 Double -> Acquire (Ptr Trsf)) -> V3 Double -> Solid -> Solid
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V3 Double -> Acquire (Ptr Trsf)
mirrorTrsf

instance Transformable Path where
    matTransform :: M34 Double -> Path -> Path
    matTransform :: M34 Double -> Path -> Path
matTransform M34 Double
m = (V3 Double -> V3 Double)
-> Acquire (Maybe (Ptr GTrsf)) -> Path -> Path
fromGTrsfPath (M34 Double -> V3 Double -> V3 Double
forall a. Transformable a => M34 Double -> a -> a
matTransform M34 Double
m) (M34 Double -> Acquire (Maybe (Ptr GTrsf))
matrixGTrsf M34 Double
m)
    
    scale :: V3 Double -> Path -> Path
    scale :: V3 Double -> Path -> Path
scale V3 Double
s = (V3 Double -> V3 Double)
-> Acquire (Maybe (Ptr GTrsf)) -> Path -> Path
fromGTrsfPath (V3 Double -> V3 Double -> V3 Double
forall a. Transformable a => V3 Double -> a -> a
scale V3 Double
s) (V3 Double -> Acquire (Maybe (Ptr GTrsf))
scaleTrsf V3 Double
s)

    uScale :: Double -> Path -> Path
    uScale :: Double -> Path -> Path
uScale Double
s = (V3 Double -> V3 Double) -> Acquire (Ptr Trsf) -> Path -> Path
fromTrsfPath (Double -> V3 Double -> V3 Double
forall a. Transformable a => Double -> a -> a
uScale Double
s) (Double -> Acquire (Ptr Trsf)
uScaleTrsf Double
s)

    rotate :: V3 Double -> Double -> Path -> Path
    rotate :: V3 Double -> Double -> Path -> Path
rotate V3 Double
axis Double
angle = (V3 Double -> V3 Double) -> Acquire (Ptr Trsf) -> Path -> Path
fromTrsfPath (V3 Double -> Double -> V3 Double -> V3 Double
forall a. Transformable a => V3 Double -> Double -> a -> a
rotate V3 Double
axis Double
angle) (V3 Double -> Double -> Acquire (Ptr Trsf)
rotateTrsf V3 Double
axis Double
angle)

    translate :: V3 Double -> Path -> Path
    translate :: V3 Double -> Path -> Path
translate V3 Double
v = (V3 Double -> V3 Double) -> Acquire (Ptr Trsf) -> Path -> Path
fromTrsfPath (V3 Double -> V3 Double -> V3 Double
forall a. Transformable a => V3 Double -> a -> a
translate V3 Double
v) (V3 Double -> Acquire (Ptr Trsf)
translateTrsf V3 Double
v)
    
    mirror :: V3 Double -> Path -> Path
    mirror :: V3 Double -> Path -> Path
mirror V3 Double
v = (V3 Double -> V3 Double) -> Acquire (Ptr Trsf) -> Path -> Path
fromTrsfPath (V3 Double -> V3 Double -> V3 Double
forall a. Transformable a => V3 Double -> a -> a
mirror V3 Double
v) (V3 Double -> Acquire (Ptr Trsf)
mirrorTrsf V3 Double
v)

instance Transformable (V3 Double) where
    matTransform :: M34 Double -> V3 Double -> V3 Double
    matTransform :: M34 Double -> V3 Double -> V3 Double
matTransform M34 Double
m V3 Double
v = M34 Double
m M34 Double -> V4 Double -> V3 Double
forall (m :: * -> *) (r :: * -> *) a.
(Functor m, Foldable r, Additive r, Num a) =>
m (r a) -> r a -> m a
!* (ASetter' (V4 Double) Double -> V4 Double
forall (t :: * -> *) a.
(Additive t, Num a) =>
ASetter' (t a) a -> t a
unit ASetter' (V4 Double) Double
forall a. Lens' (V4 a) a
forall (t :: * -> *) a. R4 t => Lens' (t a) a
_w V4 Double -> (V4 Double -> V4 Double) -> V4 Double
forall a b. a -> (a -> b) -> b
& (V3 Double -> Identity (V3 Double))
-> V4 Double -> Identity (V4 Double)
forall a. Lens' (V4 a) (V3 a)
forall (t :: * -> *) a. R3 t => Lens' (t a) (V3 a)
_xyz ((V3 Double -> Identity (V3 Double))
 -> V4 Double -> Identity (V4 Double))
-> V3 Double -> V4 Double -> V4 Double
forall s t a b. ASetter s t a b -> b -> s -> t
.~ V3 Double
v)

    scale :: V3 Double -> V3 Double  -> V3 Double
    scale :: V3 Double -> V3 Double -> V3 Double
scale = V3 Double -> V3 Double -> V3 Double
forall a. Num a => a -> a -> a
(*)

    -- Uniform Scale
    uScale :: Double -> V3 Double -> V3 Double
    uScale :: Double -> V3 Double -> V3 Double
uScale = Double -> V3 Double -> V3 Double
forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
(*^)

    rotate :: V3 Double -> Double -> V3 Double -> V3 Double 
    rotate :: V3 Double -> Double -> V3 Double -> V3 Double
rotate V3 Double
axis Double
angle = Quaternion Double -> V3 Double -> V3 Double
forall a.
(Conjugate a, RealFloat a) =>
Quaternion a -> V3 a -> V3 a
Quaternion.rotate (V3 Double -> Double -> Quaternion Double
forall a. (Epsilon a, Floating a) => V3 a -> a -> Quaternion a
Quaternion.axisAngle V3 Double
axis Double
angle)

    translate :: V3 Double -> V3 Double -> V3 Double 
    translate :: V3 Double -> V3 Double -> V3 Double
translate = V3 Double -> V3 Double -> V3 Double
forall a. Num a => a -> a -> a
(+)

    mirror :: V3 Double -> V3 Double -> V3 Double 
    mirror :: V3 Double -> V3 Double -> V3 Double
mirror V3 Double
mirrorVec V3 Double
toMirror = 
        let nm :: V3 Double
nm = V3 Double -> V3 Double
forall a (f :: * -> *).
(Floating a, Metric f, Epsilon a) =>
f a -> f a
normalize V3 Double
mirrorVec
        in V3 Double
toMirror V3 Double -> V3 Double -> V3 Double
forall a. Num a => a -> a -> a
- (Double
2 Double -> Double -> Double
forall a. Num a => a -> a -> a
* (V3 Double
nm V3 Double -> V3 Double -> Double
forall a. Num a => V3 a -> V3 a -> a
forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
`dot` V3 Double
toMirror) Double -> V3 Double -> V3 Double
forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ V3 Double
nm)