//===========================================================================
// GoTools - SINTEF Geometry Tools version 1.0
//
// GoTools module: Implicitization, version 0.9
//
// Copyright (C) 2000-2005 SINTEF ICT, Applied Mathematics, Norway.
//
// This program is free software; you can redistribute it and/or          
// modify it under the terms of the GNU General Public License            
// as published by the Free Software Foundation version 2 of the License. 
//
// This program is distributed in the hope that it will be useful,        
// but WITHOUT ANY WARRANTY; without even the implied warranty of         
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
// GNU General Public License for more details.                           
//
// You should have received a copy of the GNU General Public License      
// along with this program; if not, write to the Free Software            
// Foundation, Inc.,                                                      
// 59 Temple Place - Suite 330,                                           
// Boston, MA  02111-1307, USA.                                           
//
// Contact information: e-mail: tor.dokken@sintef.no                      
// SINTEF ICT, Department of Applied Mathematics,                         
// P.O. Box 124 Blindern,                                                 
// 0314 Oslo, Norway.                                                     
//
// Other licenses are also available for this software, notably licenses
// for:
// - Building commercial software.                                        
// - Building software whose source code you wish to keep private.        
//===========================================================================
#ifndef _IMPLICITIZESURFACEALGO_H
#define _IMPLICITIZESURFACEALGO_H


#include "BernsteinTetrahedralPoly.h"
#include "SplineSurface.h"
#include "BaryCoordSystem.h"


namespace Go {
///\addtogroup implicitization
///\{



/**
 * Class that implements an implicitization algorithm for spline
 * surfaces
 *
 * Input: A surface of type SplineSurface, and the degree that is
 * chosen for the implicitization.
 *
 * Output: A barycentric coordinate system, and the Bernstein
 * polynomial that represents the implicit surface.
 *
 * The algorithm first defines a barycentric coordinate system in
 * terms of a tetrahedron that is slightly larger than the bounding
 * box of the spline surface. It then computes the Bernstein
 * polynomial representing the implicit surface. If the chosen degree
 * is too low to produce the exact result, an approximate implicit
 * surface is produced. If the degree is too high, the resulting
 * polynomial will be reducible and contain the exact implicitization
 * as a factor. If the input surface consists of multiple patches, the
 * output polynomial will be a product of the separate implicit
 * surfaces, or an approximation of it.
 */

class ImplicitizeSurfaceAlgo {
public:
    /// Default constructor
    ImplicitizeSurfaceAlgo() : tol_(3.0e-15) { }
    /// Constructor.
    /// \param deg degree of the implicit representation
    explicit ImplicitizeSurfaceAlgo(int deg) : deg_(deg), tol_(3.0e-15) { }
    /// Constructor.
    /// \param surf spline surface to be implicitized
    /// \param deg degree of the implicit representation
    ImplicitizeSurfaceAlgo(const SplineSurface& surf, int deg)
	: surf_(surf), deg_(deg), tol_(3.0e-15) { }

    /// Load the spline surface to be implicitized.
    /// \param surf surfaceon SplineSurface form
    void useSplineSurface(const SplineSurface& surf)
    { surf_ = surf; }

    /// Choose the degree of the implicit representation.
    /// \param deg degree
    void setDegree(int deg)
    { deg_ = deg; }

    /// Set the tolerance.
    /// \param tol tolerance; default value is 3.0e-15
    void setTolerance(double tol)
    { tol_ = tol; }

    /// Perform the implicitization.
    /// This function runs the implicitization algorithm.
    void perform();

    /// Get the result of the implicitization.
    /// \retval implicit a BernsteinTetrahedralPoly representing the
    /// implicit surface
    /// \retval bc the barycentric coordinate system in which the
    /// BernsteinTetrahedralPoly is defined
    void getResultData(BernsteinTetrahedralPoly& implicit,
		       BaryCoordSystem3D& bc)
    {
	implicit = implicit_;
	bc = bc_;
    }

private:
    SplineSurface surf_;
    BernsteinTetrahedralPoly implicit_;
    BaryCoordSystem3D bc_;
    int deg_;
    double tol_;

};


///\}
} // namespace Go


#endif // _IMPLICITIZESURFACEALGO_H


