-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Analytical CSG (Constructive Solid Geometry) library
--   
--   Analytical CSG (Constructive Solid Geometry) library
@package csg
@version 0.1.0.5


-- | Types and routines for constructive solid geometry.
--   
--   This module provides constructors for complex solids as well as
--   membership predicates and routines to compute intersections of such
--   solids with a ray.
module Data.CSG

-- | CSG solid is a recursive composition of primitive objects or other
--   solids.
data Solid

-- | A half-space defined by an arbitary point on the boundary plane and an
--   outward normal (not necessarily a unit vector).
plane :: Point -> Vec3 -> Solid

-- | A sphere defined by a center point and a radius.
sphere :: Vec3 -> Double -> Solid

-- | An infinite circular cylinder defined by two arbitary points on axis
--   and a radius.
cylinder :: Point -> Point -> Double -> Solid

-- | An infinite right circular cone defined by an outward axis vector, an
--   apex point and an angle between the generatrix and the axis (in
--   degrees, less than 90).
cone :: Vec3 -> Point -> Double -> Solid

-- | A rectangular cuboid with faces parallel to axes, defined by two
--   opposite vertices.
cuboid :: Point -> Point -> Solid

-- | A conical frustum defined by two points on its axis with radii at that
--   points. One of radii may be zero (in which case one of frustum ends
--   will be the apex).
coneFrustum :: (Point, Double) -> (Point, Double) -> Solid

-- | A finite right circular cylinder defined by two points on its top and
--   bottom and a radius.
cylinderFrustum :: Point -> Point -> Double -> Solid

-- | Intersection of two solids.
intersect :: Solid -> Solid -> Solid

-- | Union of two solids.
unite :: Solid -> Solid -> Solid

-- | Complement to a solid (normals flipped).
complement :: Solid -> Solid

-- | Subtract a solid from another.
subtract :: Solid -> Solid -> Solid
type Point = Vec3

-- | We use <a>CVec3</a> as a simple replacement for <tt>(Double, Double,
--   Double)</tt>. <a>CVec3</a> implements a contiguous storage scheme for
--   Unboxed and Storable vectors which shows better performance. Compile
--   this package with <tt>triples</tt> flag and run benchmarks to see the
--   difference.
type Vec3 = CVec3

