344 lines
13 KiB
C++
Executable File
344 lines
13 KiB
C++
Executable File
/**
|
|
* @file MarchingCubes.h
|
|
* @author Thomas Lewiner <thomas.lewiner@polytechnique.org>
|
|
* @author Math Dept, PUC-Rio
|
|
* @version 0.2
|
|
* @date 12/08/2002
|
|
*
|
|
* @brief MarchingCubes Algorithm
|
|
*/
|
|
//________________________________________________
|
|
|
|
|
|
#ifndef _MARCHINGCUBES_H_
|
|
#define _MARCHINGCUBES_H_
|
|
|
|
#if !defined(WIN32) || defined(__CYGWIN__)
|
|
#pragma interface
|
|
#endif // WIN32
|
|
|
|
|
|
//_____________________________________________________________________________
|
|
// types
|
|
/** unsigned char alias */
|
|
typedef unsigned char uchar ;
|
|
/** signed char alias */
|
|
typedef signed char schar ;
|
|
/** isovalue alias */
|
|
typedef float real ;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Vertex structure
|
|
/** \struct Vertex "MarchingCubes.h" MarchingCubes
|
|
* Position and normal of a vertex
|
|
* \brief vertex structure
|
|
* \param x X coordinate
|
|
* \param y Y coordinate
|
|
* \param z Z coordinate
|
|
* \param nx X component of the normal
|
|
* \param ny Y component of the normal
|
|
* \param nz Z component of the normal
|
|
*/
|
|
typedef struct
|
|
{
|
|
real x, y, z ; /**< Vertex coordinates */
|
|
real nx, ny, nz ; /**< Vertex normal */
|
|
} Vertex ;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Triangle structure
|
|
/** \struct Triangle "MarchingCubes.h" MarchingCubes
|
|
* Indices of the oriented triange vertices
|
|
* \brief triangle structure
|
|
* \param v1 First vertex index
|
|
* \param v2 Second vertex index
|
|
* \param v3 Third vertex index
|
|
*/
|
|
typedef struct
|
|
{
|
|
int v1,v2,v3 ; /**< Triangle vertices */
|
|
} Triangle ;
|
|
//_____________________________________________________________________________
|
|
|
|
|
|
|
|
//_____________________________________________________________________________
|
|
/** Marching Cubes algorithm wrapper */
|
|
/** \class MarchingCubes
|
|
* \brief Marching Cubes algorithm.
|
|
*/
|
|
class MarchingCubes
|
|
//-----------------------------------------------------------------------------
|
|
{
|
|
// Constructors
|
|
public :
|
|
/**
|
|
* Main and default constructor
|
|
* \brief constructor
|
|
* \param size_x width of the grid
|
|
* \param size_y depth of the grid
|
|
* \param size_z height of the grid
|
|
*/
|
|
MarchingCubes ( const int size_x = -1, const int size_y = -1, const int size_z = -1 ) ;
|
|
/** Destructor */
|
|
~MarchingCubes() ;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Accessors
|
|
public :
|
|
/** accesses the number of vertices of the generated mesh */
|
|
inline const int nverts() const { return _nverts ; }
|
|
/** accesses the number of triangles of the generated mesh */
|
|
inline const int ntrigs() const { return _ntrigs ; }
|
|
/** accesses a specific vertex of the generated mesh */
|
|
inline Vertex * vert( const int i ) const { if( i < 0 || i >= _nverts ) return ( Vertex *)NULL ; return _vertices + i ; }
|
|
/** accesses a specific triangle of the generated mesh */
|
|
inline Triangle * trig( const int i ) const { if( i < 0 || i >= _ntrigs ) return (Triangle*)NULL ; return _triangles + i ; }
|
|
|
|
/** accesses the vertex buffer of the generated mesh */
|
|
inline Vertex *vertices () { return _vertices ; }
|
|
/** accesses the triangle buffer of the generated mesh */
|
|
inline Triangle *triangles() { return _triangles ; }
|
|
|
|
/** accesses the width of the grid */
|
|
inline const int size_x() const { return _size_x ; }
|
|
/** accesses the depth of the grid */
|
|
inline const int size_y() const { return _size_y ; }
|
|
/** accesses the height of the grid */
|
|
inline const int size_z() const { return _size_z ; }
|
|
|
|
/**
|
|
* changes the size of the grid
|
|
* \param size_x width of the grid
|
|
* \param size_y depth of the grid
|
|
* \param size_z height of the grid
|
|
*/
|
|
inline void set_resolution( const int size_x, const int size_y, const int size_z ) { _size_x = size_x ; _size_y = size_y ; _size_z = size_z ; }
|
|
/**
|
|
* selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes
|
|
* \param originalMC true for the original Marching Cubes
|
|
*/
|
|
inline void set_method ( const bool originalMC = false ) { _originalMC = originalMC ; }
|
|
/**
|
|
* selects to use data from another class
|
|
* \param data is the pointer to the external data, allocated as a size_x*size_y*size_z vector running in x first
|
|
*/
|
|
inline void set_ext_data ( real *data )
|
|
{ if( !_ext_data ) delete [] _data ; _ext_data = data != NULL ; if( _ext_data ) _data = data ; }
|
|
/**
|
|
* selects to allocate data
|
|
*/
|
|
inline void set_int_data () { _ext_data = false ; _data = NULL ; }
|
|
|
|
// Data access
|
|
/**
|
|
* accesses a specific cube of the grid
|
|
* \param i abscisse of the cube
|
|
* \param j ordinate of the cube
|
|
* \param k height of the cube
|
|
*/
|
|
inline const real get_data ( const int i, const int j, const int k ) const { return _data[ i + j*_size_x + k*_size_x*_size_y] ; }
|
|
/**
|
|
* sets a specific cube of the grid
|
|
* \param val new value for the cube
|
|
* \param i abscisse of the cube
|
|
* \param j ordinate of the cube
|
|
* \param k height of the cube
|
|
*/
|
|
inline void set_data ( const real val, const int i, const int j, const int k ) { _data[ i + j*_size_x + k*_size_x*_size_y] = val ; }
|
|
|
|
// Data initialization
|
|
/** inits temporary structures (must set sizes before call) : the grid and the vertex index per cube */
|
|
void init_temps () ;
|
|
/** inits all structures (must set sizes before call) : the temporary structures and the mesh buffers */
|
|
void init_all () ;
|
|
/** clears temporary structures : the grid and the main */
|
|
void clean_temps() ;
|
|
/** clears all structures : the temporary structures and the mesh buffers */
|
|
void clean_all () ;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Exportation
|
|
public :
|
|
/**
|
|
* PLY exportation of the generated mesh
|
|
* \param fn name of the PLY file to create
|
|
* \param bin if true, the PLY will be written in binary mode
|
|
*/
|
|
void writePLY( const char *fn, bool bin = false ) ;
|
|
|
|
/**
|
|
* PLY importation of a mesh
|
|
* \param fn name of the PLY file to read from
|
|
*/
|
|
void readPLY( const char *fn ) ;
|
|
|
|
/**
|
|
* VRML / Open Inventor exportation of the generated mesh
|
|
* \param fn name of the IV file to create
|
|
*/
|
|
void writeIV ( const char *fn ) ;
|
|
|
|
/**
|
|
* ISO exportation of the input grid
|
|
* \param fn name of the ISO file to create
|
|
*/
|
|
void writeISO( const char *fn ) ;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Algorithm
|
|
public :
|
|
/**
|
|
* Main algorithm : must be called after init_all
|
|
* \param iso isovalue
|
|
*/
|
|
void run( real iso = (real)0.0 ) ;
|
|
|
|
protected :
|
|
/** tesselates one cube */
|
|
void process_cube () ;
|
|
/** tests if the components of the tesselation of the cube should be connected by the interior of an ambiguous face */
|
|
bool test_face ( schar face ) ;
|
|
/** tests if the components of the tesselation of the cube should be connected through the interior of the cube */
|
|
bool test_interior( schar s ) ;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Operations
|
|
protected :
|
|
/**
|
|
* computes almost all the vertices of the mesh by interpolation along the cubes edges
|
|
* \param iso isovalue
|
|
*/
|
|
void compute_intersection_points( real iso ) ;
|
|
|
|
/**
|
|
* routine to add a triangle to the mesh
|
|
* \param trig the code for the triangle as a sequence of edges index
|
|
* \param n the number of triangles to produce
|
|
* \param v12 the index of the interior vertex to use, if necessary
|
|
*/
|
|
void add_triangle ( const char* trig, char n, int v12 = -1 ) ;
|
|
|
|
/** tests and eventually doubles the vertex buffer capacity for a new vertex insertion */
|
|
void test_vertex_addition() ;
|
|
/** adds a vertex on the current horizontal edge */
|
|
int add_x_vertex() ;
|
|
/** adds a vertex on the current longitudinal edge */
|
|
int add_y_vertex() ;
|
|
/** adds a vertex on the current vertical edge */
|
|
int add_z_vertex() ;
|
|
/** adds a vertex inside the current cube */
|
|
int add_c_vertex() ;
|
|
|
|
/**
|
|
* interpolates the horizontal gradient of the implicit function at the lower vertex of the specified cube
|
|
* \param i abscisse of the cube
|
|
* \param j ordinate of the cube
|
|
* \param k height of the cube
|
|
*/
|
|
real get_x_grad( const int i, const int j, const int k ) const ;
|
|
/**
|
|
* interpolates the longitudinal gradient of the implicit function at the lower vertex of the specified cube
|
|
* \param i abscisse of the cube
|
|
* \param j ordinate of the cube
|
|
* \param k height of the cube
|
|
*/
|
|
real get_y_grad( const int i, const int j, const int k ) const ;
|
|
/**
|
|
* interpolates the vertical gradient of the implicit function at the lower vertex of the specified cube
|
|
* \param i abscisse of the cube
|
|
* \param j ordinate of the cube
|
|
* \param k height of the cube
|
|
*/
|
|
real get_z_grad( const int i, const int j, const int k ) const ;
|
|
|
|
/**
|
|
* accesses the pre-computed vertex index on the lower horizontal edge of a specific cube
|
|
* \param i abscisse of the cube
|
|
* \param j ordinate of the cube
|
|
* \param k height of the cube
|
|
*/
|
|
inline int get_x_vert( const int i, const int j, const int k ) const { return _x_verts[ i + j*_size_x + k*_size_x*_size_y] ; }
|
|
/**
|
|
* accesses the pre-computed vertex index on the lower longitudinal edge of a specific cube
|
|
* \param i abscisse of the cube
|
|
* \param j ordinate of the cube
|
|
* \param k height of the cube
|
|
*/
|
|
inline int get_y_vert( const int i, const int j, const int k ) const { return _y_verts[ i + j*_size_x + k*_size_x*_size_y] ; }
|
|
/**
|
|
* accesses the pre-computed vertex index on the lower vertical edge of a specific cube
|
|
* \param i abscisse of the cube
|
|
* \param j ordinate of the cube
|
|
* \param k height of the cube
|
|
*/
|
|
inline int get_z_vert( const int i, const int j, const int k ) const { return _z_verts[ i + j*_size_x + k*_size_x*_size_y] ; }
|
|
|
|
/**
|
|
* sets the pre-computed vertex index on the lower horizontal edge of a specific cube
|
|
* \param val the index of the new vertex
|
|
* \param i abscisse of the cube
|
|
* \param j ordinate of the cube
|
|
* \param k height of the cube
|
|
*/
|
|
inline void set_x_vert( const int val, const int i, const int j, const int k ) { _x_verts[ i + j*_size_x + k*_size_x*_size_y] = val ; }
|
|
/**
|
|
* sets the pre-computed vertex index on the lower longitudinal edge of a specific cube
|
|
* \param val the index of the new vertex
|
|
* \param i abscisse of the cube
|
|
* \param j ordinate of the cube
|
|
* \param k height of the cube
|
|
*/
|
|
inline void set_y_vert( const int val, const int i, const int j, const int k ) { _y_verts[ i + j*_size_x + k*_size_x*_size_y] = val ; }
|
|
/**
|
|
* sets the pre-computed vertex index on the lower vertical edge of a specific cube
|
|
* \param val the index of the new vertex
|
|
* \param i abscisse of the cube
|
|
* \param j ordinate of the cube
|
|
* \param k height of the cube
|
|
*/
|
|
inline void set_z_vert( const int val, const int i, const int j, const int k ) { _z_verts[ i + j*_size_x + k*_size_x*_size_y] = val ; }
|
|
|
|
/** prints cube for debug */
|
|
void print_cube() ;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Elements
|
|
protected :
|
|
bool _originalMC ; /**< selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes */
|
|
bool _ext_data ; /**< selects wether to allocate data or use data from another class */
|
|
|
|
int _size_x ; /**< width of the grid */
|
|
int _size_y ; /**< depth of the grid */
|
|
int _size_z ; /**< height of the grid */
|
|
real *_data ; /**< implicit function values sampled on the grid */
|
|
|
|
int *_x_verts ; /**< pre-computed vertex indices on the lower horizontal edge of each cube */
|
|
int *_y_verts ; /**< pre-computed vertex indices on the lower longitudinal edge of each cube */
|
|
int *_z_verts ; /**< pre-computed vertex indices on the lower vertical edge of each cube */
|
|
|
|
int _nverts ; /**< number of allocated vertices in the vertex buffer */
|
|
int _ntrigs ; /**< number of allocated triangles in the triangle buffer */
|
|
int _Nverts ; /**< size of the vertex buffer */
|
|
int _Ntrigs ; /**< size of the triangle buffer */
|
|
Vertex *_vertices ; /**< vertex buffer */
|
|
Triangle *_triangles ; /**< triangle buffer */
|
|
|
|
int _i ; /**< abscisse of the active cube */
|
|
int _j ; /**< height of the active cube */
|
|
int _k ; /**< ordinate of the active cube */
|
|
|
|
real _cube[8] ; /**< values of the implicit function on the active cube */
|
|
uchar _lut_entry ; /**< cube sign representation in [0..255] */
|
|
uchar _case ; /**< case of the active cube in [0..15] */
|
|
uchar _config ; /**< configuration of the active cube */
|
|
uchar _subconfig ; /**< subconfiguration of the active cube */
|
|
};
|
|
//_____________________________________________________________________________
|
|
|
|
|
|
#endif // _MARCHINGCUBES_H_
|