// ----------------------------------------------------------------------------
//
// Copyright (C) Columbia University, 1994. All Rights Reserved.
// Sameer A. Nene, Shree K. Nayar, Hiroshi Murase
//
// See file LICENSE for details of software license agreement.
//
// ----------------------------------------------------------------------------
//
// bsplinevolume.h
//
// Author:               Sameer Nene
// Date:                 05/26/94
// Version:              1.0
// Modification History:
// Bugs:
//
// Classes:
//   BSplineVolume
//
// Notes:
//   This header includes declarations for the class BSplineVolume.
//   BSplineVolume is a "two dimensional" BSpline as enforced by the BSpline
//   protocol. Although the spline itself is a "3D solid volume", it can lie in
//   multidimensional space.
//
// ----------------------------------------------------------------------------

#ifndef SPLINEVOLUME_INCLUDED
#define SPLINEVOLUME_INCLUDED

#ifndef BSPLINE_INCLUDED
#include "bspline.h"
#endif

#ifndef VECTOR_INCLUDED
#include "vector.h"
#endif

#ifndef BSPLINE_INCLUDED
#include "bspline.h"
#endif

#ifndef VECTOR_INCLUDED
#include "vector.h"
#endif

#ifndef REGISTRY_INCLUDED
#include "registry.h"
#endif

class Persistent;
class Interpolation;

class BSplineVolume : public BSpline {

  // Private Members

  static void* d_protocol;
  static void *d_ipProtocol;
  static char *d_name_p;
  static Registrar d_registrar;

  static Persistent* createFunc();
   // returns a pointer to a newly created BSplineVolume

  int d_sizei, d_sizej, d_sizek;
  Vector d_knoti, d_knotj, d_knotk;

  void generateBand(Vector*, int, int) const;

  // BSplineVolumes cannot be copied or assigned

  BSplineVolume(const BSplineVolume&);
  BSplineVolume& operator=(const BSplineVolume&);

  // Protected Members
  
protected:

  int hasInterpolationProtocol(void *protocol) const;
  // returns 1 if this object is of type(protocol) protocol OR is derived
  // from an object of type(protocol) protocol
  
  int hasProtocol(void* protocol) const;
  // returns 1 if this object is of type(protocol) protocol OR is derived
  // from an object of type(protocol) protocol

  // Public Members

public:

  // Construct and Destroy
    
  BSplineVolume();
  BSplineVolume(int, int, int); // number of control points
  ~BSplineVolume();

  // Accessors

  static BSplineVolume* safeCast(Persistent*);
  // Converts Persistent to a BSplineVolume if the object pointed to by
  // Persistent is in fact a BSplineVolume

  static BSplineVolume* safeCast(Interpolation*);
  // Converts Interpolation to a BSplineVolume if the object pointed to by
  // Interpolation is in fact a BSplineVolume

  int getSizeI() const;
  // gets number of control points in Spline in I direction

  int getSizeJ() const;
  // gets number of control points in Spline in J direction

  int getSizeK() const;
  // gets number of control points in Spline in K direction

  Vector& getControl(int i, int j, int k) const;
  // gets i,j,k th control point

  Vector sample(const Vector&) const;
  // samples the curve with supplied set of parameters and returns sampled
  // point

  int dimension() const;
  // returns dimensionality = 3

  int spaceDimension() const;

  void sample(double u, double w, double x, Vector*) const;
  // sample Spline at parameter u, w, x into vector

  BSpline* clone() const;
  // makes a clone of this object

  ErrorScope::Error put(FILE*) const;
  // puts BSplineVolume in file

  const char* name() const;
  // returns the name of the class

  // Manipulators

  void setControl(int i, int j, int k, const Vector&);
  // sets vector as i,j,k th control point

  ErrorScope::Error get(FILE*);
  // gets BSplineVolume from file

  void fit(const VectAry&);
  
};

#endif
