module Waterfall.Solids
( Solid
, emptySolid
, unitCube
, centeredCube
, box
, unitSphere
, unitCylinder
, centeredCylinder
, unitCone
, torus
, tetrahedron
, octahedron
, dodecahedron
, icosahedron
, prism
, volume
, centerOfMass
, momentOfInertia
) where
import Waterfall.Internal.Solid (Solid (..), solidFromAcquire, acquireSolid, emptySolid)
import Waterfall.Internal.Finalizers (toAcquire, unsafeFromAcquire)
import Waterfall.TwoD.Internal.Shape (rawShape)
import Waterfall.Internal.ToOpenCascade (v3ToVertex)
import Waterfall.Internal.FromOpenCascade (gpPntToV3)
import Waterfall.Internal.Remesh (makeSolidFromShell)
import Waterfall.Transforms (translate, rotate)
import qualified Waterfall.TwoD.Shape as TwoD.Shape
import qualified OpenCascade.BRepBuilderAPI.MakeShape as MakeShape
import qualified OpenCascade.BRepBuilderAPI.MakeEdge as MakeEdge
import qualified OpenCascade.BRepBuilderAPI.MakeWire as MakeWire
import qualified OpenCascade.BRepBuilderAPI.MakeFace as MakeFace
import qualified OpenCascade.BRepBuilderAPI.Sewing as BRepBuilderAPI.Sewing
import qualified OpenCascade.TopoDS as TopoDS
import qualified OpenCascade.TopoDS.Compound as TopoDS.Compound
import qualified OpenCascade.TopoDS.Builder as TopoDS.Builder
import qualified OpenCascade.BRepPrimAPI.MakeBox as MakeBox
import qualified OpenCascade.BRepPrimAPI.MakeSphere as MakeSphere
import qualified OpenCascade.BRepPrimAPI.MakeCylinder as MakeCylinder
import qualified OpenCascade.BRepPrimAPI.MakeCone as MakeCone
import qualified OpenCascade.BRepPrimAPI.MakeTorus as MakeTorus
import qualified OpenCascade.GProp.GProps as GProps
import qualified OpenCascade.BRepGProp as BRepGProp
import qualified OpenCascade.GP as GP
import Control.Lens ((^.), (&), (.~))
import Linear (V3 (..), V2 (..), unit, _x, _y, _z, _xy, _yz, _zx, (^*), (*^), unangle, zero)
import qualified OpenCascade.GP.Pnt as GP.Pnt
import qualified OpenCascade.GP.Vec as GP.Vec
import qualified OpenCascade.GP.Dir as GP.Dir
import qualified OpenCascade.GP.Ax1 as GP.Ax1
import qualified OpenCascade.BRepPrimAPI.MakePrism as MakePrism
import qualified OpenCascade.Inheritance as Inheritance
import Control.Monad.IO.Class (liftIO)
import Control.Monad ((<=<))
import Foreign.Ptr (Ptr)
import Data.Acquire (Acquire)
unitCube :: Solid
unitCube :: Solid
unitCube = Acquire (Ptr Shape) -> Solid
solidFromAcquire (Acquire (Ptr Shape) -> Solid) -> Acquire (Ptr Shape) -> Solid
forall a b. (a -> b) -> a -> b
$ do
Ptr Pnt
a <- Acquire (Ptr Pnt)
GP.origin
Ptr Pnt
b <- Double -> Double -> Double -> Acquire (Ptr Pnt)
GP.Pnt.new Double
1 Double
1 Double
1
Ptr MakeBox
builder <- Ptr Pnt -> Ptr Pnt -> Acquire (Ptr MakeBox)
MakeBox.fromPnts Ptr Pnt
a Ptr Pnt
b
Ptr Solid -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
Inheritance.upcast (Ptr Solid -> Ptr Shape)
-> Acquire (Ptr Solid) -> Acquire (Ptr Shape)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr MakeBox -> Acquire (Ptr Solid)
MakeBox.solid Ptr MakeBox
builder
centeredCube :: Solid
centeredCube :: Solid
centeredCube = Acquire (Ptr Shape) -> Solid
solidFromAcquire (Acquire (Ptr Shape) -> Solid) -> Acquire (Ptr Shape) -> Solid
forall a b. (a -> b) -> a -> b
$ do
Ptr Pnt
a <- Double -> Double -> Double -> Acquire (Ptr Pnt)
GP.Pnt.new (-Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (-Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (-Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2)
Ptr Pnt
b <- Double -> Double -> Double -> Acquire (Ptr Pnt)
GP.Pnt.new (Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2)
Ptr MakeBox
builder <- Ptr Pnt -> Ptr Pnt -> Acquire (Ptr MakeBox)
MakeBox.fromPnts Ptr Pnt
a Ptr Pnt
b
Ptr Solid -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
Inheritance.upcast (Ptr Solid -> Ptr Shape)
-> Acquire (Ptr Solid) -> Acquire (Ptr Shape)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr MakeBox -> Acquire (Ptr Solid)
MakeBox.solid Ptr MakeBox
builder
box :: V3 Double -> Solid
box :: V3 Double -> Solid
box (V3 Double
x Double
y Double
z) = Acquire (Ptr Shape) -> Solid
solidFromAcquire (Acquire (Ptr Shape) -> Solid) -> Acquire (Ptr Shape) -> Solid
forall a b. (a -> b) -> a -> b
$ do
Ptr Pnt
a <- Acquire (Ptr Pnt)
GP.origin
Ptr Pnt
b <- Double -> Double -> Double -> Acquire (Ptr Pnt)
GP.Pnt.new Double
x Double
y Double
z
Ptr MakeBox
builder <- Ptr Pnt -> Ptr Pnt -> Acquire (Ptr MakeBox)
MakeBox.fromPnts Ptr Pnt
a Ptr Pnt
b
Ptr Solid -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
Inheritance.upcast (Ptr Solid -> Ptr Shape)
-> Acquire (Ptr Solid) -> Acquire (Ptr Shape)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr MakeBox -> Acquire (Ptr Solid)
MakeBox.solid Ptr MakeBox
builder
unitSphere :: Solid
unitSphere :: Solid
unitSphere = Acquire (Ptr Shape) -> Solid
solidFromAcquire (Acquire (Ptr Shape) -> Solid) -> Acquire (Ptr Shape) -> Solid
forall a b. (a -> b) -> a -> b
$ Ptr Solid -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
Inheritance.upcast (Ptr Solid -> Ptr Shape)
-> Acquire (Ptr Solid) -> Acquire (Ptr Shape)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Double -> Acquire (Ptr Solid)
MakeSphere.fromRadius Double
1
unitCylinder :: Solid
unitCylinder :: Solid
unitCylinder = Acquire (Ptr Shape) -> Solid
solidFromAcquire (Acquire (Ptr Shape) -> Solid) -> Acquire (Ptr Shape) -> Solid
forall a b. (a -> b) -> a -> b
$ Ptr Solid -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
Inheritance.upcast (Ptr Solid -> Ptr Shape)
-> Acquire (Ptr Solid) -> Acquire (Ptr Shape)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Double -> Double -> Acquire (Ptr Solid)
MakeCylinder.fromRadiusAndHeight Double
1 Double
1
centeredCylinder :: Solid
centeredCylinder :: Solid
centeredCylinder = V3 Double -> Solid -> Solid
forall a. Transformable a => V3 Double -> a -> a
translate (ASetter' (V3 Double) Double -> V3 Double
forall (t :: * -> *) a.
(Additive t, Num a) =>
ASetter' (t a) a -> t a
unit ASetter' (V3 Double) Double
forall a. Lens' (V3 a) a
forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z V3 Double -> Double -> V3 Double
forall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^* (-Double
0.5)) (Solid -> Solid) -> Solid -> Solid
forall a b. (a -> b) -> a -> b
$ Solid
unitCylinder
torus ::
Double
-> Double
-> Solid
torus :: Double -> Double -> Solid
torus Double
major Double
minor =
Acquire (Ptr Shape) -> Solid
solidFromAcquire
(Acquire (Ptr Shape) -> Solid) -> Acquire (Ptr Shape) -> Solid
forall a b. (a -> b) -> a -> b
$ Ptr MakeShape -> Acquire (Ptr Shape)
MakeShape.shape
(Ptr MakeShape -> Acquire (Ptr Shape))
-> (Ptr MakeTorus -> Ptr MakeShape)
-> Ptr MakeTorus
-> Acquire (Ptr Shape)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr MakeTorus -> Ptr MakeShape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
Inheritance.upcast
(Ptr MakeTorus -> Acquire (Ptr Shape))
-> Acquire (Ptr MakeTorus) -> Acquire (Ptr Shape)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Double -> Double -> Acquire (Ptr MakeTorus)
MakeTorus.fromRadii Double
major Double
minor
unitCone :: Solid
unitCone :: Solid
unitCone = Acquire (Ptr Shape) -> Solid
solidFromAcquire (Acquire (Ptr Shape) -> Solid) -> Acquire (Ptr Shape) -> Solid
forall a b. (a -> b) -> a -> b
$ Ptr Solid -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
Inheritance.upcast (Ptr Solid -> Ptr Shape)
-> Acquire (Ptr Solid) -> Acquire (Ptr Shape)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Double -> Double -> Double -> Acquire (Ptr Solid)
MakeCone.fromTwoRadiiAndHeight Double
0 Double
1 Double
1
prism :: Double -> TwoD.Shape.Shape -> Solid
prism :: Double -> Shape -> Solid
prism Double
len Shape
face = Acquire (Ptr Shape) -> Solid
solidFromAcquire (Acquire (Ptr Shape) -> Solid) -> Acquire (Ptr Shape) -> Solid
forall a b. (a -> b) -> a -> b
$ do
Ptr Shape
p <- Ptr Shape -> Acquire (Ptr Shape)
forall a. a -> Acquire a
toAcquire (Ptr Shape -> Acquire (Ptr Shape))
-> (Shape -> Ptr Shape) -> Shape -> Acquire (Ptr Shape)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Shape -> Ptr Shape
rawShape (Shape -> Acquire (Ptr Shape)) -> Shape -> Acquire (Ptr Shape)
forall a b. (a -> b) -> a -> b
$ Shape
face
Ptr Vec
v <- Double -> Double -> Double -> Acquire (Ptr Vec)
GP.Vec.new Double
0 Double
0 Double
len
Ptr Shape -> Ptr Vec -> Bool -> Bool -> Acquire (Ptr Shape)
MakePrism.fromVec Ptr Shape
p Ptr Vec
v Bool
True Bool
True
faceFromVerts :: [V3 Double] -> Acquire (Ptr TopoDS.Face)
faceFromVerts :: [V3 Double] -> Acquire (Ptr Face)
faceFromVerts [V3 Double]
pnts = do
[Ptr Vertex]
verts <- (V3 Double -> Acquire (Ptr Vertex))
-> [V3 Double] -> Acquire [Ptr Vertex]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse V3 Double -> Acquire (Ptr Vertex)
v3ToVertex [V3 Double]
pnts
[Ptr Edge]
edges <- ((Ptr Vertex, Ptr Vertex) -> Acquire (Ptr Edge))
-> [(Ptr Vertex, Ptr Vertex)] -> Acquire [Ptr Edge]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Ptr Vertex -> Ptr Vertex -> Acquire (Ptr Edge))
-> (Ptr Vertex, Ptr Vertex) -> Acquire (Ptr Edge)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Ptr Vertex -> Ptr Vertex -> Acquire (Ptr Edge)
MakeEdge.fromVertices) ([(Ptr Vertex, Ptr Vertex)] -> Acquire [Ptr Edge])
-> [(Ptr Vertex, Ptr Vertex)] -> Acquire [Ptr Edge]
forall a b. (a -> b) -> a -> b
$ [Ptr Vertex] -> [Ptr Vertex] -> [(Ptr Vertex, Ptr Vertex)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Ptr Vertex]
verts (Int -> [Ptr Vertex] -> [Ptr Vertex]
forall a. Int -> [a] -> [a]
drop Int
1 ([Ptr Vertex] -> [Ptr Vertex]
forall a. HasCallStack => [a] -> [a]
cycle [Ptr Vertex]
verts))
Ptr MakeWire
wireBuilder <- Acquire (Ptr MakeWire)
MakeWire.new
[()]
_ <- 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 Edge -> IO ()) -> [Ptr Edge] -> IO [()]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (Ptr MakeWire -> Ptr Edge -> IO ()
MakeWire.addEdge Ptr MakeWire
wireBuilder) [Ptr Edge]
edges
Ptr Wire
wire <- Ptr MakeWire -> Acquire (Ptr Wire)
MakeWire.wire Ptr MakeWire
wireBuilder
Ptr MakeFace
faceBuilder <- Ptr Wire -> Bool -> Acquire (Ptr MakeFace)
MakeFace.fromWire Ptr Wire
wire Bool
True
Ptr MakeFace -> Acquire (Ptr Face)
MakeFace.face Ptr MakeFace
faceBuilder
solidFromFaces :: [Ptr TopoDS.Face] -> Acquire (Ptr TopoDS.Solid)
solidFromFaces :: [Ptr Face] -> Acquire (Ptr Solid)
solidFromFaces [Ptr Face]
faces = do
Ptr Sewing
sewing <- Double -> Bool -> Bool -> Bool -> Bool -> Acquire (Ptr Sewing)
BRepBuilderAPI.Sewing.new Double
1e-6 Bool
True Bool
True Bool
True Bool
False
Ptr Compound
compound <- Acquire (Ptr Compound)
TopoDS.Compound.new
Ptr Builder
builder <- Acquire (Ptr Builder)
TopoDS.Builder.new
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 Builder -> Ptr Compound -> IO ()
TopoDS.Builder.makeCompound Ptr Builder
builder Ptr Compound
compound
[()]
_ <- 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 Face -> IO ()) -> [Ptr Face] -> IO [()]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (Ptr Builder -> Ptr Shape -> Ptr Shape -> IO ()
TopoDS.Builder.add Ptr Builder
builder (Ptr Compound -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
Inheritance.upcast Ptr Compound
compound) (Ptr Shape -> IO ())
-> (Ptr Face -> Ptr Shape) -> Ptr Face -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Face -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
Inheritance.upcast) [Ptr Face]
faces
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 Sewing -> Ptr Shape -> IO ()
BRepBuilderAPI.Sewing.load Ptr Sewing
sewing (Ptr Compound -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
Inheritance.upcast Ptr Compound
compound)
IO () -> Acquire ()
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Acquire ())
-> (Ptr Sewing -> IO ()) -> Ptr Sewing -> Acquire ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Sewing -> IO ()
BRepBuilderAPI.Sewing.perform (Ptr Sewing -> Acquire ()) -> Ptr Sewing -> Acquire ()
forall a b. (a -> b) -> a -> b
$ Ptr Sewing
sewing
Ptr Shape
shape <- Ptr Sewing -> Acquire (Ptr Shape)
BRepBuilderAPI.Sewing.sewedShape Ptr Sewing
sewing
Maybe (Ptr Solid)
maybeShapeAsSolid <- Ptr Shape -> Acquire (Maybe (Ptr Solid))
makeSolidFromShell Ptr Shape
shape
case Maybe (Ptr Solid)
maybeShapeAsSolid of
Just Ptr Solid
s -> Ptr Solid -> Acquire (Ptr Solid)
forall a. a -> Acquire a
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr Solid
s
Maybe (Ptr Solid)
Nothing -> [Char] -> Acquire (Ptr Solid)
forall a. HasCallStack => [Char] -> a
error [Char]
"Failed to construct solid from faces"
solidFromVerts :: [[V3 Double]] -> Solid
solidFromVerts :: [[V3 Double]] -> Solid
solidFromVerts = Acquire (Ptr Shape) -> Solid
solidFromAcquire (Acquire (Ptr Shape) -> Solid)
-> ([[V3 Double]] -> Acquire (Ptr Shape)) -> [[V3 Double]] -> Solid
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Ptr Solid -> Ptr Shape)
-> Acquire (Ptr Solid) -> Acquire (Ptr Shape)
forall a b. (a -> b) -> Acquire a -> Acquire b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Ptr Solid -> Ptr Shape
forall a b. SubTypeOf a b => Ptr b -> Ptr a
Inheritance.upcast (Acquire (Ptr Solid) -> Acquire (Ptr Shape))
-> ([[V3 Double]] -> Acquire (Ptr Solid))
-> [[V3 Double]]
-> Acquire (Ptr Shape)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Ptr Face] -> Acquire (Ptr Solid)
solidFromFaces ([Ptr Face] -> Acquire (Ptr Solid))
-> ([[V3 Double]] -> Acquire [Ptr Face])
-> [[V3 Double]]
-> Acquire (Ptr Solid)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ([V3 Double] -> Acquire (Ptr Face))
-> [[V3 Double]] -> Acquire [Ptr Face]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse [V3 Double] -> Acquire (Ptr Face)
faceFromVerts)
tetrahedron :: Solid
tetrahedron :: Solid
tetrahedron =
let r :: V3 Double -> V3 Double
r = ((Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double -> Double
forall a. Floating a => a -> a
sqrt Double
8) Double -> V3 Double -> V3 Double
forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^)
(V3 Double -> V3 Double)
-> (V3 Double -> V3 Double) -> V3 Double -> V3 Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V3 Double -> Double -> V3 Double -> V3 Double
forall a. Transformable a => V3 Double -> Double -> a -> a
rotate (ASetter' (V3 Double) Double -> V3 Double
forall (t :: * -> *) a.
(Additive t, Num a) =>
ASetter' (t a) a -> t a
unit ASetter' (V3 Double) Double
forall a. Lens' (V3 a) a
forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z) (Double
forall a. Floating a => a
piDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
4)
(V3 Double -> V3 Double)
-> (V3 Double -> V3 Double) -> V3 Double -> V3 Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V3 Double -> Double -> V3 Double -> V3 Double
forall a. Transformable a => V3 Double -> Double -> a -> a
rotate (Double -> Double -> Double -> V3 Double
forall a. a -> a -> a -> V3 a
V3 Double
1 Double
1 Double
0) (Double
forall a. Floating a => a
pi Double -> Double -> Double
forall a. Num a => a -> a -> a
- V2 Double -> Double
forall a. (Floating a, Ord a) => V2 a -> a
unangle (Double -> Double -> V2 Double
forall a. a -> a -> V2 a
V2 Double
1 (Double -> Double
forall a. Floating a => a -> a
sqrt Double
2)))
v1 :: V3 Double
v1 = Double -> Double -> Double -> V3 Double
forall a. a -> a -> a -> V3 a
V3 Double
1 Double
1 Double
1
v2 :: V3 Double
v2 = Double -> Double -> Double -> V3 Double
forall a. a -> a -> a -> V3 a
V3 Double
1 (-Double
1) (-Double
1)
v3 :: V3 Double
v3 = Double -> Double -> Double -> V3 Double
forall a. a -> a -> a -> V3 a
V3 (-Double
1) Double
1 (-Double
1)
v4 :: V3 Double
v4 = Double -> Double -> Double -> V3 Double
forall a. a -> a -> a -> V3 a
V3 (-Double
1) (-Double
1) Double
1
in [[V3 Double]] -> Solid
solidFromVerts ([[V3 Double]] -> Solid)
-> ([[V3 Double]] -> [[V3 Double]]) -> [[V3 Double]] -> Solid
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([V3 Double] -> [V3 Double]) -> [[V3 Double]] -> [[V3 Double]]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((V3 Double -> V3 Double) -> [V3 Double] -> [V3 Double]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap V3 Double -> V3 Double
r) ([[V3 Double]] -> Solid) -> [[V3 Double]] -> Solid
forall a b. (a -> b) -> a -> b
$
[ [V3 Double
v1, V3 Double
v2, V3 Double
v3]
, [V3 Double
v1 ,V3 Double
v2, V3 Double
v4]
, [V3 Double
v2, V3 Double
v3, V3 Double
v4]
, [V3 Double
v3, V3 Double
v1, V3 Double
v4]
]
octahedron :: Solid
octahedron :: Solid
octahedron =
let h :: Double
h = Double
1 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double -> Double
forall a. Floating a => a -> a
sqrt Double
2
t :: V3 Double
t = ASetter' (V3 Double) Double -> V3 Double
forall (t :: * -> *) a.
(Additive t, Num a) =>
ASetter' (t a) a -> t a
unit ASetter' (V3 Double) Double
forall a. Lens' (V3 a) a
forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z V3 Double -> Double -> V3 Double
forall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^* Double
h
b :: V3 Double
b = V3 Double -> V3 Double
forall a. Num a => a -> a
negate V3 Double
t
c1 :: V3 Double
c1 = Double
h Double -> V3 Double -> V3 Double
forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ ASetter' (V3 Double) Double -> V3 Double
forall (t :: * -> *) a.
(Additive t, Num a) =>
ASetter' (t a) a -> t a
unit ASetter' (V3 Double) Double
forall a. Lens' (V3 a) a
forall (t :: * -> *) a. R1 t => Lens' (t a) a
_x
c2 :: V3 Double
c2 = Double
h Double -> V3 Double -> V3 Double
forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ ASetter' (V3 Double) Double -> V3 Double
forall (t :: * -> *) a.
(Additive t, Num a) =>
ASetter' (t a) a -> t a
unit ASetter' (V3 Double) Double
forall a. Lens' (V3 a) a
forall (t :: * -> *) a. R2 t => Lens' (t a) a
_y
c3 :: V3 Double
c3 = V3 Double -> V3 Double
forall a. Num a => a -> a
negate V3 Double
c1
c4 :: V3 Double
c4 = V3 Double -> V3 Double
forall a. Num a => a -> a
negate V3 Double
c2
in [[V3 Double]] -> Solid
solidFromVerts
[ [V3 Double
t, V3 Double
c1, V3 Double
c2]
, [V3 Double
t, V3 Double
c2, V3 Double
c3]
, [V3 Double
t, V3 Double
c3, V3 Double
c4]
, [V3 Double
t, V3 Double
c4, V3 Double
c1]
, [V3 Double
b, V3 Double
c2, V3 Double
c1]
, [V3 Double
b, V3 Double
c3, V3 Double
c2]
, [V3 Double
b, V3 Double
c4, V3 Double
c3]
, [V3 Double
b, V3 Double
c1, V3 Double
c4]
]
icosahedron :: Solid
icosahedron :: Solid
icosahedron =
let phi :: Double
phi = (Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
forall a. Floating a => a -> a
sqrt Double
5) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
2
signs :: [Double]
signs = [-Double
1, Double
1]
in [[V3 Double]] -> Solid
solidFromVerts ([[V3 Double]] -> Solid) -> [[V3 Double]] -> Solid
forall a b. (a -> b) -> a -> b
$
[
let a :: V3 Double
a = V3 Double
forall a. Num a => V3 a
forall (f :: * -> *) a. (Additive f, Num a) => f a
zero V3 Double -> (V3 Double -> V3 Double) -> V3 Double
forall a b. a -> (a -> b) -> b
& (V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
l1 ((V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double))
-> V2 Double -> V3 Double -> V3 Double
forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Double -> Double -> V2 Double
forall a. a -> a -> V2 a
V2 (Double
s1 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
phiDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) Double
0.5)
b :: V3 Double
b = V3 Double
forall a. Num a => V3 a
forall (f :: * -> *) a. (Additive f, Num a) => f a
zero V3 Double -> (V3 Double -> V3 Double) -> V3 Double
forall a b. a -> (a -> b) -> b
& (V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
l1 ((V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double))
-> V2 Double -> V3 Double -> V3 Double
forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Double -> Double -> V2 Double
forall a. a -> a -> V2 a
V2 (Double
s1 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
phiDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (-Double
0.5))
c :: V3 Double
c = V3 Double
forall a. Num a => V3 a
forall (f :: * -> *) a. (Additive f, Num a) => f a
zero V3 Double -> (V3 Double -> V3 Double) -> V3 Double
forall a b. a -> (a -> b) -> b
& (V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
l2 ((V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double))
-> V2 Double -> V3 Double -> V3 Double
forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Double -> Double -> V2 Double
forall a. a -> a -> V2 a
V2 (Double
s2 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
phiDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (Double
0.5 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
s1))
in if Double
s1 Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
0 then [V3 Double
b, V3 Double
a, V3 Double
c]
else [V3 Double
a, V3 Double
b, V3 Double
c]
| Double
s1 <- [Double]
signs
, Double
s2 <- [Double]
signs
, ((V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
l1, (V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
l2) <- [((V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
forall a. Lens' (V3 a) (V2 a)
forall (t :: * -> *) a. R2 t => Lens' (t a) (V2 a)
_xy, (V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
Lens' (V3 Double) (V2 Double)
forall (t :: * -> *) a. R3 t => Lens' (t a) (V2 a)
_zx), ((V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
Lens' (V3 Double) (V2 Double)
forall (t :: * -> *) a. R3 t => Lens' (t a) (V2 a)
_zx, (V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
Lens' (V3 Double) (V2 Double)
forall (t :: * -> *) a. R3 t => Lens' (t a) (V2 a)
_yz), ((V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
Lens' (V3 Double) (V2 Double)
forall (t :: * -> *) a. R3 t => Lens' (t a) (V2 a)
_yz, (V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
forall a. Lens' (V3 a) (V2 a)
forall (t :: * -> *) a. R2 t => Lens' (t a) (V2 a)
_xy)]
] [[V3 Double]] -> [[V3 Double]] -> [[V3 Double]]
forall a. Semigroup a => a -> a -> a
<>
[
[ V3 Double
forall a. Num a => V3 a
forall (f :: * -> *) a. (Additive f, Num a) => f a
zero V3 Double -> (V3 Double -> V3 Double) -> V3 Double
forall a b. a -> (a -> b) -> b
& (V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
forall a. Lens' (V3 a) (V2 a)
forall (t :: * -> *) a. R2 t => Lens' (t a) (V2 a)
_xy ((V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double))
-> V2 Double -> V3 Double -> V3 Double
forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Double -> Double -> V2 Double
forall a. a -> a -> V2 a
V2 (Double
a Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
phiDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (Double
c Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
0.5))
, V3 Double
forall a. Num a => V3 a
forall (f :: * -> *) a. (Additive f, Num a) => f a
zero V3 Double -> (V3 Double -> V3 Double) -> V3 Double
forall a b. a -> (a -> b) -> b
& (V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
Lens' (V3 Double) (V2 Double)
forall (t :: * -> *) a. R3 t => Lens' (t a) (V2 a)
_yz ((V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double))
-> V2 Double -> V3 Double -> V3 Double
forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Double -> Double -> V2 Double
forall a. a -> a -> V2 a
V2 (Double
c Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
phiDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (Double
b Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
0.5))
, V3 Double
forall a. Num a => V3 a
forall (f :: * -> *) a. (Additive f, Num a) => f a
zero V3 Double -> (V3 Double -> V3 Double) -> V3 Double
forall a b. a -> (a -> b) -> b
& (V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double)
Lens' (V3 Double) (V2 Double)
forall (t :: * -> *) a. R3 t => Lens' (t a) (V2 a)
_zx ((V2 Double -> Identity (V2 Double))
-> V3 Double -> Identity (V3 Double))
-> V2 Double -> V3 Double -> V3 Double
forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Double -> Double -> V2 Double
forall a. a -> a -> V2 a
V2 (Double
b Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
phiDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (Double
a Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
0.5))
]
| Double
a <- [Double]
signs
, Double
b <- [Double]
signs
, Double
c <- [Double]
signs
]
dodecahedron :: Solid
dodecahedron :: Solid
dodecahedron =
let phi :: Double
phi = (Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
forall a. Floating a => a -> a
sqrt Double
5)Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2
plusMinusOne :: [Double]
plusMinusOne = [Double
1, -Double
1]
scale :: Double
scale = Double
phi Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
2
orange :: Double -> Double -> Double -> V3 Double
orange Double
x Double
y Double
z = Double
scale Double -> V3 Double -> V3 Double
forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ Double -> Double -> Double -> V3 Double
forall a. a -> a -> a -> V3 a
V3 Double
x Double
y Double
z
green :: Double -> Double -> V3 Double
green Double
y Double
z = Double
scale Double -> V3 Double -> V3 Double
forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ Double -> Double -> Double -> V3 Double
forall a. a -> a -> a -> V3 a
V3 Double
0 (Double
phi Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
y) (Double
z Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
phi)
blue :: Double -> Double -> V3 Double
blue Double
x Double
z = Double
scale Double -> V3 Double -> V3 Double
forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ Double -> Double -> Double -> V3 Double
forall a. a -> a -> a -> V3 a
V3 (Double
xDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
phi) Double
0 (Double
phi Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
z)
pink :: Double -> Double -> V3 Double
pink Double
x Double
y = Double
scale Double -> V3 Double -> V3 Double
forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ Double -> Double -> Double -> V3 Double
forall a. a -> a -> a -> V3 a
V3 (Double
phi Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
x) (Double
yDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
phi) Double
0
in [[V3 Double]] -> Solid
solidFromVerts ([[V3 Double]] -> Solid) -> [[V3 Double]] -> Solid
forall a b. (a -> b) -> a -> b
$
[ \Double
y Double
z -> [ Double -> Double -> V3 Double
blue (-Double
1) Double
z, Double -> Double -> V3 Double
blue (Double
1) Double
z, Double -> Double -> Double -> V3 Double
orange (Double
1) Double
y Double
z, Double -> Double -> V3 Double
green Double
y Double
z, Double -> Double -> Double -> V3 Double
orange (-Double
1) Double
y Double
z]
, \Double
x Double
y -> [ Double -> Double -> V3 Double
green Double
y (-Double
1), Double -> Double -> V3 Double
green Double
y Double
1, Double -> Double -> Double -> V3 Double
orange Double
x Double
y Double
1, Double -> Double -> V3 Double
pink Double
x Double
y, Double -> Double -> Double -> V3 Double
orange Double
x Double
y (-Double
1)]
, \Double
x Double
z -> [ Double -> Double -> V3 Double
pink Double
x (-Double
1), Double -> Double -> V3 Double
pink Double
x Double
1, Double -> Double -> Double -> V3 Double
orange Double
x Double
1 Double
z, Double -> Double -> V3 Double
blue Double
x Double
z, Double -> Double -> Double -> V3 Double
orange Double
x (-Double
1) Double
z]
] [Double -> Double -> [V3 Double]]
-> [Double] -> [Double -> [V3 Double]]
forall a b. [a -> b] -> [a] -> [b]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Double]
plusMinusOne [Double -> [V3 Double]] -> [Double] -> [[V3 Double]]
forall a b. [a -> b] -> [a] -> [b]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Double]
plusMinusOne
gPropQuery :: (Ptr GProps.GProps -> Acquire a) -> Solid -> a
gPropQuery :: forall a. (Ptr GProps -> Acquire a) -> Solid -> a
gPropQuery Ptr GProps -> Acquire a
f Solid
s = Acquire a -> a
forall a. Acquire a -> a
unsafeFromAcquire (Acquire a -> a) -> Acquire a -> a
forall a b. (a -> b) -> a -> b
$ do
Ptr Shape
solid <- Solid -> Acquire (Ptr Shape)
acquireSolid Solid
s
Ptr GProps
gProp <- Acquire (Ptr GProps)
GProps.new
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 Shape -> Ptr GProps -> Bool -> Bool -> Bool -> IO ()
BRepGProp.volumeProperties Ptr Shape
solid Ptr GProps
gProp Bool
False Bool
False Bool
False
Ptr GProps -> Acquire a
f Ptr GProps
gProp
volume :: Solid -> Double
volume :: Solid -> Double
volume = (Ptr GProps -> Acquire Double) -> Solid -> Double
forall a. (Ptr GProps -> Acquire a) -> Solid -> a
gPropQuery (IO Double -> Acquire Double
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Double -> Acquire Double)
-> (Ptr GProps -> IO Double) -> Ptr GProps -> Acquire Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr GProps -> IO Double
GProps.mass)
centerOfMass :: Solid -> V3 Double
centerOfMass :: Solid -> V3 Double
centerOfMass = (Ptr GProps -> Acquire (V3 Double)) -> Solid -> V3 Double
forall a. (Ptr GProps -> Acquire a) -> Solid -> a
gPropQuery ((IO (V3 Double) -> Acquire (V3 Double)
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (V3 Double) -> Acquire (V3 Double))
-> (Ptr Pnt -> IO (V3 Double)) -> Ptr Pnt -> Acquire (V3 Double)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Pnt -> IO (V3 Double)
gpPntToV3) (Ptr Pnt -> Acquire (V3 Double))
-> (Ptr GProps -> Acquire (Ptr Pnt))
-> Ptr GProps
-> Acquire (V3 Double)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Ptr GProps -> Acquire (Ptr Pnt)
GProps.centreOfMass)
momentOfInertia :: V3 Double
-> V3 Double
-> Solid
-> Double
momentOfInertia :: V3 Double -> V3 Double -> Solid -> Double
momentOfInertia V3 Double
center V3 Double
axis = (Ptr GProps -> Acquire Double) -> Solid -> Double
forall a. (Ptr GProps -> Acquire a) -> Solid -> a
gPropQuery ((Ptr GProps -> Acquire Double) -> Solid -> Double)
-> (Ptr GProps -> Acquire Double) -> Solid -> Double
forall a b. (a -> b) -> a -> b
$ \Ptr GProps
gprop -> do
Ptr Pnt
pnt <- Double -> Double -> Double -> Acquire (Ptr Pnt)
GP.Pnt.new (V3 Double
center V3 Double -> Getting Double (V3 Double) Double -> Double
forall s a. s -> Getting a s a -> a
^. Getting Double (V3 Double) Double
forall a. Lens' (V3 a) a
forall (t :: * -> *) a. R1 t => Lens' (t a) a
_x) (V3 Double
center V3 Double -> Getting Double (V3 Double) Double -> Double
forall s a. s -> Getting a s a -> a
^. Getting Double (V3 Double) Double
forall a. Lens' (V3 a) a
forall (t :: * -> *) a. R2 t => Lens' (t a) a
_y) (V3 Double
center V3 Double -> Getting Double (V3 Double) Double -> Double
forall s a. s -> Getting a s a -> a
^. Getting Double (V3 Double) Double
forall a. Lens' (V3 a) a
forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z)
Ptr Dir
dir <- Double -> Double -> Double -> Acquire (Ptr Dir)
GP.Dir.new (V3 Double
axis V3 Double -> Getting Double (V3 Double) Double -> Double
forall s a. s -> Getting a s a -> a
^. Getting Double (V3 Double) Double
forall a. Lens' (V3 a) a
forall (t :: * -> *) a. R1 t => Lens' (t a) a
_x) (V3 Double
axis V3 Double -> Getting Double (V3 Double) Double -> Double
forall s a. s -> Getting a s a -> a
^. Getting Double (V3 Double) Double
forall a. Lens' (V3 a) a
forall (t :: * -> *) a. R2 t => Lens' (t a) a
_y) (V3 Double
axis V3 Double -> Getting Double (V3 Double) Double -> Double
forall s a. s -> Getting a s a -> a
^. Getting Double (V3 Double) Double
forall a. Lens' (V3 a) a
forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z)
Ptr Ax1
ax1 <- Ptr Pnt -> Ptr Dir -> Acquire (Ptr Ax1)
GP.Ax1.new Ptr Pnt
pnt Ptr Dir
dir
IO Double -> Acquire Double
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Double -> Acquire Double) -> IO Double -> Acquire Double
forall a b. (a -> b) -> a -> b
$ Ptr GProps -> Ptr Ax1 -> IO Double
GProps.momentOfInertia Ptr GProps
gprop Ptr Ax1
ax1