#ifndef D3CLIPPING_H
#define D3CLIPPING_H

#include <vector>
using namespace std;

#include <d3tess.h>
#include <partitionspace.h>

typedef point3<double> pt3;

/*!
\brief 2D simplex mesh subtraction.

The partition is used to find the intersection between
 the mesh and itself.  It then clips the mesh.
 So the partition is subtracted from the mesh.

The algorithm works by classifying points as either
 white or black.  Points with all white points are
 discarded and points with all black points are accepted.

Triangles with white and black points are reclassified
 as a black point on the boundary is different from
 a black point not one the boundary.  For example
 two white points and one black on the boundary
 is discarded as it is equivalent to three white points.

\par Example
\verbatim
#include <point.h>
#include <d3tess.h>
#include <d3clipping.h>
...
<TODO>
\endverbatim
*/
class d3clipping
{
  d3tess & tess;
  vector<d3tri> & vi;
  vector<pt3> & pt;
  partitionspace< pt3, double > const & H;

  /** Process case One Black and Two White Balls. */
  void processB1W2
  ( 
    uintc s, 
    uintc b0, 
    uintc w0, 
    uintc w1 
  );

  /** Process case Two Black and One White Balls. */
  void processW1B2
  ( 
    uintc s, 
    uintc w0, 
    uintc b0, 
    uintc b1 
  );

  /** pt and bv are updated. */
  void addintersectionpoint( pt3c & A, pt3c & B );

  /** Identify the case and either handle or forward 
      processing.  Simplexes that need reprocessing 
      are placed in the reprocess stack. */
  void processSimplex(uintc s);

  /** The initial stack size is given before calling 
      tess.split1D(...) */
  void reprocessStack
  (
    uintc nstacksz,
    uintc s,
    uintc neib0=0,
    uintc neib1=0
  );  

public:

  /** Short for black value it is true if the associated 
      point is black in color. */
  vector<bool> bv;  

  /** Clip the tessellation against the line. */
  d3clipping
  (
    d3tess & tess_, 
    partitionspace< pt3, double > const & H_ 
  );

  /** Clip the tessellation against the partition. */
  void eval();

  /** Client configures zero for isOnBoundary routine.
    eg  zero = 1.0e-10 */
  double zero;

};



#endif