-- | A ray described by the equation <tt>p(t) = p_0 + v * t</tt> with an
--   initial point <tt>p_0</tt> and a direction <tt>v</tt>. Substituting a
--   specific time <tt>t'</tt> in the equation yields a position of a point
--   <tt>p(t')</tt> on the ray. For negative values of <tt>t'</tt>,
--   position precedes the initial point.
newtype Ray
Ray :: (Point, Vec3) -> Ray

-- | A point at which a ray intersects a surface, given as a distance from
--   the ray's initial point and an outward normal to the surface at the
--   hit point. If hit is in infinity, then normal is <a>Nothing</a>. If
--   the hit occures on the same line but precedes the initial point of the
--   ray, the distance is negative.
--   
--   Note that this datatype is strict only on first argument: we do not
--   compare normals when combining traces and thus do not force
--   calculation of normals.
data HitPoint
HitPoint :: !Double -> (Maybe Vec3) -> HitPoint

-- | A segment of ray inside a solid.
type HitSegment = (Pair HitPoint HitPoint)

-- | Trace of a ray/line on a solid is a list of segments corresponding to
--   the portions of the ray inside the solid.
--   
--   <pre>
--   O - ray
--    -- &gt;                         -- &gt;                          +------------
--   </pre>
type Trace = [HitSegment]

-- | Trace of a ray on a solid.
trace :: Solid -> Ray -> Trace

-- | Find the next point where a ray hits a solid, if any.
--   
--   Here we consider only future intersections: the <a>HitPoint</a> is
--   guaranteed to have non-negative distance (unlike when using
--   <a>trace</a>).
--   
--   This means that if the ray starts inside the solid the only way to
--   tell that from <a>cast</a> result is to compare it's direction and the
--   surface normal at the hit point.
cast :: Ray -> Solid -> Maybe HitPoint

-- | True if the point is in inside the solid.
inside :: Point -> Solid -> Bool
instance GHC.Show.Show Data.CSG.Solid
instance GHC.Classes.Eq Data.CSG.Solid
instance GHC.Show.Show Data.CSG.HitPoint
instance GHC.Classes.Eq Data.CSG.HitPoint
instance Test.QuickCheck.Arbitrary.Arbitrary Data.CSG.Solid
instance GHC.Classes.Ord Data.CSG.HitPoint


-- | Parser for CSG solid definition format. The format uses text files and
--   is inspired by NETGEN 4.x <tt>.geo</tt> format.
--   
--   Each definition may contain several solid definitions and ends with
--   the top level object declaration. Right hand side of solid equations
--   may reference other solids to allow composing of complex solids.
--   
--   <pre>
--   # comment
--   
--   # define several primitives
--   solid b1 = sphere (0, 0, 0; 5);
--   solid p1 = plane (0, 0, 0; 1, 0, 0);
--   
--   # define a composition
--   solid comp = b1 and p1;
--   
--   # make it the top level object
--   tlo comp;
--   </pre>
--   
--   Statements must end with a semicolon (newlines are optional).
--   Whitespace is ignored.
--   
--   Multiple-solid compositions are <b>right-associative</b>, so <tt>b1
--   and b2 or b3</tt> really means <tt>b1 and (b2 or b3)</tt>. Keep
--   simpler objects on the left and when in doubt stick to combining two
--   solids at a time.
--   
--   Top-level object line must reference a previously defined solid.
--   
--   Syntax for primitives follows the signatures of <tt>CSG</tt>
--   constructors for <a>plane</a> and <a>sphere</a>, but differs for
--   cylinder and cone, as this module provides access only to frustums
--   (<a>cylinderFrustum</a> and <a>coneFrustum</a>).
--   
--   <ul>
--   <li><i>Half-space</i> <tt>plane (px, py, pz; nx, ny, nz)</tt>, where
--   <tt>(px, py, pz)</tt> is a point on a plane which defines the
--   half-space and <tt>(nx, ny, nz)</tt> is a normal to the plane (outward
--   to the half-space), not necessarily a unit vector.</li>
--   <li><i>Brick</i> <tt>orthobrick (ax, ay, az; bx, by, bz)</tt>, where
--   <tt>(ax, ay, az)</tt> is a vertex with minimum coordinates and
--   <tt>(bx, by, bz)</tt> is a vertex with maximum coordinates.</li>
--   <li><i>Sphere</i> <tt>sphere (cx, cy, cz; r)</tt>, where <tt>(cx, cy,
--   cz)</tt> is a central point of a sphere and <tt>r</tt> is radius.</li>
--   <li><i>Right circular cylinder</i> <tt>cylinder (p1x, p1y, p1z; p2x,
--   p2y, p2z; r)</tt> where <tt>(p1x, p1y, p1z)</tt> and <tt>(p2x, p2y,
--   p2z)</tt> are bottom and top points on axis and <tt>r</tt> is
--   radius.</li>
--   <li><i>Right circular conical frustum</i> <tt>cone (p1x, p1y, p1z; r1;
--   p2x, p2y, p2z; r2)</tt> where <tt>(p1x, p1y, p1z)</tt> and <tt>(p2x,
--   p2y, p2z)</tt> are bottom and top points on cone axis and <tt>r1</tt>,
--   <tt>r2</tt> are the corresponding radii.</li>
--   </ul>
module Data.CSG.Parser

-- | Read solid definition. If parsing fails, return error message as a
--   string.
parseGeometry :: ByteString -> Either String Solid

-- | Read solid definition from a file. If parsing fails, return error
--   message as a string.
parseGeometryFile :: FilePath -> IO (Either String Solid)
