diff --git a/3rdParty/MarchingCubes/CMakePackage.txt b/3rdParty/MarchingCubes/CMakePackage.txt deleted file mode 100644 index b4e619a03839520bde16837d806f9dc5269be71a..0000000000000000000000000000000000000000 --- a/3rdParty/MarchingCubes/CMakePackage.txt +++ /dev/null @@ -1,6 +0,0 @@ -GET_FILENAME_COMPONENT( CURRENT_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) -COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES outOption outSourceGroupName) - -IF(${outOption}) - list(APPEND VF_COMPILER_DEFINITION MC_CUBES) -ENDIF() diff --git a/3rdParty/MarchingCubes/MarchingCubes.h b/3rdParty/MarchingCubes/MarchingCubes.h deleted file mode 100644 index e03d151d7a27859c07ac17e4d92fbf1c9379864a..0000000000000000000000000000000000000000 --- a/3rdParty/MarchingCubes/MarchingCubes.h +++ /dev/null @@ -1,1640 +0,0 @@ -#ifndef MARCHINGCUBES_H -#define MARCHINGCUBES_H -/** -* @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 -*/ -//________________________________________________ - -#include <MarchingCubes/McTypes.h> -#include <MarchingCubes/MatrixWrapper.h> -#include <MarchingCubes/Matrix3DWrapper.h> -#include <MarchingCubes/Matrix4DWrapper.h> -#include <MarchingCubes/McLookUpTable.h> -#include <MarchingCubes/McPly.h> - -#include <cmath> -#include <ctime> -#include <cfloat> -#include <iostream> - -namespace McCubes{ -//_____________________________________________________________________________ -/** Marching Cubes algorithm wrapper */ -/** \class MarchingCubes - * \brief Marching Cubes algorithm. - */ -template<typename DataWrapper = MatrixWrapper<real> > -class MarchingCubes -//----------------------------------------------------------------------------- -{ -public: - //nested classes - //----------------------------------------------------------------------------- - // 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 Vertex - { - 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 Triangle - { - int v1,v2,v3 ; /**< Triangle vertices */ - } Triangle ; - //_____________________________________________________________________________ - -public : - // Constructors - /** - * 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 ) ; - MarchingCubes ( const DataWrapper& dataWrapper ); - /** 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 dataWrapper.getNX1(); /*_size_x ;*/ } - /** accesses the depth of the grid */ - inline const int size_y() const { return dataWrapper.getNX2(); /*_size_y ;*/ } - /** accesses the height of the grid */ - inline const int size_z() const { return dataWrapper.getNX3(); /*_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 ) - { - dataWrapper.resize(size_x, size_y, size_z); - //throw UbException("MarchingCubes::set_resolution disabled by CAB"); - //_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 ) - { - throw UbException(UB_EXARGS, "disabled by CAB"); - //if( !_ext_data ) delete [] _data ; _ext_data = data != NULL ; if( _ext_data ) _data = data ; - } - /** - * selects to allocate data - */ - inline void set_int_data () - { - throw UbException(UB_EXARGS,"disabled by CAB"); - //_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 - */ - //MODIFIED BY CAB - inline const real get_data ( const int& i, const int& j, const int& k ) const - { - return dataWrapper.getData(i,j,k); - //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 - */ - //MODIFIED BY CAB - inline void set_data ( const real& val, const int& i, const int& j, const int& k ) - { - dataWrapper.setData(val,i,j,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 ) ; - - /** - * 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 ) ; - - - void writeUCD( std::string filename ); - void writeUCDwithNormals( std::string filename ); - -//----------------------------------------------------------------------------- -// 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*dataWrapper.getNX1() + k*dataWrapper.getNX1()*dataWrapper.getNX2()] ; } - /** - * 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*dataWrapper.getNX1() + k*dataWrapper.getNX1()*dataWrapper.getNX2()] ; } - /** - * 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*dataWrapper.getNX1() + k*dataWrapper.getNX1()*dataWrapper.getNX2()] ; } - - /** - * 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*dataWrapper.getNX1() + k*dataWrapper.getNX1()*dataWrapper.getNX2()] = 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*dataWrapper.getNX1() + k*dataWrapper.getNX1()*dataWrapper.getNX2()] = 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*dataWrapper.getNX1() + k*dataWrapper.getNX1()*dataWrapper.getNX2()] = val ; } - - /** prints cube for debug */ - void print_cube(std::ostream& os) ; - -//----------------------------------------------------------------------------- -// 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 */ - -//folgendes ist nun alles folgenden dataWrapper: -// 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 */ - DataWrapper dataWrapper; - - 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 */ - -private: - MarchingCubes ( const MarchingCubes & ); //no copy allowed - const MarchingCubes& operator=( const MarchingCubes& ); //no copy allowed -}; -//_____________________________________________________________________________ - - -// step size of the arrays of vertices and triangles -static const int ALLOC_SIZE = 65536; - -//_____________________________________________________________________________ -// print cube for debug -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::print_cube(std::ostream& os) -{ - os<<_cube[0]<<","<<_cube[1]<<","<<_cube[2]<<","<<_cube[3]<<"," - <<_cube[4]<<","<<_cube[5]<<","<<_cube[6]<<","<<_cube[7]; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Constructors - -template<typename DataWrapper > -MarchingCubes< DataWrapper >::MarchingCubes( const int size_x /*= -1*/, const int size_y /*= -1*/, const int size_z /*= -1*/ ) : -_originalMC(false), -//_ext_data (false), -// _size_x (size_x), -// _size_y (size_y), -// _size_z (size_z), -//_data ((real *)NULL), -_x_verts (( int *)NULL), -_y_verts (( int *)NULL), -_z_verts (( int *)NULL), -_nverts (0), -_ntrigs (0), -_Nverts (0), -_Ntrigs (0), -_vertices (( Vertex *)NULL), -_triangles ((Triangle*)NULL) -{ - this->dataWrapper = DataWrapper(size_x,size_y,size_z); -} - -template<typename DataWrapper > -MarchingCubes< DataWrapper >::MarchingCubes ( const DataWrapper& dataWrapper ) : -_originalMC(false), -//_ext_data (false), -// _size_x (size_x), -// _size_y (size_y), -// _size_z (size_z), -//_data ((real *)NULL), -_x_verts (( int *)NULL), -_y_verts (( int *)NULL), -_z_verts (( int *)NULL), -_nverts (0), -_ntrigs (0), -_Nverts (0), -_Ntrigs (0), -_vertices (( Vertex *)NULL), -_triangles ((Triangle*)NULL) -{ - this->dataWrapper = dataWrapper; -} - -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Destructor -template<typename DataWrapper > -MarchingCubes<DataWrapper >::~MarchingCubes() -//----------------------------------------------------------------------------- -{ - clean_all() ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// main algorithm -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::run( real iso ) -//----------------------------------------------------------------------------- -{ - //printf("Marching Cubes begin: cpu %ld\n", clock() ) ; - - compute_intersection_points( iso ) ; - - for( _k = dataWrapper.getMinX3(); _k < dataWrapper.getMaxX3(); _k++ ) - for( _j = dataWrapper.getMinX2(); _j < dataWrapper.getMaxX2(); _j++ ) - for( _i = dataWrapper.getMinX1(); _i < dataWrapper.getMaxX1(); _i++ ) - { - _lut_entry = 0 ; - for( int p = 0 ; p < 8 ; ++p ) - { - _cube[p] = get_data( _i+((p^(p>>1))&1), _j+((p>>1)&1), _k+((p>>2)&1) ) - iso ; - if( std::fabs( _cube[p] ) < FLT_EPSILON ) _cube[p] = FLT_EPSILON ; - if( _cube[p] > 0 ) _lut_entry += 1 << p ; - } - /* - if( ( _cube[0] = get_data( _i , _j , _k ) ) > 0 ) _lut_entry += 1 ; - if( ( _cube[1] = get_data(_i+1, _j , _k ) ) > 0 ) _lut_entry += 2 ; - if( ( _cube[2] = get_data(_i+1,_j+1, _k ) ) > 0 ) _lut_entry += 4 ; - if( ( _cube[3] = get_data( _i ,_j+1, _k ) ) > 0 ) _lut_entry += 8 ; - if( ( _cube[4] = get_data( _i , _j ,_k+1) ) > 0 ) _lut_entry += 16 ; - if( ( _cube[5] = get_data(_i+1, _j ,_k+1) ) > 0 ) _lut_entry += 32 ; - if( ( _cube[6] = get_data(_i+1,_j+1,_k+1) ) > 0 ) _lut_entry += 64 ; - if( ( _cube[7] = get_data( _i ,_j+1,_k+1) ) > 0 ) _lut_entry += 128 ; - */ - process_cube( ) ; - } - - // printf("Marching Cubes end: cpu %ld\n", clock() ) ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// init temporary structures (must set sizes before call) -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::init_temps() -//----------------------------------------------------------------------------- -{ -// if( !_ext_data ) -// _data = new real [_size_x * _size_y * _size_z] ; - _x_verts = new int [dataWrapper.getNX1() * dataWrapper.getNX2() * dataWrapper.getNX3()] ; - _y_verts = new int [dataWrapper.getNX1() * dataWrapper.getNX2() * dataWrapper.getNX3()] ; - _z_verts = new int [dataWrapper.getNX1() * dataWrapper.getNX2() * dataWrapper.getNX3()] ; - - memset( _x_verts, -1, dataWrapper.getNX1() * dataWrapper.getNX2() * dataWrapper.getNX3() * sizeof( int ) ) ; - memset( _y_verts, -1, dataWrapper.getNX1() * dataWrapper.getNX2() * dataWrapper.getNX3() * sizeof( int ) ) ; - memset( _z_verts, -1, dataWrapper.getNX1() * dataWrapper.getNX2() * dataWrapper.getNX3() * sizeof( int ) ) ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// init all structures (must set sizes before call) -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::init_all () -//----------------------------------------------------------------------------- -{ - init_temps() ; - - _nverts = _ntrigs = 0 ; - _Nverts = _Ntrigs = ALLOC_SIZE ; - _vertices = new Vertex [_Nverts] ; - _triangles = new Triangle[_Ntrigs] ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// clean temporary structures -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::clean_temps() -//----------------------------------------------------------------------------- -{ -// if( !_ext_data ) -// delete [] _data; - delete [] _x_verts; - delete [] _y_verts; - delete [] _z_verts; - -// if( !_ext_data ) -// _data = (real*)NULL ; - _x_verts = (int*)NULL ; - _y_verts = (int*)NULL ; - _z_verts = (int*)NULL ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// clean all structures -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::clean_all() -//----------------------------------------------------------------------------- -{ - clean_temps() ; - delete [] _vertices ; - delete [] _triangles ; - _vertices = (Vertex *)NULL ; - _triangles = (Triangle *)NULL ; - _nverts = _ntrigs = 0 ; - _Nverts = _Ntrigs = 0 ; - - //_size_x = _size_y = _size_z = -1 ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Compute the intersection points -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::compute_intersection_points( real iso ) -//----------------------------------------------------------------------------- -{ - for( _k = 0 ; _k < dataWrapper.getNX3() ; _k++ ) - for( _j = 0 ; _j < dataWrapper.getNX2() ; _j++ ) - for( _i = 0 ; _i < dataWrapper.getNX1() ; _i++ ) - { - _cube[0] = get_data( _i, _j, _k ) - iso ; - if( _i < dataWrapper.getNX1() - 1 ) _cube[1] = get_data(_i+1, _j , _k ) - iso ; - else _cube[1] = _cube[0] ; - - if( _j < dataWrapper.getNX2() - 1 ) _cube[3] = get_data( _i ,_j+1, _k ) - iso ; - else _cube[3] = _cube[0] ; - - if( _k < dataWrapper.getNX3() - 1 ) _cube[4] = get_data( _i , _j ,_k+1) - iso ; - else _cube[4] = _cube[0] ; - - if( std::fabs( _cube[0] ) < FLT_EPSILON ) _cube[0] = FLT_EPSILON ; - if( std::fabs( _cube[1] ) < FLT_EPSILON ) _cube[1] = FLT_EPSILON ; - if( std::fabs( _cube[3] ) < FLT_EPSILON ) _cube[3] = FLT_EPSILON ; - if( std::fabs( _cube[4] ) < FLT_EPSILON ) _cube[4] = FLT_EPSILON ; - - if( _cube[0] < 0 ) - { - if( _cube[1] > 0 ) set_x_vert( add_x_vertex( ), _i,_j,_k ) ; - if( _cube[3] > 0 ) set_y_vert( add_y_vertex( ), _i,_j,_k ) ; - if( _cube[4] > 0 ) set_z_vert( add_z_vertex( ), _i,_j,_k ) ; - } - else - { - if( _cube[1] < 0 ) set_x_vert( add_x_vertex( ), _i,_j,_k ) ; - if( _cube[3] < 0 ) set_y_vert( add_y_vertex( ), _i,_j,_k ) ; - if( _cube[4] < 0 ) set_z_vert( add_z_vertex( ), _i,_j,_k ) ; - } - } -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Test a face -// if face>0 return true if the face contains a part of the surface -template<typename DataWrapper > -bool MarchingCubes<DataWrapper >::test_face( schar face ) -//----------------------------------------------------------------------------- -{ - real A,B,C,D ; - - switch( face ) - { - case -1 : case 1 : A = _cube[0] ; B = _cube[4] ; C = _cube[5] ; D = _cube[1] ; break ; - case -2 : case 2 : A = _cube[1] ; B = _cube[5] ; C = _cube[6] ; D = _cube[2] ; break ; - case -3 : case 3 : A = _cube[2] ; B = _cube[6] ; C = _cube[7] ; D = _cube[3] ; break ; - case -4 : case 4 : A = _cube[3] ; B = _cube[7] ; C = _cube[4] ; D = _cube[0] ; break ; - case -5 : case 5 : A = _cube[0] ; B = _cube[3] ; C = _cube[2] ; D = _cube[1] ; break ; - case -6 : case 6 : A = _cube[4] ; B = _cube[7] ; C = _cube[6] ; D = _cube[5] ; break ; - default : - std::cerr<<" MarchingCubes<DataWrapper >::test_face ["<<__LINE__<<"]:: Invalid face code "<< face <<std::endl; - print_cube(std::cerr); - A = B = C = D = 0 ; - }; - - if( std::fabs( A*C - B*D ) < FLT_EPSILON ) - return face >= 0 ; - return face * A * ( A*C - B*D ) >= 0 ; // face and A invert signs -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Test the interior of a cube -// if s == 7, return true if the interior is empty -// if s ==-7, return false if the interior is empty -template<typename DataWrapper > -bool MarchingCubes<DataWrapper >::test_interior( schar s ) -//----------------------------------------------------------------------------- -{ - real t, At=0, Bt=0, Ct=0, Dt=0, a, b ; - char test = 0 ; - char edge = -1 ; // reference edge of the triangulation - - switch( _case ) - { - case 4 : - case 10 : - a = ( _cube[4] - _cube[0] ) * ( _cube[6] - _cube[2] ) - ( _cube[7] - _cube[3] ) * ( _cube[5] - _cube[1] ) ; - b = _cube[2] * ( _cube[4] - _cube[0] ) + _cube[0] * ( _cube[6] - _cube[2] ) - - _cube[1] * ( _cube[7] - _cube[3] ) - _cube[3] * ( _cube[5] - _cube[1] ) ; - t = - b / (2*a) ; - if( t<0 || t>1 ) return s>0 ; - - At = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - break ; - - case 6 : - case 7 : - case 12 : - case 13 : - switch( _case ) - { - case 6 : edge = test6 [_config][2] ; break ; - case 7 : edge = test7 [_config][4] ; break ; - case 12 : edge = test12[_config][3] ; break ; - case 13 : edge = tiling13_5_1[_config][_subconfig][0] ; break ; - } - switch( edge ) - { - case 0 : - t = _cube[0] / ( _cube[0] - _cube[1] ) ; - At = 0 ; - Bt = _cube[3] + ( _cube[2] - _cube[3] ) * t ; - Ct = _cube[7] + ( _cube[6] - _cube[7] ) * t ; - Dt = _cube[4] + ( _cube[5] - _cube[4] ) * t ; - break ; - case 1 : - t = _cube[1] / ( _cube[1] - _cube[2] ) ; - At = 0 ; - Bt = _cube[0] + ( _cube[3] - _cube[0] ) * t ; - Ct = _cube[4] + ( _cube[7] - _cube[4] ) * t ; - Dt = _cube[5] + ( _cube[6] - _cube[5] ) * t ; - break ; - case 2 : - t = _cube[2] / ( _cube[2] - _cube[3] ) ; - At = 0 ; - Bt = _cube[1] + ( _cube[0] - _cube[1] ) * t ; - Ct = _cube[5] + ( _cube[4] - _cube[5] ) * t ; - Dt = _cube[6] + ( _cube[7] - _cube[6] ) * t ; - break ; - case 3 : - t = _cube[3] / ( _cube[3] - _cube[0] ) ; - At = 0 ; - Bt = _cube[2] + ( _cube[1] - _cube[2] ) * t ; - Ct = _cube[6] + ( _cube[5] - _cube[6] ) * t ; - Dt = _cube[7] + ( _cube[4] - _cube[7] ) * t ; - break ; - case 4 : - t = _cube[4] / ( _cube[4] - _cube[5] ) ; - At = 0 ; - Bt = _cube[7] + ( _cube[6] - _cube[7] ) * t ; - Ct = _cube[3] + ( _cube[2] - _cube[3] ) * t ; - Dt = _cube[0] + ( _cube[1] - _cube[0] ) * t ; - break ; - case 5 : - t = _cube[5] / ( _cube[5] - _cube[6] ) ; - At = 0 ; - Bt = _cube[4] + ( _cube[7] - _cube[4] ) * t ; - Ct = _cube[0] + ( _cube[3] - _cube[0] ) * t ; - Dt = _cube[1] + ( _cube[2] - _cube[1] ) * t ; - break ; - case 6 : - t = _cube[6] / ( _cube[6] - _cube[7] ) ; - At = 0 ; - Bt = _cube[5] + ( _cube[4] - _cube[5] ) * t ; - Ct = _cube[1] + ( _cube[0] - _cube[1] ) * t ; - Dt = _cube[2] + ( _cube[3] - _cube[2] ) * t ; - break ; - case 7 : - t = _cube[7] / ( _cube[7] - _cube[4] ) ; - At = 0 ; - Bt = _cube[6] + ( _cube[5] - _cube[6] ) * t ; - Ct = _cube[2] + ( _cube[1] - _cube[2] ) * t ; - Dt = _cube[3] + ( _cube[0] - _cube[3] ) * t ; - break ; - case 8 : - t = _cube[0] / ( _cube[0] - _cube[4] ) ; - At = 0 ; - Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - break ; - case 9 : - t = _cube[1] / ( _cube[1] - _cube[5] ) ; - At = 0 ; - Bt = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - Ct = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - Dt = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - break ; - case 10 : - t = _cube[2] / ( _cube[2] - _cube[6] ) ; - At = 0 ; - Bt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - Ct = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - Dt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - break ; - case 11 : - t = _cube[3] / ( _cube[3] - _cube[7] ) ; - At = 0 ; - Bt = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - Ct = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - Dt = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - break ; - default : - std::cerr<<" MarchingCubes<DataWrapper >::test_interior ["<<__LINE__<<"]: Invalid edge "<< edge <<std::endl; - print_cube(std::cerr); - break; - } - break ; - - default : - std::cerr<<" MarchingCubes<DataWrapper >::test_interior ["<<__LINE__<<"]: Invalid ambiguous case "<< _case <<std::endl; - print_cube(std::cerr); - break; - } - - if( At >= 0 ) test ++ ; - if( Bt >= 0 ) test += 2 ; - if( Ct >= 0 ) test += 4 ; - if( Dt >= 0 ) test += 8 ; - switch( test ) - { - case 0 : return s>0 ; - case 1 : return s>0 ; - case 2 : return s>0 ; - case 3 : return s>0 ; - case 4 : return s>0 ; - case 5 : if( At * Ct - Bt * Dt < FLT_EPSILON ) return s>0 ; break ; - case 6 : return s>0 ; - case 7 : return s<0 ; - case 8 : return s>0 ; - case 9 : return s>0 ; - case 10 : if( At * Ct - Bt * Dt >= FLT_EPSILON ) return s>0 ; break ; - case 11 : return s<0 ; - case 12 : return s>0 ; - case 13 : return s<0 ; - case 14 : return s<0 ; - case 15 : return s<0 ; - } - - return s<0 ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Process a unit cube -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::process_cube( ) -//----------------------------------------------------------------------------- -{ - if( _originalMC ) - { - char nt = 0 ; - while( casesClassic[_lut_entry][3*nt] != -1 ) nt++ ; - add_triangle( casesClassic[_lut_entry], nt ) ; - return ; - } - - int v12 = -1 ; - _case = cases[_lut_entry][0] ; - _config = cases[_lut_entry][1] ; - _subconfig = 0 ; - - switch( _case ) - { - case 0 : - break ; - - case 1 : - add_triangle( tiling1[_config], 1 ) ; - break ; - - case 2 : - add_triangle( tiling2[_config], 2 ) ; - break ; - - case 3 : - if( test_face( test3[_config]) ) - add_triangle( tiling3_2[_config], 4 ) ; // 3.2 - else - add_triangle( tiling3_1[_config], 2 ) ; // 3.1 - break ; - - case 4 : - if( test_interior( test4[_config]) ) - add_triangle( tiling4_1[_config], 2 ) ; // 4.1.1 - else - add_triangle( tiling4_2[_config], 6 ) ; // 4.1.2 - break ; - - case 5 : - add_triangle( tiling5[_config], 3 ) ; - break ; - - case 6 : - if( test_face( test6[_config][0]) ) - add_triangle( tiling6_2[_config], 5 ) ; // 6.2 - else - { - if( test_interior( test6[_config][1]) ) - add_triangle( tiling6_1_1[_config], 3 ) ; // 6.1.1 - else - add_triangle( tiling6_1_2[_config], 7 ) ; // 6.1.2 - } - break ; - - case 7 : - if( test_face( test7[_config][0] ) ) _subconfig += 1 ; - if( test_face( test7[_config][1] ) ) _subconfig += 2 ; - if( test_face( test7[_config][2] ) ) _subconfig += 4 ; - switch( _subconfig ) - { - case 0 : - add_triangle( tiling7_1[_config], 3 ) ; break ; - case 1 : - add_triangle( tiling7_2[_config][0], 5 ) ; break ; - case 2 : - add_triangle( tiling7_2[_config][1], 5 ) ; break ; - case 3 : - v12 = add_c_vertex() ; - add_triangle( tiling7_3[_config][0], 9, v12 ) ; break ; - case 4 : - add_triangle( tiling7_2[_config][2], 5 ) ; break ; - case 5 : - v12 = add_c_vertex() ; - add_triangle( tiling7_3[_config][1], 9, v12 ) ; break ; - case 6 : - v12 = add_c_vertex() ; - add_triangle( tiling7_3[_config][2], 9, v12 ) ; break ; - case 7 : - if( test_interior( test7[_config][3]) ) - add_triangle( tiling7_4_2[_config], 9 ) ; - else - add_triangle( tiling7_4_1[_config], 5 ) ; - break ; - }; - break ; - - case 8 : - add_triangle( tiling8[_config], 2 ) ; - break ; - - case 9 : - add_triangle( tiling9[_config], 4 ) ; - break ; - - case 10 : - if( test_face( test10[_config][0]) ) - { - if( test_face( test10[_config][1]) ) - add_triangle( tiling10_1_1_[_config], 4 ) ; // 10.1.1 - else - { - v12 = add_c_vertex() ; - add_triangle( tiling10_2[_config], 8, v12 ) ; // 10.2 - } - } - else - { - if( test_face( test10[_config][1]) ) - { - v12 = add_c_vertex() ; - add_triangle( tiling10_2_[_config], 8, v12 ) ; // 10.2 - } - else - { - if( test_interior( test10[_config][2]) ) - add_triangle( tiling10_1_1[_config], 4 ) ; // 10.1.1 - else - add_triangle( tiling10_1_2[_config], 8 ) ; // 10.1.2 - } - } - break ; - - case 11 : - add_triangle( tiling11[_config], 4 ) ; - break ; - - case 12 : - if( test_face( test12[_config][0]) ) - { - if( test_face( test12[_config][1]) ) - add_triangle( tiling12_1_1_[_config], 4 ) ; // 12.1.1 - else - { - v12 = add_c_vertex() ; - add_triangle( tiling12_2[_config], 8, v12 ) ; // 12.2 - } - } - else - { - if( test_face( test12[_config][1]) ) - { - v12 = add_c_vertex() ; - add_triangle( tiling12_2_[_config], 8, v12 ) ; // 12.2 - } - else - { - if( test_interior( test12[_config][2]) ) - add_triangle( tiling12_1_1[_config], 4 ) ; // 12.1.1 - else - add_triangle( tiling12_1_2[_config], 8 ) ; // 12.1.2 - } - } - break ; - - case 13 : - if( test_face( test13[_config][0] ) ) _subconfig += 1 ; - if( test_face( test13[_config][1] ) ) _subconfig += 2 ; - if( test_face( test13[_config][2] ) ) _subconfig += 4 ; - if( test_face( test13[_config][3] ) ) _subconfig += 8 ; - if( test_face( test13[_config][4] ) ) _subconfig += 16 ; - if( test_face( test13[_config][5] ) ) _subconfig += 32 ; - switch( subconfig13[_subconfig] ) - { - case 0 :/* 13.1 */ - add_triangle( tiling13_1[_config], 4 ) ; break ; - - case 1 :/* 13.2 */ - add_triangle( tiling13_2[_config][0], 6 ) ; break ; - case 2 :/* 13.2 */ - add_triangle( tiling13_2[_config][1], 6 ) ; break ; - case 3 :/* 13.2 */ - add_triangle( tiling13_2[_config][2], 6 ) ; break ; - case 4 :/* 13.2 */ - add_triangle( tiling13_2[_config][3], 6 ) ; break ; - case 5 :/* 13.2 */ - add_triangle( tiling13_2[_config][4], 6 ) ; break ; - case 6 :/* 13.2 */ - add_triangle( tiling13_2[_config][5], 6 ) ; break ; - - case 7 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][0], 10, v12 ) ; break ; - case 8 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][1], 10, v12 ) ; break ; - case 9 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][2], 10, v12 ) ; break ; - case 10 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][3], 10, v12 ) ; break ; - case 11 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][4], 10, v12 ) ; break ; - case 12 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][5], 10, v12 ) ; break ; - case 13 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][6], 10, v12 ) ; break ; - case 14 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][7], 10, v12 ) ; break ; - case 15 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][8], 10, v12 ) ; break ; - case 16 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][9], 10, v12 ) ; break ; - case 17 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][10], 10, v12 ) ; break ; - case 18 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][11], 10, v12 ) ; break ; - - case 19 :/* 13.4 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_4[_config][0], 12, v12 ) ; break ; - case 20 :/* 13.4 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_4[_config][1], 12, v12 ) ; break ; - case 21 :/* 13.4 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_4[_config][2], 12, v12 ) ; break ; - case 22 :/* 13.4 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_4[_config][3], 12, v12 ) ; break ; - - case 23 :/* 13.5 */ - _subconfig = 0 ; - if( test_interior( test13[_config][6] ) ) - add_triangle( tiling13_5_1[_config][0], 6 ) ; - else - add_triangle( tiling13_5_2[_config][0], 10 ) ; - break ; - case 24 :/* 13.5 */ - _subconfig = 1 ; - if( test_interior( test13[_config][6] ) ) - add_triangle( tiling13_5_1[_config][1], 6 ) ; - else - add_triangle( tiling13_5_2[_config][1], 10 ) ; - break ; - case 25 :/* 13.5 */ - _subconfig = 2 ; - if( test_interior( test13[_config][6] ) ) - add_triangle( tiling13_5_1[_config][2], 6 ) ; - else - add_triangle( tiling13_5_2[_config][2], 10 ) ; - break ; - case 26 :/* 13.5 */ - _subconfig = 3 ; - if( test_interior( test13[_config][6] ) ) - add_triangle( tiling13_5_1[_config][3], 6 ) ; - else - add_triangle( tiling13_5_2[_config][3], 10 ) ; - break ; - - case 27 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][0], 10, v12 ) ; break ; - case 28 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][1], 10, v12 ) ; break ; - case 29 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][2], 10, v12 ) ; break ; - case 30 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][3], 10, v12 ) ; break ; - case 31 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][4], 10, v12 ) ; break ; - case 32 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][5], 10, v12 ) ; break ; - case 33 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][6], 10, v12 ) ; break ; - case 34 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][7], 10, v12 ) ; break ; - case 35 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][8], 10, v12 ) ; break ; - case 36 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][9], 10, v12 ) ; break ; - case 37 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][10], 10, v12 ) ; break ; - case 38 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][11], 10, v12 ) ; break ; - - case 39 :/* 13.2 */ - add_triangle( tiling13_2_[_config][0], 6 ) ; break ; - case 40 :/* 13.2 */ - add_triangle( tiling13_2_[_config][1], 6 ) ; break ; - case 41 :/* 13.2 */ - add_triangle( tiling13_2_[_config][2], 6 ) ; break ; - case 42 :/* 13.2 */ - add_triangle( tiling13_2_[_config][3], 6 ) ; break ; - case 43 :/* 13.2 */ - add_triangle( tiling13_2_[_config][4], 6 ) ; break ; - case 44 :/* 13.2 */ - add_triangle( tiling13_2_[_config][5], 6 ) ; break ; - - case 45 :/* 13.1 */ - add_triangle( tiling13_1_[_config], 4 ) ; break ; - - default : - std::cerr<<" MarchingCubes<DataWrapper >::process_cube ["<<__LINE__<<"]: Impossible case 13?"<<std::endl; - print_cube(std::cerr); - } - break ; - - case 14 : - add_triangle( tiling14[_config], 4 ) ; - break ; - }; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Adding triangles -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::add_triangle( const char* trig, char n, int v12 ) -//----------------------------------------------------------------------------- -{ - int tv[3] ; - - for( int t = 0 ; t < 3*n ; t++ ) - { - switch( trig[t] ) - { - case 0 : tv[ t % 3 ] = get_x_vert( _i , _j , _k ) ; break ; - case 1 : tv[ t % 3 ] = get_y_vert(_i+1, _j , _k ) ; break ; - case 2 : tv[ t % 3 ] = get_x_vert( _i ,_j+1, _k ) ; break ; - case 3 : tv[ t % 3 ] = get_y_vert( _i , _j , _k ) ; break ; - case 4 : tv[ t % 3 ] = get_x_vert( _i , _j ,_k+1) ; break ; - case 5 : tv[ t % 3 ] = get_y_vert(_i+1, _j ,_k+1) ; break ; - case 6 : tv[ t % 3 ] = get_x_vert( _i ,_j+1,_k+1) ; break ; - case 7 : tv[ t % 3 ] = get_y_vert( _i , _j ,_k+1) ; break ; - case 8 : tv[ t % 3 ] = get_z_vert( _i , _j , _k ) ; break ; - case 9 : tv[ t % 3 ] = get_z_vert(_i+1, _j , _k ) ; break ; - case 10 : tv[ t % 3 ] = get_z_vert(_i+1,_j+1, _k ) ; break ; - case 11 : tv[ t % 3 ] = get_z_vert( _i ,_j+1, _k ) ; break ; - case 12 : tv[ t % 3 ] = v12 ; break ; - default : break ; - } - - if( tv[t%3] == -1 ) - { - std::cerr<<"Marching Cubes::add_triangle ["<<__LINE__<<"]: invalid triangle "<<_ntrigs+1<<std::endl; - print_cube(std::cerr) ; - } - - if( t%3 == 2 ) - { - if( _ntrigs >= _Ntrigs ) - { - Triangle *temp = _triangles ; - _triangles = new Triangle[ 2*_Ntrigs ] ; - memcpy( _triangles, temp, _Ntrigs*sizeof(Triangle) ) ; - delete[] temp ; - //std::cout<<_Ntrigs <<" allocated triangles"<<std::endl; - _Ntrigs *= 2 ; - } - - Triangle *T = _triangles + _ntrigs++ ; - T->v1 = tv[0] ; - T->v2 = tv[1] ; - T->v3 = tv[2] ; - } - } -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Calculating gradient - -template<typename DataWrapper > -real MarchingCubes<DataWrapper >::get_x_grad( const int i, const int j, const int k ) const -//----------------------------------------------------------------------------- -{ - if( i > 0 ) - { - if ( i < dataWrapper.getNX1() - 1 ) - return ( get_data( i+1, j, k ) - get_data( i-1, j, k ) ) / 2 ; - else - return get_data( i, j, k ) - get_data( i-1, j, k ) ; - } - else - return get_data( i+1, j, k ) - get_data( i, j, k ) ; -} -//----------------------------------------------------------------------------- - -template<typename DataWrapper > -real MarchingCubes<DataWrapper >::get_y_grad( const int i, const int j, const int k ) const -//----------------------------------------------------------------------------- -{ - if( j > 0 ) - { - if ( j < dataWrapper.getNX2() - 1 ) - return ( get_data( i, j+1, k ) - get_data( i, j-1, k ) ) / 2 ; - else - return get_data( i, j, k ) - get_data( i, j-1, k ) ; - } - else - return get_data( i, j+1, k ) - get_data( i, j, k ) ; -} -//----------------------------------------------------------------------------- - -template<typename DataWrapper > -real MarchingCubes<DataWrapper >::get_z_grad( const int i, const int j, const int k ) const -//----------------------------------------------------------------------------- -{ - if( k > 0 ) - { - if ( k < dataWrapper.getNX3() - 1 ) - return ( get_data( i, j, k+1 ) - get_data( i, j, k-1 ) ) / 2 ; - else - return get_data( i, j, k ) - get_data( i, j, k-1 ) ; - } - else - return get_data( i, j, k+1 ) - get_data( i, j, k ) ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Adding vertices - -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::test_vertex_addition() -{ - if( _nverts >= _Nverts ) - { - Vertex *temp = _vertices ; - _vertices = new Vertex[ _Nverts*2 ] ; - memcpy( _vertices, temp, _Nverts*sizeof(Vertex) ) ; - delete[] temp ; - //std::cout<<_Nverts<<" allocated vertices"<<std::endl; - _Nverts *= 2 ; - } -} - - -template<typename DataWrapper > -int MarchingCubes<DataWrapper >::add_x_vertex( ) -//----------------------------------------------------------------------------- -{ - test_vertex_addition() ; - Vertex *vert = _vertices + _nverts++ ; - - real u = ( _cube[0] ) / ( _cube[0] - _cube[1] ) ; - - vert->x = (real)_i+u; - vert->y = (real) _j ; - vert->z = (real) _k ; - - vert->nx = (1-u)*get_x_grad(_i,_j,_k) + u*get_x_grad(_i+1,_j,_k) ; - vert->ny = (1-u)*get_y_grad(_i,_j,_k) + u*get_y_grad(_i+1,_j,_k) ; - vert->nz = (1-u)*get_z_grad(_i,_j,_k) + u*get_z_grad(_i+1,_j,_k) ; - - u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ; - if( u > 0 ) - { - vert->nx /= u ; - vert->ny /= u ; - vert->nz /= u ; - } - - - return _nverts-1 ; -} -//----------------------------------------------------------------------------- - -template<typename DataWrapper > -int MarchingCubes<DataWrapper >::add_y_vertex( ) -//----------------------------------------------------------------------------- -{ - test_vertex_addition() ; - Vertex *vert = _vertices + _nverts++ ; - - real u = ( _cube[0] ) / ( _cube[0] - _cube[3] ) ; - - vert->x = (real) _i ; - vert->y = (real)_j+u; - vert->z = (real) _k ; - - vert->nx = (1-u)*get_x_grad(_i,_j,_k) + u*get_x_grad(_i,_j+1,_k) ; - vert->ny = (1-u)*get_y_grad(_i,_j,_k) + u*get_y_grad(_i,_j+1,_k) ; - vert->nz = (1-u)*get_z_grad(_i,_j,_k) + u*get_z_grad(_i,_j+1,_k) ; - - u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ; - if( u > 0 ) - { - vert->nx /= u ; - vert->ny /= u ; - vert->nz /= u ; - } - - return _nverts-1 ; -} -//----------------------------------------------------------------------------- - -template<typename DataWrapper > -int MarchingCubes<DataWrapper >::add_z_vertex( ) -//----------------------------------------------------------------------------- -{ - test_vertex_addition() ; - Vertex *vert = _vertices + _nverts++ ; - - real u = ( _cube[0] ) / ( _cube[0] - _cube[4] ) ; - - vert->x = (real) _i ; - vert->y = (real) _j ; - vert->z = (real)_k+u; - - vert->nx = (1-u)*get_x_grad(_i,_j,_k) + u*get_x_grad(_i,_j,_k+1) ; - vert->ny = (1-u)*get_y_grad(_i,_j,_k) + u*get_y_grad(_i,_j,_k+1) ; - vert->nz = (1-u)*get_z_grad(_i,_j,_k) + u*get_z_grad(_i,_j,_k+1) ; - - u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ; - if( u > 0 ) - { - vert->nx /= u ; - vert->ny /= u ; - vert->nz /= u ; - } - - return _nverts-1 ; -} - - -template<typename DataWrapper > -int MarchingCubes<DataWrapper >::add_c_vertex( ) -//----------------------------------------------------------------------------- -{ - test_vertex_addition() ; - Vertex *vert = _vertices + _nverts++ ; - - real u = 0 ; - int vid ; - - vert->x = vert->y = vert->z = vert->nx = vert->ny = vert->nz = 0 ; - - // Computes the average of the intersection points of the cube - vid = get_x_vert( _i , _j , _k ) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - vid = get_y_vert(_i+1, _j , _k ) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - vid = get_x_vert( _i ,_j+1, _k ) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - vid = get_y_vert( _i , _j , _k ) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - vid = get_x_vert( _i , _j ,_k+1) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - vid = get_y_vert(_i+1, _j ,_k+1) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - vid = get_x_vert( _i ,_j+1,_k+1) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - vid = get_y_vert( _i , _j ,_k+1) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - vid = get_z_vert( _i , _j , _k ) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - vid = get_z_vert(_i+1, _j , _k ) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - vid = get_z_vert(_i+1,_j+1, _k ) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - vid = get_z_vert( _i ,_j+1, _k ) ; - if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } - - vert->x /= u ; - vert->y /= u ; - vert->z /= u ; - - u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ; - if( u > 0 ) - { - vert->nx /= u ; - vert->ny /= u ; - vert->nz /= u ; - } - - return _nverts-1 ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Grid exportation -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::writeISO(const char *fn ) -//----------------------------------------------------------------------------- -{ - unsigned char buf[sizeof(float)] ; - - FILE *fp = fopen( fn, "wb" ) ; - - // header - * (int*) buf = dataWrapper.getNX1() ; - fwrite(buf, sizeof(float), 1, fp); - * (int*) buf = dataWrapper.getNX2() ; - fwrite(buf, sizeof(float), 1, fp); - * (int*) buf = dataWrapper.getNX3(); - fwrite(buf, sizeof(float), 1, fp); - - * (float*) buf = -1.0f ; - fwrite(buf, sizeof(float), 1, fp); - * (float*) buf = 1.0f ; - fwrite(buf, sizeof(float), 1, fp); - * (float*) buf = -1.0f ; - fwrite(buf, sizeof(float), 1, fp); - * (float*) buf = 1.0f ; - fwrite(buf, sizeof(float), 1, fp); - * (float*) buf = -1.0f ; - fwrite(buf, sizeof(float), 1, fp); - * (float*) buf = 1.0f ; - fwrite(buf, sizeof(float), 1, fp); - - for( int i = 0 ; i < dataWrapper.getNX1() ; i++ ) - { - for( int j = 0 ; j < dataWrapper.getNX2() ; j++ ) - { - for( int k = 0 ; k < dataWrapper.getNX3() ; k++ ) - { - * (float*) buf = (float)get_data( i,j,k ) ; - fwrite(buf, sizeof(float), 1, fp); - } - } - } - - fclose(fp) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// PLY exportation - -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::writePLY(const char *fn, bool bin ) -//----------------------------------------------------------------------------- -{ - - typedef struct PlyFace { - unsigned char nverts; /* number of Vertex indices in list */ - int *verts; /* Vertex index list */ - } PlyFace; - - - PlyProperty vert_props[] = { /* list of property information for a PlyVertex */ - {"x", Float32, Float32, offsetof( Vertex,x ), 0, 0, 0, 0}, - {"y", Float32, Float32, offsetof( Vertex,y ), 0, 0, 0, 0}, - {"z", Float32, Float32, offsetof( Vertex,z ), 0, 0, 0, 0}, - {"nx", Float32, Float32, offsetof( Vertex,nx ), 0, 0, 0, 0}, - {"ny", Float32, Float32, offsetof( Vertex,ny ), 0, 0, 0, 0}, - {"nz", Float32, Float32, offsetof( Vertex,nz ), 0, 0, 0, 0} - }; - - PlyProperty face_props[] = { /* list of property information for a PlyFace */ - {"vertex_indices", Int32, Int32, offsetof( PlyFace,verts ), - 1, Uint8, Uint8, offsetof( PlyFace,nverts )}, - }; - - - PlyFile *ply; - FILE *fp = fopen( fn, "w" ); - - int i ; - PlyFace face ; - int verts[3] ; - char *elem_names[] = { "vertex", "face" }; - std::cout<<"McCubes.MarchingCubes<DataWrapper >.writePLY ("<<fn<<")..."; - ply = write_ply ( fp, 2, elem_names, bin? PLY_BINARY_LE : PLY_ASCII ); - - /* describe what properties go into the PlyVertex elements */ - describe_element_ply ( ply, "vertex", _nverts ); - describe_property_ply ( ply, &vert_props[0] ); - describe_property_ply ( ply, &vert_props[1] ); - describe_property_ply ( ply, &vert_props[2] ); - describe_property_ply ( ply, &vert_props[3] ); - describe_property_ply ( ply, &vert_props[4] ); - describe_property_ply ( ply, &vert_props[5] ); - - /* describe PlyFace properties (just list of PlyVertex indices) */ - describe_element_ply ( ply, "face", _ntrigs ); - describe_property_ply ( ply, &face_props[0] ); - - header_complete_ply ( ply ); - - /* set up and write the PlyVertex elements */ - put_element_setup_ply ( ply, "vertex" ); - for ( i = 0; i < _nverts; i++ ) - put_element_ply ( ply, ( void * ) &(_vertices[i]) ); - std::cout<<_nverts<<" vertices written\n"; - - /* set up and write the PlyFace elements */ - put_element_setup_ply ( ply, "face" ); - face.nverts = 3 ; - face.verts = verts ; - for ( i = 0; i < _ntrigs; i++ ) - { - face.verts[0] = _triangles[i].v1 ; - face.verts[1] = _triangles[i].v2 ; - face.verts[2] = _triangles[i].v3 ; - put_element_ply ( ply, ( void * ) &face ); - } - std::cout<<_ntrigs<<" triangles written\n"; - - close_ply ( ply ); - free_ply ( ply ); - fclose( fp ) ; -} -//_____________________________________________________________________________ - -//_____________________________________________________________________________ -// Open Inventor / VRML 1.0 ascii exportation -template<typename DataWrapper > -void MarchingCubes<DataWrapper >::writeIV(const char *fn ) -//----------------------------------------------------------------------------- -{ - FILE *fp = fopen( fn, "w" ) ; - int i ; - - std::cout<<"Marching Cubes::exportIV("<<fn<<")..."; - - fprintf( fp, "#Inventor V2.1 ascii \n\nSeparator { \n ShapeHints {\n vertexOrdering COUNTERCLOCKWISE\n shapeType UNKNOWN_SHAPE_TYPE\n creaseAngle 0.0\n }\n Coordinate3 { \n point [ \n" ) ; - for ( i = 0; i < _nverts; i++ ) - fprintf( fp, " %f %f %f,\n", _vertices[i].x, _vertices[i].y, _vertices[i].z ) ; - std::cout<<_nverts<<" vertices written\n"; - - fprintf( fp, "\n ] \n} \nNormal { \nvector [ \n" ) ; - for ( i = 0; i < _nverts; i++ ) - fprintf( fp, " %f %f %f,\n", _vertices[i].nx, _vertices[i].ny, _vertices[i].nz ) ; - - fprintf( fp, "\n ] \n} \nIndexedFaceSet { \ncoordIndex [ \n" ) ; - for ( i = 0; i < _ntrigs; i++ ) - fprintf( fp, "%d, %d, %d, -1,\n", _triangles[i].v1, _triangles[i].v2, _triangles[i].v3 ) ; - - fprintf( fp, " ] \n } \n } \n" ) ; - fclose( fp ) ; - std::cout<<_ntrigs<<" triangles written\n"; -} - -/*=======================================================================*/ -template<typename DataWrapper > -void MarchingCubes< DataWrapper >::writeUCD( std::string filename ) -{ - std::cout<<"MarchingCubes::writeUCD("<<filename<<")..."; - - //Dreiecke in UCD Datei schreiben - std::ofstream out(filename.c_str()); - if(!out) throw UbException(UB_EXARGS,"couldn't open "+filename); - - out<<"# UCD-File containing triangulated geometry data"<<std::endl; - out<<this->nverts()<<" "<<this->ntrigs()<<" 0 0 0"<<std::endl; - - int count = 1; - for(int k=0;k<this->nverts();k++) - out<<count++<<" "<<_vertices[k].x<<" "<<_vertices[k].y<<" "<<_vertices[k].z<<std::endl; - - count = 1; - for(int k=0;k<this->ntrigs();k++) - out<<count++<<" "<<"1"<<" tri "<<_triangles[k].v1+1<<" " <<_triangles[k].v2+1<<" "<<_triangles[k].v3+1<<std::endl; - - out.flush(); - out.close(); - std::cout<<"done\n"; - -} - -template<typename DataWrapper > -void MarchingCubes< DataWrapper >::writeUCDwithNormals( std::string filename) -{ - std::cout<<"MarchingCubes::writeUCDwithNormals("<<filename<<")..."; - - //Dreiecke in UCD Datei schreiben - std::ofstream out(filename.c_str()); - if(!out) throw UbException(UB_EXARGS,"couldn't open "+filename); - - out<<"# UCD-File containing triangulated geometry data an vertex normals"<<std::endl; - out<<2*this->nverts()<<" "<<this->ntrigs()+this->nverts()<<" 0 0 0"<<std::endl; - - int count = 1; - for(int k=0;k<this->nverts();k++) out<<count++<<" "<<_vertices[k].x+_vertices[k].nx<<" "<<_vertices[k].y+_vertices[k].ny<<" "<<_vertices[k].z+_vertices[k].nz<<std::endl; - for(int k=0;k<this->nverts();k++) out<<count++<<" "<<_vertices[k].x+_vertices[k].nx<<" "<<_vertices[k].y+_vertices[k].ny<<" "<<_vertices[k].z+_vertices[k].nz<<std::endl; - - count = 1; - for(int k=0;k<this->ntrigs();k++) - out<<count++<<" "<<"1"<<" tri "<<_triangles[k].v1+1<<" " <<_triangles[k].v2+1<<" "<<_triangles[k].v3+1<<std::endl; - - for(int k=0;k<this->nverts();k++) - out<<count++<<" "<< "1"<<" line "<<k+1<<" " <<this->nverts()+k+1<<" "<<std::endl; - - out.flush(); - out.close(); - std::cout<<"done\n"; -} - -} //namespace McCubes - -#endif // _MARCHINGCUBES_H_ diff --git a/3rdParty/MarchingCubes/Matrix3DWrapper.h b/3rdParty/MarchingCubes/Matrix3DWrapper.h deleted file mode 100644 index 159b5d53c416032ec0ff2f2672fb962036ea2449..0000000000000000000000000000000000000000 --- a/3rdParty/MarchingCubes/Matrix3DWrapper.h +++ /dev/null @@ -1,126 +0,0 @@ -// _ ___ __ __________ _ __ -// | | / (_)____/ /___ ______ _/ / ____/ /_ __(_)___/ /____ -// | | / / / ___/ __/ / / / __ `/ / /_ / / / / / / __ / ___/ -// | |/ / / / / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__ ) -// |___/_/_/ \__/\__,_/\__,_/_/_/ /_/\__,_/_/\__,_/____/ -// -#ifndef MATRIX3DWRAPPER_H -#define MATRIX3DWRAPPER_H - -//extension by CAB -#include <vector> -#include <string> -#include <fstream> - -#include <basics/utilities/UbException.h> -#include <MarchingCubes/McTypes.h> - -//neu: matrix muss lediglich double operator()(int x1, int x2, int x3) ueberladen, dann kann man sie verwenden!! - -////////////////////////////////////////////////////////////////////////// -//Matrix3DWrapper-Wrapper -// CbUniformMatrix3D<double> data(10,8,5); -// for(int x3=0; x3<data.getNX3(); x3++) -// for(int x2=0; x2<data.getNX2(); x2++) -// for(int x1=0; x1<data.getNX1(); x1++) -// data(x1,x2,x3) = x1; -// -// Matrix3DWrapper< CbUniformMatrix3D<double> > wrapper(&data); -// MarchingCubes< Matrix3DWrapper< CbUniformMatrix3D<double> > > mc( wrapper ); -// -// mc.init_all(); -// mc.run(3.5); -// mc.writeUCD("c:/temp/triangles.inp"); -// mc.clean_all(); - -namespace McCubes{ - -template< typename Matrix3D > -class Matrix3DWrapper -{ -public: - Matrix3DWrapper() - : matrix(NULL) - , minX1(-1), minX2(-1), minX3(-1) - , maxX1(-1), maxX2(-1), maxX3(-1) - , nx1(-1) , nx2(-1) , nx3(-1) - { - //wird benoetigt, damit MarchingCubes generell eine membervariabel erstellen kann - } - /*==========================================================*/ - Matrix3DWrapper( Matrix3D* matrix) - : matrix(matrix) - { - nx1 = (int)matrix->getNX1(); - nx2 = (int)matrix->getNX2(); - nx3 = (int)matrix->getNX3(); - - minX1 = minX2 = minX3 = 0; - maxX1 = nx1-1; - maxX2 = nx2-1; - maxX3 = nx3-1; - } - /*==========================================================*/ - Matrix3DWrapper( Matrix3D* matrix, const int& n1, const int& nx2, const int& nx3) - : matrix(matrix) - , nx1(nx1), nx2(nx2), nx3(nx3) - { - minX1 = minX2 = minX3 = 0; - maxX1 = nx1-1; - maxX2 = nx2-1; - maxX3 = nx3-1; - } - /*==========================================================*/ - Matrix3DWrapper( Matrix3D* matrix, const int& minX1, const int& minX2, const int& minX3 - , const int& maxX1, const int& maxX2, const int& maxX3 ) - : matrix(matrix) - , minX1(minX1), minX2(minX2), minX3(minX3) - , maxX1(maxX1), maxX2(maxX2), maxX3(maxX3) - { - nx1 = matrix->getNX1(); - nx2 = matrix->getNX2(); - nx3 = matrix->getNX3(); - - if(minX1<0 || minX2<0 || minX3<0 || maxX1>=nx1 || maxX2>=nx2 || maxX3>=nx3) - throw UbException(UB_EXARGS,"range error"); - } - /*==========================================================*/ - //wenn man z.B. matrixX1 von[0..10] geht und man nur den bereich 1..9 fuer MC - //verwenden moechte -> minX1=1 und maxX2=2 - Matrix3DWrapper( Matrix3D* matrix, const int& minX1, const int& minX2, const int& minX3 - , const int& maxX1, const int& maxX2, const int& maxX3 - , const int& n1 , const int& nx2 , const int& nx3 ) - : matrix(matrix) - , minX1(minX1), minX2(minX2), minX3(minX3) - , maxX1(maxX1), maxX2(maxX2), maxX3(maxX3) - , nx1(n1) , nx2(nx2) , nx3(nx3) - { - if(minX1<0 || minX2<0 || minX3<0 || maxX1>=nx1 || maxX2>=nx2 || maxX3>=nx3) - throw UbException(UB_EXARGS,"range error"); - } - /*==========================================================*/ - inline real getData(const int& x1, const int& x2, const int& x3 ) const - { - return static_cast<real>( (*matrix)(x1, x2, x3) ); - } - /*==========================================================*/ - inline int getMinX1() const { return minX1; } - inline int getMinX2() const { return minX2; } - inline int getMinX3() const { return minX3; } - - inline int getMaxX1() const { return maxX1; } - inline int getMaxX2() const { return maxX2; } - inline int getMaxX3() const { return maxX3; } - - inline int getNX1() const { return nx1; } - inline int getNX2() const { return nx2; } - inline int getNX3() const { return nx3; } - -protected: - Matrix3D* matrix; - int minX1, minX2, minX3, maxX1, maxX2, maxX3, nx1, nx2, nx3; -}; - -} //namespace McCubes - -#endif //MATRIX3DWRAPPER_H diff --git a/3rdParty/MarchingCubes/Matrix4DWrapper.h b/3rdParty/MarchingCubes/Matrix4DWrapper.h deleted file mode 100644 index dda3e3fb92e386c817940e54b113831823a13179..0000000000000000000000000000000000000000 --- a/3rdParty/MarchingCubes/Matrix4DWrapper.h +++ /dev/null @@ -1,131 +0,0 @@ -// _ ___ __ __________ _ __ -// | | / (_)____/ /___ ______ _/ / ____/ /_ __(_)___/ /____ -// | | / / / ___/ __/ / / / __ `/ / /_ / / / / / / __ / ___/ -// | |/ / / / / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__ ) -// |___/_/_/ \__/\__,_/\__,_/_/_/ /_/\__,_/_/\__,_/____/ -// -#ifndef MATRIX4DWRAPPER_H -#define MATRIX4DWRAPPER_H - -//extension by CAB -#include <vector> -#include <string> -#include <fstream> - -#include <basics/utilities/UbException.h> -#include <MarchingCubes/McTypes.h> - -//neu: matrix muss lediglich double operator()(int x1, int x2, int x3, int x4) ueberladen, dann kann man sie verwenden!! - -////////////////////////////////////////////////////////////////////////// -//Matrix4DWrapper-Wrapper -//example: -// int indexForDataValue = 1; -// CbUniformMatrix4D<double> data(10,8,5,2); -// for(int x3=0; x3<data.getNX3(); x3++) -// for(int x2=0; x2<data.getNX2(); x2++) -// for(int x1=0; x1<data.getNX1(); x1++) -// data(x1,x2,x3,indexForDataValue) = x1; -// -// Matrix4DWrapper< CbUniformMatrix4D<double> > wrapper(&data,indexForDataValue); -// MarchingCubes< Matrix4DWrapper< CbUniformMatrix4D<double> > > mc( wrapper ); -// -// mc.init_all(); -// mc.run(3.5); -// mc.writeUCD("c:/temp/triangles.inp"); -// mc.clean_all(); - -namespace McCubes{ - -template< typename Matrix4D > -class Matrix4DWrapper -{ -public: - Matrix4DWrapper() - : valIndex(-1), matrix(NULL) - , minX1(-1), minX2(-1), minX3(-1) - , maxX1(-1), maxX2(-1), maxX3(-1) - , nx1(-1) , nx2(-1) , nx3(-1) - { - //wird benoetigt, damit MarchingCubes generell eine membervariabel erstellen kann - } - /*==========================================================*/ - Matrix4DWrapper( Matrix4D* matrix, const int& valIndex,const int& n1, const int& nx2, const int& nx3) - : valIndex(valIndex), matrix(matrix) - , nx1(nx1), nx2(nx2), nx3(nx3) - { - minX1 = minX2 = minX3 = 0; - maxX1 = nx1-1; - maxX2 = nx2-1; - maxX3 = nx3-1; - } - /*==========================================================*/ - Matrix4DWrapper( Matrix4D* matrix, const int& valIndex) - : valIndex(valIndex), matrix(matrix) - { - nx1 = matrix->getNX1(); - nx2 = matrix->getNX2(); - nx3 = matrix->getNX3(); - - minX1 = minX2 = minX3 = 0; - maxX1 = nx1-1; - maxX2 = nx2-1; - maxX3 = nx3-1; - } - /*==========================================================*/ - //wenn man z.B. matrixX1 von[0..10] geht und man nur den bereich 1..9 fuer MC - //verwenden moechte -> minX1=1 und maxX2=2 - Matrix4DWrapper( Matrix4D* matrix, const int& valIndex, const int& minX1, const int& minX2, const int& minX3, - const int& maxX1, const int& maxX2, const int& maxX3) - : valIndex(valIndex), matrix(matrix) - , minX1(minX1), minX2(minX2), minX3(minX3) - , maxX1(maxX1), maxX2(maxX2), maxX3(maxX3) - { - nx1 = matrix->getNX1(); - nx2 = matrix->getNX2(); - nx3 = matrix->getNX3(); - - if(minX1<0 || minX2<0 || minX3<0 || maxX1>=nx1 || maxX2>=nx2 || maxX3>=nx3) - throw UbException(UB_EXARGS,"range error"); - } - /*==========================================================*/ - //wenn man z.B. matrixX1 von[0..10] geht und man nur den bereich 1..9 fuer MC - //verwenden moechte -> minX1=1 und maxX2=2 - Matrix4DWrapper( Matrix4D* matrix, const int& valIndex, const int& minX1, const int& minX2, const int& minX3 - , const int& maxX1, const int& maxX2, const int& maxX3 - , const int& n1 , const int& nx2 , const int& nx3 ) - : valIndex(valIndex), matrix(matrix) - , minX1(minX1), minX2(minX2), minX3(minX3) - , maxX1(maxX1), maxX2(maxX2), maxX3(maxX3) - , nx1(nx1) , nx2(nx2) , nx3(nx3) - { - if(minX1<0 || minX2<0 || minX3<0 || maxX1>=nx1 || maxX2>=nx2 || maxX3>=nx3) - throw UbException(UB_EXARGS,"range error"); - } - /*==========================================================*/ - inline real getData(const int& x1, const int& x2, const int& x3 ) const - { - return static_cast<real>( (*matrix)(x1, x2, x3, valIndex) ); - } - /*==========================================================*/ - inline int getMinX1() const { return minX1; } - inline int getMinX2() const { return minX2; } - inline int getMinX3() const { return minX3; } - - inline int getMaxX1() const { return maxX1; } - inline int getMaxX2() const { return maxX2; } - inline int getMaxX3() const { return maxX3; } - - inline int getNX1() const { return nx1; } - inline int getNX2() const { return nx2; } - inline int getNX3() const { return nx3; } - -protected: - int valIndex; - Matrix4D* matrix; - int minX1, minX2, minX3, maxX1, maxX2, maxX3, nx1, nx2, nx3; -}; - -} //namespace McCubes - -#endif //MATRIX4DWRAPPER_H diff --git a/3rdParty/MarchingCubes/MatrixWrapper.h b/3rdParty/MarchingCubes/MatrixWrapper.h deleted file mode 100644 index c787fa77ffd59014f6a542a66916c9784aa6c7d0..0000000000000000000000000000000000000000 --- a/3rdParty/MarchingCubes/MatrixWrapper.h +++ /dev/null @@ -1,131 +0,0 @@ -// _ ___ __ __________ _ __ -// | | / (_)____/ /___ ______ _/ / ____/ /_ __(_)___/ /____ -// | | / / / ___/ __/ / / / __ `/ / /_ / / / / / / __ / ___/ -// | |/ / / / / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__ ) -// |___/_/_/ \__/\__,_/\__,_/_/_/ /_/\__,_/_/\__,_/____/ -// -#ifndef MATRIXWRAPPER_H -#define MATRIXWRAPPER_H - -//extension by CAB -#include <vector> -#include <string> -#include <fstream> - -#include <basics/utilities/UbException.h> - -#include <MarchingCubes/McTypes.h> - -////////////////////////////////////////////////////////////////////////// -//Standard-Wrapper -// MarchingCubes<DataWrapper> mc( 10,8,5 ); -// for(int z=0; z<mc.size_z(); z++) -// for(int y=0; y<mc.size_y(); y++) -// for(int x=0; x<mc.size_x(); x++) -// mc.set_data(x,x,y,z); -// -// mc.init_all(); -// mc.run(3.5); -// mc.writeUCD("c:/temp/triangles.inp"); -// mc.clean_all(); - -namespace McCubes{ - -template< typename T=real > -class MatrixWrapper -{ -public: - typedef T value_type; - typedef typename std::vector< value_type >::reference reference; - typedef typename std::vector< value_type >::const_reference const_reference; - typedef typename std::vector< value_type >::pointer pointer; - typedef typename std::vector< value_type >::const_pointer const_pointer; - -public: - MatrixWrapper() : nx1(-1), nx2(-1), nx3(-1) - { - } - /*==========================================================*/ - MatrixWrapper(const int& nx1, const int& nx2, const int& nx3, const T& initVal=T()) - { - this->resize(nx1,nx2,nx3,initVal); - } - /*=======================================================================*/ - reference operator() (const int& x1, const int& x2, const int& x3) - { - #ifdef _DEBUG - return this->data.at(x1 + x2*nx1 + x3*nx1*nx2); - #else - return this->data[x1 + x2*nx1 + x3*nx1*nx2]; - #endif - } - /*=======================================================================*/ - const_reference operator() (const int& x1, const int& x2, const int& x3) const - { - #ifdef _DEBUG - return this->data.at(x1 + x2*nx1 + x3*nx1*nx2); - #else - return this->data[x1 + x2*nx1 + x3*nx1*nx2]; - #endif - } - /*==========================================================*/ - inline void setData( const T& val, const int& x1, const int& x2, const int& x3 ) - { - #ifdef _DEBUG - this->data.at(x1 + x2*nx1 + x3*nx1*nx2) = val; - #else - this->data[x1 + x2*nx1 + x3*nx1*nx2] = val; - #endif - } - /*==========================================================*/ - inline value_type getData(const int& x1, const int& x2, const int& x3 ) const - { - #ifdef _DEBUG - return this->data.at(x1 + x2*nx1 + x3*nx1*nx2); - #else - return this->data[x1 + x2*nx1 + x3*nx1*nx2]; - #endif - } - /*==========================================================*/ - inline void resize(const int& nx1, const int& nx2, const int& nx3) - { - if(nx1>0 && nx2>0 && nx3>0) - { - this->nx1 = nx1; - this->nx2 = nx2; - this->nx3 = nx3; - this->data.resize(nx1*nx2*nx3); - } - } - /*==========================================================*/ - inline void resize(const int& nx1, const int& nx2, const int& nx3, const T& initVal) - { - if(nx1>0 && nx2>0 && nx3>0) - { - this->nx1 = nx1; - this->nx2 = nx2; - this->nx3 = nx3; - this->data.resize(nx1*nx2*nx3,initVal); - } - } - /*==========================================================*/ - inline int getMinX1() const { return 0; } - inline int getMinX2() const { return 0; } - inline int getMinX3() const { return 0; } - - inline int getMaxX1() const { return nx1-1; } - inline int getMaxX2() const { return nx2-1; } - inline int getMaxX3() const { return nx3-1; } - - inline int getNX1() const { return nx1; } - inline int getNX2() const { return nx2; } - inline int getNX3() const { return nx3; } - -protected: - std::vector<T> data; - int nx1, nx2, nx3; -}; - -} //namespace McCubes - -#endif //MATRIXWRAPPER_H diff --git a/3rdParty/MarchingCubes/McLookUpTable.h b/3rdParty/MarchingCubes/McLookUpTable.h deleted file mode 100644 index 00983bb1b1147f56d3565201fab6a7909530219b..0000000000000000000000000000000000000000 --- a/3rdParty/MarchingCubes/McLookUpTable.h +++ /dev/null @@ -1,2320 +0,0 @@ -/** - * @file LookUpTable.h - * @author Thomas Lewiner <thomas.lewiner@polytechnique.org> - * @author Math Dept, PUC-Rio - * @version 0.2 - * @date 12/08/2002 - * - * @brief LookUpTable for the MarchingCubes 33 Algorithm - */ -//________________________________________________ - - - -#ifndef MCLOOKUPTABLE_H -#define MCLOOKUPTABLE_H - -namespace McCubes{ - -//_____________________________________________________________________________ -/** - * \brief case mapping - * For each of the possible vertex states listed in this table there is a - * specific triangulation of the edge intersection points. The table lists - * all of them in the form of 0-5 edge triples with the list terminated by - * the invalid value -1. For example: case[3] list the 2 triangles - * formed when cube[0] and cube[1] are inside of the surface, but the rest of - * the cube is not. - * - * Cube description: - * 7 ________ 6 _____6__ ________ - * /| /| 7/| /| /| /| - * / | / | / | /5 | / 6 / | - * 4 /_______ / | /__4____ / 10 /_______3/ | - * | | |5 | | 11 | | | | | 2 | - * | 3|__|_____|2 | |__|__2__| | 4 |__|_____| - * | / | / 8 3/ 9 / | / | / - * | / | / | / | /1 | / 5 / - * |/_______|/ |/___0___|/ |/_1_____|/ - * 0 1 0 1 - */ -//----------------------------------------------------------------------------- -static const char cases[256][2] = { -/* 0: */ { 0, -1 }, -/* 1: 0, */ { 1, 0 }, -/* 2: 1, */ { 1, 1 }, -/* 3: 0, 1, */ { 2, 0 }, -/* 4: 2, */ { 1, 2 }, -/* 5: 0, 2, */ { 3, 0 }, -/* 6: 1, 2, */ { 2, 3 }, -/* 7: 0, 1, 2, */ { 5, 0 }, -/* 8: 3, */ { 1, 3 }, -/* 9: 0, 3, */ { 2, 1 }, -/* 10: 1, 3, */ { 3, 3 }, -/* 11: 0, 1, 3, */ { 5, 1 }, -/* 12: 2, 3, */ { 2, 5 }, -/* 13: 0, 2, 3, */ { 5, 4 }, -/* 14: 1, 2, 3, */ { 5, 9 }, -/* 15: 0, 1, 2, 3, */ { 8, 0 }, -/* 16: 4, */ { 1, 4 }, -/* 17: 0, 4, */ { 2, 2 }, -/* 18: 1, 4, */ { 3, 4 }, -/* 19: 0, 1, 4, */ { 5, 2 }, -/* 20: 2, 4, */ { 4, 2 }, -/* 21: 0, 2, 4, */ { 6, 2 }, -/* 22: 1, 2, 4, */ { 6, 9 }, -/* 23: 0, 1, 2, 4, */ { 11, 0 }, -/* 24: 3, 4, */ { 3, 8 }, -/* 25: 0, 3, 4, */ { 5, 5 }, -/* 26: 1, 3, 4, */ { 7, 3 }, -/* 27: 0, 1, 3, 4, */ { 9, 1 }, -/* 28: 2, 3, 4, */ { 6, 16 }, -/* 29: 0, 2, 3, 4, */ { 14, 3 }, -/* 30: 1, 2, 3, 4, */ { 12, 12 }, -/* 31: 0, 1, 2, 3, 4, */ { 5, 24 }, -/* 32: 5, */ { 1, 5 }, -/* 33: 0, 5, */ { 3, 1 }, -/* 34: 1, 5, */ { 2, 4 }, -/* 35: 0, 1, 5, */ { 5, 3 }, -/* 36: 2, 5, */ { 3, 6 }, -/* 37: 0, 2, 5, */ { 7, 0 }, -/* 38: 1, 2, 5, */ { 5, 10 }, -/* 39: 0, 1, 2, 5, */ { 9, 0 }, -/* 40: 3, 5, */ { 4, 3 }, -/* 41: 0, 3, 5, */ { 6, 4 }, -/* 42: 1, 3, 5, */ { 6, 11 }, -/* 43: 0, 1, 3, 5, */ { 14, 1 }, -/* 44: 2, 3, 5, */ { 6, 17 }, -/* 45: 0, 2, 3, 5, */ { 12, 4 }, -/* 46: 1, 2, 3, 5, */ { 11, 6 }, -/* 47: 0, 1, 2, 3, 5, */ { 5, 25 }, -/* 48: 4, 5, */ { 2, 8 }, -/* 49: 0, 4, 5, */ { 5, 7 }, -/* 50: 1, 4, 5, */ { 5, 12 }, -/* 51: 0, 1, 4, 5, */ { 8, 1 }, -/* 52: 2, 4, 5, */ { 6, 18 }, -/* 53: 0, 2, 4, 5, */ { 12, 5 }, -/* 54: 1, 2, 4, 5, */ { 14, 7 }, -/* 55: 0, 1, 2, 4, 5, */ { 5, 28 }, -/* 56: 3, 4, 5, */ { 6, 21 }, -/* 57: 0, 3, 4, 5, */ { 11, 4 }, -/* 58: 1, 3, 4, 5, */ { 12, 15 }, -/* 59: 0, 1, 3, 4, 5, */ { 5, 30 }, -/* 60: 2, 3, 4, 5, */ { 10, 5 }, -/* 61: 0, 2, 3, 4, 5, */ { 6, 32 }, -/* 62: 1, 2, 3, 4, 5, */ { 6, 39 }, -/* 63: 0, 1, 2, 3, 4, 5, */ { 2, 12 }, -/* 64: 6, */ { 1, 6 }, -/* 65: 0, 6, */ { 4, 0 }, -/* 66: 1, 6, */ { 3, 5 }, -/* 67: 0, 1, 6, */ { 6, 0 }, -/* 68: 2, 6, */ { 2, 6 }, -/* 69: 0, 2, 6, */ { 6, 3 }, -/* 70: 1, 2, 6, */ { 5, 11 }, -/* 71: 0, 1, 2, 6, */ { 14, 0 }, -/* 72: 3, 6, */ { 3, 9 }, -/* 73: 0, 3, 6, */ { 6, 5 }, -/* 74: 1, 3, 6, */ { 7, 4 }, -/* 75: 0, 1, 3, 6, */ { 12, 1 }, -/* 76: 2, 3, 6, */ { 5, 14 }, -/* 77: 0, 2, 3, 6, */ { 11, 3 }, -/* 78: 1, 2, 3, 6, */ { 9, 4 }, -/* 79: 0, 1, 2, 3, 6, */ { 5, 26 }, -/* 80: 4, 6, */ { 3, 10 }, -/* 81: 0, 4, 6, */ { 6, 6 }, -/* 82: 1, 4, 6, */ { 7, 5 }, -/* 83: 0, 1, 4, 6, */ { 12, 2 }, -/* 84: 2, 4, 6, */ { 6, 19 }, -/* 85: 0, 2, 4, 6, */ { 10, 1 }, -/* 86: 1, 2, 4, 6, */ { 12, 13 }, -/* 87: 0, 1, 2, 4, 6, */ { 6, 24 }, -/* 88: 3, 4, 6, */ { 7, 7 }, -/* 89: 0, 3, 4, 6, */ { 12, 9 }, -/* 90: 1, 3, 4, 6, */ { 13, 1 }, -/* 91: 0, 1, 3, 4, 6, */ { 7, 9 }, -/* 92: 2, 3, 4, 6, */ { 12, 20 }, -/* 93: 0, 2, 3, 4, 6, */ { 6, 33 }, -/* 94: 1, 2, 3, 4, 6, */ { 7, 13 }, -/* 95: 0, 1, 2, 3, 4, 6, */ { 3, 12 }, -/* 96: 5, 6, */ { 2, 10 }, -/* 97: 0, 5, 6, */ { 6, 7 }, -/* 98: 1, 5, 6, */ { 5, 13 }, -/* 99: 0, 1, 5, 6, */ { 11, 2 }, -/* 100: 2, 5, 6, */ { 5, 16 }, -/* 101: 0, 2, 5, 6, */ { 12, 7 }, -/* 102: 1, 2, 5, 6, */ { 8, 3 }, -/* 103: 0, 1, 2, 5, 6, */ { 5, 29 }, -/* 104: 3, 5, 6, */ { 6, 22 }, -/* 105: 0, 3, 5, 6, */ { 10, 2 }, -/* 106: 1, 3, 5, 6, */ { 12, 17 }, -/* 107: 0, 1, 3, 5, 6, */ { 6, 27 }, -/* 108: 2, 3, 5, 6, */ { 14, 9 }, -/* 109: 0, 2, 3, 5, 6, */ { 6, 34 }, -/* 110: 1, 2, 3, 5, 6, */ { 5, 39 }, -/* 111: 0, 1, 2, 3, 5, 6, */ { 2, 14 }, -/* 112: 4, 5, 6, */ { 5, 20 }, -/* 113: 0, 4, 5, 6, */ { 14, 5 }, -/* 114: 1, 4, 5, 6, */ { 9, 5 }, -/* 115: 0, 1, 4, 5, 6, */ { 5, 32 }, -/* 116: 2, 4, 5, 6, */ { 11, 10 }, -/* 117: 0, 2, 4, 5, 6, */ { 6, 35 }, -/* 118: 1, 2, 4, 5, 6, */ { 5, 41 }, -/* 119: 0, 1, 2, 4, 5, 6, */ { 2, 16 }, -/* 120: 3, 4, 5, 6, */ { 12, 23 }, -/* 121: 0, 3, 4, 5, 6, */ { 6, 37 }, -/* 122: 1, 3, 4, 5, 6, */ { 7, 14 }, -/* 123: 0, 1, 3, 4, 5, 6, */ { 3, 16 }, -/* 124: 2, 3, 4, 5, 6, */ { 6, 46 }, -/* 125: 0, 2, 3, 4, 5, 6, */ { 4, 6 }, -/* 126: 1, 2, 3, 4, 5, 6, */ { 3, 21 }, -/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 1, 8 }, -/* 128: 7, */ { 1, 7 }, -/* 129: 0, 7, */ { 3, 2 }, -/* 130: 1, 7, */ { 4, 1 }, -/* 131: 0, 1, 7, */ { 6, 1 }, -/* 132: 2, 7, */ { 3, 7 }, -/* 133: 0, 2, 7, */ { 7, 1 }, -/* 134: 1, 2, 7, */ { 6, 10 }, -/* 135: 0, 1, 2, 7, */ { 12, 0 }, -/* 136: 3, 7, */ { 2, 7 }, -/* 137: 0, 3, 7, */ { 5, 6 }, -/* 138: 1, 3, 7, */ { 6, 12 }, -/* 139: 0, 1, 3, 7, */ { 11, 1 }, -/* 140: 2, 3, 7, */ { 5, 15 }, -/* 141: 0, 2, 3, 7, */ { 9, 2 }, -/* 142: 1, 2, 3, 7, */ { 14, 6 }, -/* 143: 0, 1, 2, 3, 7, */ { 5, 27 }, -/* 144: 4, 7, */ { 2, 9 }, -/* 145: 0, 4, 7, */ { 5, 8 }, -/* 146: 1, 4, 7, */ { 6, 13 }, -/* 147: 0, 1, 4, 7, */ { 14, 2 }, -/* 148: 2, 4, 7, */ { 6, 20 }, -/* 149: 0, 2, 4, 7, */ { 12, 6 }, -/* 150: 1, 2, 4, 7, */ { 10, 3 }, -/* 151: 0, 1, 2, 4, 7, */ { 6, 25 }, -/* 152: 3, 4, 7, */ { 5, 18 }, -/* 153: 0, 3, 4, 7, */ { 8, 2 }, -/* 154: 1, 3, 4, 7, */ { 12, 16 }, -/* 155: 0, 1, 3, 4, 7, */ { 5, 31 }, -/* 156: 2, 3, 4, 7, */ { 11, 9 }, -/* 157: 0, 2, 3, 4, 7, */ { 5, 34 }, -/* 158: 1, 2, 3, 4, 7, */ { 6, 40 }, -/* 159: 0, 1, 2, 3, 4, 7, */ { 2, 13 }, -/* 160: 5, 7, */ { 3, 11 }, -/* 161: 0, 5, 7, */ { 7, 2 }, -/* 162: 1, 5, 7, */ { 6, 14 }, -/* 163: 0, 1, 5, 7, */ { 12, 3 }, -/* 164: 2, 5, 7, */ { 7, 6 }, -/* 165: 0, 2, 5, 7, */ { 13, 0 }, -/* 166: 1, 2, 5, 7, */ { 12, 14 }, -/* 167: 0, 1, 2, 5, 7, */ { 7, 8 }, -/* 168: 3, 5, 7, */ { 6, 23 }, -/* 169: 0, 3, 5, 7, */ { 12, 10 }, -/* 170: 1, 3, 5, 7, */ { 10, 4 }, -/* 171: 0, 1, 3, 5, 7, */ { 6, 28 }, -/* 172: 2, 3, 5, 7, */ { 12, 21 }, -/* 173: 0, 2, 3, 5, 7, */ { 7, 10 }, -/* 174: 1, 2, 3, 5, 7, */ { 6, 41 }, -/* 175: 0, 1, 2, 3, 5, 7, */ { 3, 13 }, -/* 176: 4, 5, 7, */ { 5, 21 }, -/* 177: 0, 4, 5, 7, */ { 9, 3 }, -/* 178: 1, 4, 5, 7, */ { 11, 8 }, -/* 179: 0, 1, 4, 5, 7, */ { 5, 33 }, -/* 180: 2, 4, 5, 7, */ { 12, 22 }, -/* 181: 0, 2, 4, 5, 7, */ { 7, 11 }, -/* 182: 1, 2, 4, 5, 7, */ { 6, 42 }, -/* 183: 0, 1, 2, 4, 5, 7, */ { 3, 14 }, -/* 184: 3, 4, 5, 7, */ { 14, 11 }, -/* 185: 0, 3, 4, 5, 7, */ { 5, 36 }, -/* 186: 1, 3, 4, 5, 7, */ { 6, 44 }, -/* 187: 0, 1, 3, 4, 5, 7, */ { 2, 17 }, -/* 188: 2, 3, 4, 5, 7, */ { 6, 47 }, -/* 189: 0, 2, 3, 4, 5, 7, */ { 3, 18 }, -/* 190: 1, 2, 3, 4, 5, 7, */ { 4, 7 }, -/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 1, 9 }, -/* 192: 6, 7, */ { 2, 11 }, -/* 193: 0, 6, 7, */ { 6, 8 }, -/* 194: 1, 6, 7, */ { 6, 15 }, -/* 195: 0, 1, 6, 7, */ { 10, 0 }, -/* 196: 2, 6, 7, */ { 5, 17 }, -/* 197: 0, 2, 6, 7, */ { 12, 8 }, -/* 198: 1, 2, 6, 7, */ { 11, 7 }, -/* 199: 0, 1, 2, 6, 7, */ { 6, 26 }, -/* 200: 3, 6, 7, */ { 5, 19 }, -/* 201: 0, 3, 6, 7, */ { 14, 4 }, -/* 202: 1, 3, 6, 7, */ { 12, 18 }, -/* 203: 0, 1, 3, 6, 7, */ { 6, 29 }, -/* 204: 2, 3, 6, 7, */ { 8, 4 }, -/* 205: 0, 2, 3, 6, 7, */ { 5, 35 }, -/* 206: 1, 2, 3, 6, 7, */ { 5, 40 }, -/* 207: 0, 1, 2, 3, 6, 7, */ { 2, 15 }, -/* 208: 4, 6, 7, */ { 5, 22 }, -/* 209: 0, 4, 6, 7, */ { 11, 5 }, -/* 210: 1, 4, 6, 7, */ { 12, 19 }, -/* 211: 0, 1, 4, 6, 7, */ { 6, 30 }, -/* 212: 2, 4, 6, 7, */ { 14, 10 }, -/* 213: 0, 2, 4, 6, 7, */ { 6, 36 }, -/* 214: 1, 2, 4, 6, 7, */ { 6, 43 }, -/* 215: 0, 1, 2, 4, 6, 7, */ { 4, 4 }, -/* 216: 3, 4, 6, 7, */ { 9, 7 }, -/* 217: 0, 3, 4, 6, 7, */ { 5, 37 }, -/* 218: 1, 3, 4, 6, 7, */ { 7, 15 }, -/* 219: 0, 1, 3, 4, 6, 7, */ { 3, 17 }, -/* 220: 2, 3, 4, 6, 7, */ { 5, 44 }, -/* 221: 0, 2, 3, 4, 6, 7, */ { 2, 19 }, -/* 222: 1, 2, 3, 4, 6, 7, */ { 3, 22 }, -/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 1, 10 }, -/* 224: 5, 6, 7, */ { 5, 23 }, -/* 225: 0, 5, 6, 7, */ { 12, 11 }, -/* 226: 1, 5, 6, 7, */ { 14, 8 }, -/* 227: 0, 1, 5, 6, 7, */ { 6, 31 }, -/* 228: 2, 5, 6, 7, */ { 9, 6 }, -/* 229: 0, 2, 5, 6, 7, */ { 7, 12 }, -/* 230: 1, 2, 5, 6, 7, */ { 5, 42 }, -/* 231: 0, 1, 2, 5, 6, 7, */ { 3, 15 }, -/* 232: 3, 5, 6, 7, */ { 11, 11 }, -/* 233: 0, 3, 5, 6, 7, */ { 6, 38 }, -/* 234: 1, 3, 5, 6, 7, */ { 6, 45 }, -/* 235: 0, 1, 3, 5, 6, 7, */ { 4, 5 }, -/* 236: 2, 3, 5, 6, 7, */ { 5, 45 }, -/* 237: 0, 2, 3, 5, 6, 7, */ { 3, 19 }, -/* 238: 1, 2, 3, 5, 6, 7, */ { 2, 21 }, -/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 1, 11 }, -/* 240: 4, 5, 6, 7, */ { 8, 5 }, -/* 241: 0, 4, 5, 6, 7, */ { 5, 38 }, -/* 242: 1, 4, 5, 6, 7, */ { 5, 43 }, -/* 243: 0, 1, 4, 5, 6, 7, */ { 2, 18 }, -/* 244: 2, 4, 5, 6, 7, */ { 5, 46 }, -/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 20 }, -/* 246: 1, 2, 4, 5, 6, 7, */ { 2, 22 }, -/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 1, 12 }, -/* 248: 3, 4, 5, 6, 7, */ { 5, 47 }, -/* 249: 0, 3, 4, 5, 6, 7, */ { 2, 20 }, -/* 250: 1, 3, 4, 5, 6, 7, */ { 3, 23 }, -/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 13 }, -/* 252: 2, 3, 4, 5, 6, 7, */ { 2, 23 }, -/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 1, 14 }, -/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 1, 15 }, -/* 255: 0, 1, 2, 3, 4, 5, 6, 7, */ { 0, -1 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling1[16][3] = { -/* 1: 0, */ { 0, 8, 3 }, -/* 2: 1, */ { 0, 1, 9 }, -/* 4: 2, */ { 1, 2, 10 }, -/* 8: 3, */ { 3, 11, 2 }, -/* 16: 4, */ { 4, 7, 8 }, -/* 32: 5, */ { 9, 5, 4 }, -/* 64: 6, */ { 10, 6, 5 }, -/* 128: 7, */ { 7, 6, 11 }, -/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 7, 11, 6 }, -/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 10, 5, 6 }, -/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 9, 4, 5 }, -/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 4, 8, 7 }, -/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 3, 2, 11 }, -/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 10, 2 }, -/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 0, 9, 1 }, -/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 0, 3, 8 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling2[24][6] = { -/* 3: 0, 1, */ { 1, 8, 3, 9, 8, 1 }, -/* 9: 0, 3, */ { 0, 11, 2, 8, 11, 0 }, -/* 17: 0, 4, */ { 4, 3, 0, 7, 3, 4 }, -/* 6: 1, 2, */ { 9, 2, 10, 0, 2, 9 }, -/* 34: 1, 5, */ { 0, 5, 4, 1, 5, 0 }, -/* 12: 2, 3, */ { 3, 10, 1, 11, 10, 3 }, -/* 68: 2, 6, */ { 1, 6, 5, 2, 6, 1 }, -/* 136: 3, 7, */ { 7, 2, 3, 6, 2, 7 }, -/* 48: 4, 5, */ { 9, 7, 8, 5, 7, 9 }, -/* 144: 4, 7, */ { 6, 8, 4, 11, 8, 6 }, -/* 96: 5, 6, */ { 10, 4, 9, 6, 4, 10 }, -/* 192: 6, 7, */ { 11, 5, 10, 7, 5, 11 }, -/* 63: 0, 1, 2, 3, 4, 5, */ { 11, 10, 5, 7, 11, 5 }, -/* 159: 0, 1, 2, 3, 4, 7, */ { 10, 9, 4, 6, 10, 4 }, -/* 111: 0, 1, 2, 3, 5, 6, */ { 6, 4, 8, 11, 6, 8 }, -/* 207: 0, 1, 2, 3, 6, 7, */ { 9, 8, 7, 5, 9, 7 }, -/* 119: 0, 1, 2, 4, 5, 6, */ { 7, 3, 2, 6, 7, 2 }, -/* 187: 0, 1, 3, 4, 5, 7, */ { 1, 5, 6, 2, 1, 6 }, -/* 243: 0, 1, 4, 5, 6, 7, */ { 3, 1, 10, 11, 3, 10 }, -/* 221: 0, 2, 3, 4, 6, 7, */ { 0, 4, 5, 1, 0, 5 }, -/* 249: 0, 3, 4, 5, 6, 7, */ { 9, 10, 2, 0, 9, 2 }, -/* 238: 1, 2, 3, 5, 6, 7, */ { 4, 0, 3, 7, 4, 3 }, -/* 246: 1, 2, 4, 5, 6, 7, */ { 0, 2, 11, 8, 0, 11 }, -/* 252: 2, 3, 4, 5, 6, 7, */ { 1, 3, 8, 9, 1, 8 } -}; -//_____________________________________________________________________________ - -//_____________________________________________________________________________ -/** - * \brief test table for case 3 - * One face to test - * When the test on the specified face is positive : 4 first triangles - * When the test on the specified face is negative : 2 last triangles - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test3[24] = { -/* 5: 0, 2, */ 5, -/* 33: 0, 5, */ 1, -/* 129: 0, 7, */ 4, -/* 10: 1, 3, */ 5, -/* 18: 1, 4, */ 1, -/* 66: 1, 6, */ 2, -/* 36: 2, 5, */ 2, -/* 132: 2, 7, */ 3, -/* 24: 3, 4, */ 4, -/* 72: 3, 6, */ 3, -/* 80: 4, 6, */ 6, -/* 160: 5, 7, */ 6, -/* 95: 0, 1, 2, 3, 4, 6, */ -6, -/* 175: 0, 1, 2, 3, 5, 7, */ -6, -/* 183: 0, 1, 2, 4, 5, 7, */ -3, -/* 231: 0, 1, 2, 5, 6, 7, */ -4, -/* 123: 0, 1, 3, 4, 5, 6, */ -3, -/* 219: 0, 1, 3, 4, 6, 7, */ -2, -/* 189: 0, 2, 3, 4, 5, 7, */ -2, -/* 237: 0, 2, 3, 5, 6, 7, */ -1, -/* 245: 0, 2, 4, 5, 6, 7, */ -5, -/* 126: 1, 2, 3, 4, 5, 6, */ -4, -/* 222: 1, 2, 3, 4, 6, 7, */ -1, -/* 250: 1, 3, 4, 5, 6, 7, */ -5 -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 3.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling3_1[24][6] = { -/* 5: 0, 2, */ { 0, 8, 3, 1, 2, 10 }, -/* 33: 0, 5, */ { 9, 5, 4, 0, 8, 3 }, -/* 129: 0, 7, */ { 3, 0, 8, 11, 7, 6 }, -/* 10: 1, 3, */ { 1, 9, 0, 2, 3, 11 }, -/* 18: 1, 4, */ { 0, 1, 9, 8, 4, 7 }, -/* 66: 1, 6, */ { 9, 0, 1, 5, 10, 6 }, -/* 36: 2, 5, */ { 1, 2, 10, 9, 5, 4 }, -/* 132: 2, 7, */ { 10, 1, 2, 6, 11, 7 }, -/* 24: 3, 4, */ { 8, 4, 7, 3, 11, 2 }, -/* 72: 3, 6, */ { 2, 3, 11, 10, 6, 5 }, -/* 80: 4, 6, */ { 5, 10, 6, 4, 7, 8 }, -/* 160: 5, 7, */ { 4, 9, 5, 7, 6, 11 }, -/* 95: 0, 1, 2, 3, 4, 6, */ { 5, 9, 4, 11, 6, 7 }, -/* 175: 0, 1, 2, 3, 5, 7, */ { 6, 10, 5, 8, 7, 4 }, -/* 183: 0, 1, 2, 4, 5, 7, */ { 11, 3, 2, 5, 6, 10 }, -/* 231: 0, 1, 2, 5, 6, 7, */ { 7, 4, 8, 2, 11, 3 }, -/* 123: 0, 1, 3, 4, 5, 6, */ { 2, 1, 10, 7, 11, 6 }, -/* 219: 0, 1, 3, 4, 6, 7, */ { 10, 2, 1, 4, 5, 9 }, -/* 189: 0, 2, 3, 4, 5, 7, */ { 1, 0, 9, 6, 10, 5 }, -/* 237: 0, 2, 3, 5, 6, 7, */ { 9, 1, 0, 7, 4, 8 }, -/* 245: 0, 2, 4, 5, 6, 7, */ { 0, 9, 1, 11, 3, 2 }, -/* 126: 1, 2, 3, 4, 5, 6, */ { 8, 0, 3, 6, 7, 11 }, -/* 222: 1, 2, 3, 4, 6, 7, */ { 4, 5, 9, 3, 8, 0 }, -/* 250: 1, 3, 4, 5, 6, 7, */ { 3, 8, 0, 10, 2, 1 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 3.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling3_2[24][12] = { -/* 5: 0, 2, */ { 10, 3, 2, 10, 8, 3, 10, 1, 0, 8, 10, 0 }, -/* 33: 0, 5, */ { 3, 4, 8, 3, 5, 4, 3, 0, 9, 5, 3, 9 }, -/* 129: 0, 7, */ { 6, 8, 7, 6, 0, 8, 6, 11, 3, 0, 6, 3 }, -/* 10: 1, 3, */ { 11, 0, 3, 11, 9, 0, 11, 2, 1, 9, 11, 1 }, -/* 18: 1, 4, */ { 7, 9, 4, 7, 1, 9, 7, 8, 0, 1, 7, 0 }, -/* 66: 1, 6, */ { 6, 1, 10, 6, 0, 1, 9, 0, 6, 9, 6, 5 }, -/* 36: 2, 5, */ { 4, 10, 5, 4, 2, 10, 4, 9, 1, 2, 4, 1 }, -/* 132: 2, 7, */ { 7, 2, 11, 7, 1, 2, 7, 6, 10, 1, 7, 10 }, -/* 24: 3, 4, */ { 2, 7, 11, 2, 4, 7, 2, 3, 8, 4, 2, 8 }, -/* 72: 3, 6, */ { 5, 11, 6, 5, 3, 11, 5, 10, 2, 3, 5, 2 }, -/* 80: 4, 6, */ { 8, 6, 7, 8, 10, 6, 8, 4, 5, 10, 8, 5 }, -/* 160: 5, 7, */ { 11, 5, 6, 11, 9, 5, 11, 7, 4, 9, 11, 4 }, -/* 95: 0, 1, 2, 3, 4, 6, */ { 6, 5, 11, 5, 9, 11, 4, 7, 11, 4, 11, 9 }, -/* 175: 0, 1, 2, 3, 5, 7, */ { 7, 6, 8, 6, 10, 8, 5, 4, 8, 5, 8, 10 }, -/* 183: 0, 1, 2, 4, 5, 7, */ { 6, 11, 5, 11, 3, 5, 2, 10, 5, 2, 5, 3 }, -/* 231: 0, 1, 2, 5, 6, 7, */ { 11, 7, 2, 7, 4, 2, 8, 3, 2, 8, 2, 4 }, -/* 123: 0, 1, 3, 4, 5, 6, */ { 11, 2, 7, 2, 1, 7, 10, 6, 7, 10, 7, 1 }, -/* 219: 0, 1, 3, 4, 6, 7, */ { 5, 10, 4, 10, 2, 4, 1, 9, 4, 1, 4, 2 }, -/* 189: 0, 2, 3, 4, 5, 7, */ { 10, 1, 6, 1, 0, 6, 6, 0, 9, 5, 6, 9 }, -/* 237: 0, 2, 3, 5, 6, 7, */ { 4, 9, 7, 9, 1, 7, 0, 8, 7, 0, 7, 1 }, -/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 0, 11, 0, 9, 11, 1, 2, 11, 1, 11, 9 }, -/* 126: 1, 2, 3, 4, 5, 6, */ { 7, 8, 6, 8, 0, 6, 3, 11, 6, 3, 6, 0 }, -/* 222: 1, 2, 3, 4, 6, 7, */ { 8, 4, 3, 4, 5, 3, 9, 0, 3, 9, 3, 5 }, -/* 250: 1, 3, 4, 5, 6, 7, */ { 2, 3, 10, 3, 8, 10, 0, 1, 10, 0, 10, 8 } -}; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief test table for case 4 - * Interior to test - * When the test on the interior is negative : 2 first triangles - * When the test on the interior is positive : 6 last triangles - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test4[8] = { -/* 65: 0, 6, */ 7, -/* 130: 1, 7, */ 7, -/* 20: 2, 4, */ 7, -/* 40: 3, 5, */ 7, -/* 215: 0, 1, 2, 4, 6, 7, */ -7, -/* 235: 0, 1, 3, 5, 6, 7, */ -7, -/* 125: 0, 2, 3, 4, 5, 6, */ -7, -/* 190: 1, 2, 3, 4, 5, 7, */ -7 -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 4.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling4_1[8][6] = { -/* 65: 0, 6, */ { 0, 8, 3, 5, 10, 6 }, -/* 130: 1, 7, */ { 0, 1, 9, 11, 7, 6 }, -/* 20: 2, 4, */ { 1, 2, 10, 8, 4, 7 }, -/* 40: 3, 5, */ { 9, 5, 4, 2, 3, 11 }, -/* 215: 0, 1, 2, 4, 6, 7, */ { 4, 5, 9, 11, 3, 2 }, -/* 235: 0, 1, 3, 5, 6, 7, */ { 10, 2, 1, 7, 4, 8 }, -/* 125: 0, 2, 3, 4, 5, 6, */ { 9, 1, 0, 6, 7, 11 }, -/* 190: 1, 2, 3, 4, 5, 7, */ { 3, 8, 0, 6, 10, 5 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 4.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling4_2[8][18] = { -/* 65: 0, 6, */ { 8, 5, 0, 5, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 5 }, -/* 130: 1, 7, */ { 9, 6, 1, 6, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 6 }, -/* 20: 2, 4, */ { 10, 7, 2, 7, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 7 }, -/* 40: 3, 5, */ { 11, 4, 3, 4, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 4 }, -/* 215: 0, 1, 2, 4, 6, 7, */ { 3, 4, 11, 5, 11, 4, 11, 5, 2, 9, 2, 5, 2, 9, 3, 4, 3, 9 }, -/* 235: 0, 1, 3, 5, 6, 7, */ { 2, 7, 10, 4, 10, 7, 10, 4, 1, 8, 1, 4, 1, 8, 2, 7, 2, 8 }, -/* 125: 0, 2, 3, 4, 5, 6, */ { 1, 6, 9, 7, 9, 6, 9, 7, 0, 11, 0, 7, 0, 11, 1, 6, 1, 11 }, -/* 190: 1, 2, 3, 4, 5, 7, */ { 0, 5, 8, 6, 8, 5, 8, 6, 3, 10, 3, 6, 3, 10, 0, 5, 0, 10 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 5 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling5[48][9] = { -/* 7: 0, 1, 2, */ { 2, 8, 3, 2, 10, 8, 10, 9, 8 }, -/* 11: 0, 1, 3, */ { 1, 11, 2, 1, 9, 11, 9, 8, 11 }, -/* 19: 0, 1, 4, */ { 4, 1, 9, 4, 7, 1, 7, 3, 1 }, -/* 35: 0, 1, 5, */ { 8, 5, 4, 8, 3, 5, 3, 1, 5 }, -/* 13: 0, 2, 3, */ { 0, 10, 1, 0, 8, 10, 8, 11, 10 }, -/* 25: 0, 3, 4, */ { 11, 4, 7, 11, 2, 4, 2, 0, 4 }, -/* 137: 0, 3, 7, */ { 7, 0, 8, 7, 6, 0, 6, 2, 0 }, -/* 49: 0, 4, 5, */ { 9, 3, 0, 9, 5, 3, 5, 7, 3 }, -/* 145: 0, 4, 7, */ { 3, 6, 11, 3, 0, 6, 0, 4, 6 }, -/* 14: 1, 2, 3, */ { 3, 9, 0, 3, 11, 9, 11, 10, 9 }, -/* 38: 1, 2, 5, */ { 5, 2, 10, 5, 4, 2, 4, 0, 2 }, -/* 70: 1, 2, 6, */ { 9, 6, 5, 9, 0, 6, 0, 2, 6 }, -/* 50: 1, 4, 5, */ { 0, 7, 8, 0, 1, 7, 1, 5, 7 }, -/* 98: 1, 5, 6, */ { 10, 0, 1, 10, 6, 0, 6, 4, 0 }, -/* 76: 2, 3, 6, */ { 6, 3, 11, 6, 5, 3, 5, 1, 3 }, -/* 140: 2, 3, 7, */ { 10, 7, 6, 10, 1, 7, 1, 3, 7 }, -/* 100: 2, 5, 6, */ { 1, 4, 9, 1, 2, 4, 2, 6, 4 }, -/* 196: 2, 6, 7, */ { 11, 1, 2, 11, 7, 1, 7, 5, 1 }, -/* 152: 3, 4, 7, */ { 8, 2, 3, 8, 4, 2, 4, 6, 2 }, -/* 200: 3, 6, 7, */ { 2, 5, 10, 2, 3, 5, 3, 7, 5 }, -/* 112: 4, 5, 6, */ { 7, 10, 6, 7, 8, 10, 8, 9, 10 }, -/* 176: 4, 5, 7, */ { 6, 9, 5, 6, 11, 9, 11, 8, 9 }, -/* 208: 4, 6, 7, */ { 5, 8, 4, 5, 10, 8, 10, 11, 8 }, -/* 224: 5, 6, 7, */ { 4, 11, 7, 4, 9, 11, 9, 10, 11 }, -/* 31: 0, 1, 2, 3, 4, */ { 4, 7, 11, 4, 11, 9, 9, 11, 10 }, -/* 47: 0, 1, 2, 3, 5, */ { 5, 4, 8, 5, 8, 10, 10, 8, 11 }, -/* 79: 0, 1, 2, 3, 6, */ { 6, 5, 9, 6, 9, 11, 11, 9, 8 }, -/* 143: 0, 1, 2, 3, 7, */ { 7, 6, 10, 7, 10, 8, 8, 10, 9 }, -/* 55: 0, 1, 2, 4, 5, */ { 2, 10, 5, 2, 5, 3, 3, 5, 7 }, -/* 103: 0, 1, 2, 5, 6, */ { 8, 3, 2, 8, 2, 4, 4, 2, 6 }, -/* 59: 0, 1, 3, 4, 5, */ { 11, 2, 1, 11, 1, 7, 7, 1, 5 }, -/* 155: 0, 1, 3, 4, 7, */ { 1, 9, 4, 1, 4, 2, 2, 4, 6 }, -/* 115: 0, 1, 4, 5, 6, */ { 10, 6, 7, 10, 7, 1, 1, 7, 3 }, -/* 179: 0, 1, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 5, 3, 1 }, -/* 157: 0, 2, 3, 4, 7, */ { 10, 1, 0, 10, 0, 6, 6, 0, 4 }, -/* 205: 0, 2, 3, 6, 7, */ { 0, 8, 7, 0, 7, 1, 1, 7, 5 }, -/* 185: 0, 3, 4, 5, 7, */ { 9, 5, 6, 9, 6, 0, 0, 6, 2 }, -/* 217: 0, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 4, 2, 0 }, -/* 241: 0, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 11, 9, 10 }, -/* 110: 1, 2, 3, 5, 6, */ { 3, 11, 6, 3, 6, 0, 0, 6, 4 }, -/* 206: 1, 2, 3, 6, 7, */ { 9, 0, 3, 9, 3, 5, 5, 3, 7 }, -/* 118: 1, 2, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 6, 0, 2 }, -/* 230: 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 2, 4, 0 }, -/* 242: 1, 4, 5, 6, 7, */ { 0, 1, 10, 0, 10, 8, 8, 10, 11 }, -/* 220: 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 3, 5, 1 }, -/* 236: 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 7, 1, 3 }, -/* 244: 2, 4, 5, 6, 7, */ { 1, 2, 11, 1, 11, 9, 9, 11, 8 }, -/* 248: 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 10, 8, 9 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief test table for case 6 - * 1 face to test + eventually the interior - * When the test on the specified face is positive : 5 first triangles - * When the test on the specified face is negative : - * - if the test on the interior is negative : 3 middle triangles - * - if the test on the interior is positive : 8 last triangles - * The support edge for the interior test is marked as the 3rd column. - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test6[48][3] = { -/* 67: 0, 1, 6, */ { 2, 7, 10 }, -/* 131: 0, 1, 7, */ { 4, 7, 11 }, -/* 21: 0, 2, 4, */ { 5, 7, 1 }, -/* 69: 0, 2, 6, */ { 5, 7, 3 }, -/* 41: 0, 3, 5, */ { 1, 7, 9 }, -/* 73: 0, 3, 6, */ { 3, 7, 10 }, -/* 81: 0, 4, 6, */ { 6, 7, 5 }, -/* 97: 0, 5, 6, */ { 1, 7, 8 }, -/* 193: 0, 6, 7, */ { 4, 7, 8 }, -/* 22: 1, 2, 4, */ { 1, 7, 8 }, -/* 134: 1, 2, 7, */ { 3, 7, 11 }, -/* 42: 1, 3, 5, */ { 5, 7, 2 }, -/* 138: 1, 3, 7, */ { 5, 7, 0 }, -/* 146: 1, 4, 7, */ { 1, 7, 9 }, -/* 162: 1, 5, 7, */ { 6, 7, 6 }, -/* 194: 1, 6, 7, */ { 2, 7, 9 }, -/* 28: 2, 3, 4, */ { 4, 7, 8 }, -/* 44: 2, 3, 5, */ { 2, 7, 9 }, -/* 52: 2, 4, 5, */ { 2, 7, 10 }, -/* 84: 2, 4, 6, */ { 6, 7, 7 }, -/* 148: 2, 4, 7, */ { 3, 7, 10 }, -/* 56: 3, 4, 5, */ { 4, 7, 11 }, -/* 104: 3, 5, 6, */ { 3, 7, 11 }, -/* 168: 3, 5, 7, */ { 6, 7, 4 }, -/* 87: 0, 1, 2, 4, 6, */ { -6, -7, 4 }, -/* 151: 0, 1, 2, 4, 7, */ { -3, -7, 11 }, -/* 199: 0, 1, 2, 6, 7, */ { -4, -7, 11 }, -/* 107: 0, 1, 3, 5, 6, */ { -3, -7, 10 }, -/* 171: 0, 1, 3, 5, 7, */ { -6, -7, 7 }, -/* 203: 0, 1, 3, 6, 7, */ { -2, -7, 10 }, -/* 211: 0, 1, 4, 6, 7, */ { -2, -7, 9 }, -/* 227: 0, 1, 5, 6, 7, */ { -4, -7, 8 }, -/* 61: 0, 2, 3, 4, 5, */ { -2, -7, 9 }, -/* 93: 0, 2, 3, 4, 6, */ { -6, -7, 6 }, -/* 109: 0, 2, 3, 5, 6, */ { -1, -7, 9 }, -/* 117: 0, 2, 4, 5, 6, */ { -5, -7, 0 }, -/* 213: 0, 2, 4, 6, 7, */ { -5, -7, 2 }, -/* 121: 0, 3, 4, 5, 6, */ { -3, -7, 11 }, -/* 233: 0, 3, 5, 6, 7, */ { -1, -7, 8 }, -/* 62: 1, 2, 3, 4, 5, */ { -4, -7, 8 }, -/* 158: 1, 2, 3, 4, 7, */ { -1, -7, 8 }, -/* 174: 1, 2, 3, 5, 7, */ { -6, -7, 5 }, -/* 182: 1, 2, 4, 5, 7, */ { -3, -7, 10 }, -/* 214: 1, 2, 4, 6, 7, */ { -1, -7, 9 }, -/* 186: 1, 3, 4, 5, 7, */ { -5, -7, 3 }, -/* 234: 1, 3, 5, 6, 7, */ { -5, -7, 1 }, -/* 124: 2, 3, 4, 5, 6, */ { -4, -7, 11 }, -/* 188: 2, 3, 4, 5, 7, */ { -2, -7, 10 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 6.1.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling6_1_1[48][9] = { -/* 67: 0, 1, 6, */ { 6, 5, 10, 3, 1, 8, 9, 8, 1 }, -/* 131: 0, 1, 7, */ { 11, 7, 6, 9, 3, 1, 3, 9, 8 }, -/* 21: 0, 2, 4, */ { 1, 2, 10, 7, 0, 4, 0, 7, 3 }, -/* 69: 0, 2, 6, */ { 3, 0, 8, 5, 2, 6, 2, 5, 1 }, -/* 41: 0, 3, 5, */ { 5, 4, 9, 2, 0, 11, 8, 11, 0 }, -/* 73: 0, 3, 6, */ { 10, 6, 5, 8, 2, 0, 2, 8, 11 }, -/* 81: 0, 4, 6, */ { 10, 6, 5, 0, 4, 3, 7, 3, 4 }, -/* 97: 0, 5, 6, */ { 3, 0, 8, 6, 4, 10, 9, 10, 4 }, -/* 193: 0, 6, 7, */ { 8, 3, 0, 10, 7, 5, 7, 10, 11 }, -/* 22: 1, 2, 4, */ { 8, 4, 7, 10, 0, 2, 0, 10, 9 }, -/* 134: 1, 2, 7, */ { 7, 6, 11, 0, 2, 9, 10, 9, 2 }, -/* 42: 1, 3, 5, */ { 2, 3, 11, 4, 1, 5, 1, 4, 0 }, -/* 138: 1, 3, 7, */ { 0, 1, 9, 6, 3, 7, 3, 6, 2 }, -/* 146: 1, 4, 7, */ { 9, 0, 1, 11, 4, 6, 4, 11, 8 }, -/* 162: 1, 5, 7, */ { 11, 7, 6, 1, 5, 0, 4, 0, 5 }, -/* 194: 1, 6, 7, */ { 0, 1, 9, 7, 5, 11, 10, 11, 5 }, -/* 28: 2, 3, 4, */ { 4, 7, 8, 1, 3, 10, 11, 10, 3 }, -/* 44: 2, 3, 5, */ { 9, 5, 4, 11, 1, 3, 1, 11, 10 }, -/* 52: 2, 4, 5, */ { 10, 1, 2, 8, 5, 7, 5, 8, 9 }, -/* 84: 2, 4, 6, */ { 8, 4, 7, 2, 6, 1, 5, 1, 6 }, -/* 148: 2, 4, 7, */ { 1, 2, 10, 4, 6, 8, 11, 8, 6 }, -/* 56: 3, 4, 5, */ { 2, 3, 11, 5, 7, 9, 8, 9, 7 }, -/* 104: 3, 5, 6, */ { 11, 2, 3, 9, 6, 4, 6, 9, 10 }, -/* 168: 3, 5, 7, */ { 9, 5, 4, 3, 7, 2, 6, 2, 7 }, -/* 87: 0, 1, 2, 4, 6, */ { 4, 5, 9, 2, 7, 3, 7, 2, 6 }, -/* 151: 0, 1, 2, 4, 7, */ { 3, 2, 11, 4, 6, 9, 10, 9, 6 }, -/* 199: 0, 1, 2, 6, 7, */ { 11, 3, 2, 9, 7, 5, 7, 9, 8 }, -/* 107: 0, 1, 3, 5, 6, */ { 10, 2, 1, 8, 6, 4, 6, 8, 11 }, -/* 171: 0, 1, 3, 5, 7, */ { 7, 4, 8, 1, 6, 2, 6, 1, 5 }, -/* 203: 0, 1, 3, 6, 7, */ { 2, 1, 10, 7, 5, 8, 9, 8, 5 }, -/* 211: 0, 1, 4, 6, 7, */ { 4, 5, 9, 3, 1, 11, 10, 11, 1 }, -/* 227: 0, 1, 5, 6, 7, */ { 8, 7, 4, 10, 3, 1, 3, 10, 11 }, -/* 61: 0, 2, 3, 4, 5, */ { 9, 1, 0, 11, 5, 7, 5, 11, 10 }, -/* 93: 0, 2, 3, 4, 6, */ { 6, 7, 11, 0, 5, 1, 5, 0, 4 }, -/* 109: 0, 2, 3, 5, 6, */ { 1, 0, 9, 6, 4, 11, 8, 11, 4 }, -/* 117: 0, 2, 4, 5, 6, */ { 9, 1, 0, 7, 3, 6, 2, 6, 3 }, -/* 213: 0, 2, 4, 6, 7, */ { 11, 3, 2, 5, 1, 4, 0, 4, 1 }, -/* 121: 0, 3, 4, 5, 6, */ { 11, 6, 7, 9, 2, 0, 2, 9, 10 }, -/* 233: 0, 3, 5, 6, 7, */ { 7, 4, 8, 2, 0, 10, 9, 10, 0 }, -/* 62: 1, 2, 3, 4, 5, */ { 0, 3, 8, 5, 7, 10, 11, 10, 7 }, -/* 158: 1, 2, 3, 4, 7, */ { 8, 0, 3, 10, 4, 6, 4, 10, 9 }, -/* 174: 1, 2, 3, 5, 7, */ { 5, 6, 10, 3, 4, 0, 4, 3, 7 }, -/* 182: 1, 2, 4, 5, 7, */ { 5, 6, 10, 0, 2, 8, 11, 8, 2 }, -/* 214: 1, 2, 4, 6, 7, */ { 9, 4, 5, 11, 0, 2, 0, 11, 8 }, -/* 186: 1, 3, 4, 5, 7, */ { 8, 0, 3, 6, 2, 5, 1, 5, 2 }, -/* 234: 1, 3, 5, 6, 7, */ { 10, 2, 1, 4, 0, 7, 3, 7, 0 }, -/* 124: 2, 3, 4, 5, 6, */ { 6, 7, 11, 1, 3, 9, 8, 9, 3 }, -/* 188: 2, 3, 4, 5, 7, */ { 10, 5, 6, 8, 1, 3, 1, 8, 9 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 6.1.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling6_1_2[48][21] = { -/* 67: 0, 1, 6, */ { 1, 10, 3, 6, 3, 10, 3, 6, 8, 5, 8, 6, 8, 5, 9, 1, 9, 5, 10, 1, 5 }, -/* 131: 0, 1, 7, */ { 1, 11, 3, 11, 1, 6, 9, 6, 1, 6, 9, 7, 8, 7, 9, 7, 8, 3, 7, 3, 11 }, -/* 21: 0, 2, 4, */ { 4, 1, 0, 1, 4, 10, 7, 10, 4, 10, 7, 2, 3, 2, 7, 2, 3, 0, 2, 0, 1 }, -/* 69: 0, 2, 6, */ { 6, 3, 2, 3, 6, 8, 5, 8, 6, 8, 5, 0, 1, 0, 5, 0, 1, 2, 0, 2, 3 }, -/* 41: 0, 3, 5, */ { 0, 9, 2, 5, 2, 9, 2, 5, 11, 4, 11, 5, 11, 4, 8, 0, 8, 4, 9, 0, 4 }, -/* 73: 0, 3, 6, */ { 0, 10, 2, 10, 0, 5, 8, 5, 0, 5, 8, 6, 11, 6, 8, 6, 11, 2, 6, 2, 10 }, -/* 81: 0, 4, 6, */ { 4, 5, 0, 10, 0, 5, 0, 10, 3, 6, 3, 10, 3, 6, 7, 4, 7, 6, 5, 4, 6 }, -/* 97: 0, 5, 6, */ { 4, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 9, 4, 9, 0, 8, 4, 0 }, -/* 193: 0, 6, 7, */ { 5, 8, 7, 8, 5, 0, 10, 0, 5, 0, 10, 3, 11, 3, 10, 3, 11, 7, 3, 7, 8 }, -/* 22: 1, 2, 4, */ { 2, 8, 0, 8, 2, 7, 10, 7, 2, 7, 10, 4, 9, 4, 10, 4, 9, 0, 4, 0, 8 }, -/* 134: 1, 2, 7, */ { 2, 11, 0, 7, 0, 11, 0, 7, 9, 6, 9, 7, 9, 6, 10, 2, 10, 6, 11, 2, 6 }, -/* 42: 1, 3, 5, */ { 5, 2, 1, 2, 5, 11, 4, 11, 5, 11, 4, 3, 0, 3, 4, 3, 0, 1, 3, 1, 2 }, -/* 138: 1, 3, 7, */ { 7, 0, 3, 0, 7, 9, 6, 9, 7, 9, 6, 1, 2, 1, 6, 1, 2, 3, 1, 3, 0 }, -/* 146: 1, 4, 7, */ { 6, 9, 4, 9, 6, 1, 11, 1, 6, 1, 11, 0, 8, 0, 11, 0, 8, 4, 0, 4, 9 }, -/* 162: 1, 5, 7, */ { 5, 6, 1, 11, 1, 6, 1, 11, 0, 7, 0, 11, 0, 7, 4, 5, 4, 7, 6, 5, 7 }, -/* 194: 1, 6, 7, */ { 5, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 10, 5, 10, 1, 9, 5, 1 }, -/* 28: 2, 3, 4, */ { 3, 8, 1, 4, 1, 8, 1, 4, 10, 7, 10, 4, 10, 7, 11, 3, 11, 7, 8, 3, 7 }, -/* 44: 2, 3, 5, */ { 3, 9, 1, 9, 3, 4, 11, 4, 3, 4, 11, 5, 10, 5, 11, 5, 10, 1, 5, 1, 9 }, -/* 52: 2, 4, 5, */ { 7, 10, 5, 10, 7, 2, 8, 2, 7, 2, 8, 1, 9, 1, 8, 1, 9, 5, 1, 5, 10 }, -/* 84: 2, 4, 6, */ { 6, 7, 2, 8, 2, 7, 2, 8, 1, 4, 1, 8, 1, 4, 5, 6, 5, 4, 7, 6, 4 }, -/* 148: 2, 4, 7, */ { 6, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 11, 6, 11, 2, 10, 6, 2 }, -/* 56: 3, 4, 5, */ { 7, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 8, 7, 8, 3, 11, 7, 3 }, -/* 104: 3, 5, 6, */ { 4, 11, 6, 11, 4, 3, 9, 3, 4, 3, 9, 2, 10, 2, 9, 2, 10, 6, 2, 6, 11 }, -/* 168: 3, 5, 7, */ { 7, 4, 3, 9, 3, 4, 3, 9, 2, 5, 2, 9, 2, 5, 6, 7, 6, 5, 4, 7, 5 }, -/* 87: 0, 1, 2, 4, 6, */ { 3, 4, 7, 4, 3, 9, 2, 9, 3, 9, 2, 5, 6, 5, 2, 5, 6, 7, 5, 7, 4 }, -/* 151: 0, 1, 2, 4, 7, */ { 6, 11, 4, 3, 4, 11, 4, 3, 9, 2, 9, 3, 9, 2, 10, 6, 10, 2, 11, 6, 2 }, -/* 199: 0, 1, 2, 6, 7, */ { 5, 11, 7, 11, 5, 2, 9, 2, 5, 2, 9, 3, 8, 3, 9, 3, 8, 7, 3, 7, 11 }, -/* 107: 0, 1, 3, 5, 6, */ { 4, 10, 6, 10, 4, 1, 8, 1, 4, 1, 8, 2, 11, 2, 8, 2, 11, 6, 2, 6, 10 }, -/* 171: 0, 1, 3, 5, 7, */ { 2, 7, 6, 7, 2, 8, 1, 8, 2, 8, 1, 4, 5, 4, 1, 4, 5, 6, 4, 6, 7 }, -/* 203: 0, 1, 3, 6, 7, */ { 5, 10, 7, 2, 7, 10, 7, 2, 8, 1, 8, 2, 8, 1, 9, 5, 9, 1, 10, 5, 1 }, -/* 211: 0, 1, 4, 6, 7, */ { 1, 9, 3, 4, 3, 9, 3, 4, 11, 5, 11, 4, 11, 5, 10, 1, 10, 5, 9, 1, 5 }, -/* 227: 0, 1, 5, 6, 7, */ { 1, 8, 3, 8, 1, 4, 10, 4, 1, 4, 10, 7, 11, 7, 10, 7, 11, 3, 7, 3, 8 }, -/* 61: 0, 2, 3, 4, 5, */ { 7, 9, 5, 9, 7, 0, 11, 0, 7, 0, 11, 1, 10, 1, 11, 1, 10, 5, 1, 5, 9 }, -/* 93: 0, 2, 3, 4, 6, */ { 1, 6, 5, 6, 1, 11, 0, 11, 1, 11, 0, 7, 4, 7, 0, 7, 4, 5, 7, 5, 6 }, -/* 109: 0, 2, 3, 5, 6, */ { 4, 9, 6, 1, 6, 9, 6, 1, 11, 0, 11, 1, 11, 0, 8, 4, 8, 0, 9, 4, 0 }, -/* 117: 0, 2, 4, 5, 6, */ { 3, 0, 7, 9, 7, 0, 7, 9, 6, 1, 6, 9, 6, 1, 2, 3, 2, 1, 0, 3, 1 }, -/* 213: 0, 2, 4, 6, 7, */ { 1, 2, 5, 11, 5, 2, 5, 11, 4, 3, 4, 11, 4, 3, 0, 1, 0, 3, 2, 1, 3 }, -/* 121: 0, 3, 4, 5, 6, */ { 0, 11, 2, 11, 0, 7, 9, 7, 0, 7, 9, 6, 10, 6, 9, 6, 10, 2, 6, 2, 11 }, -/* 233: 0, 3, 5, 6, 7, */ { 0, 8, 2, 7, 2, 8, 2, 7, 10, 4, 10, 7, 10, 4, 9, 0, 9, 4, 8, 0, 4 }, -/* 62: 1, 2, 3, 4, 5, */ { 7, 8, 5, 0, 5, 8, 5, 0, 10, 3, 10, 0, 10, 3, 11, 7, 11, 3, 8, 7, 3 }, -/* 158: 1, 2, 3, 4, 7, */ { 6, 8, 4, 8, 6, 3, 10, 3, 6, 3, 10, 0, 9, 0, 10, 0, 9, 4, 0, 4, 8 }, -/* 174: 1, 2, 3, 5, 7, */ { 0, 5, 4, 5, 0, 10, 3, 10, 0, 10, 3, 6, 7, 6, 3, 6, 7, 4, 6, 4, 5 }, -/* 182: 1, 2, 4, 5, 7, */ { 2, 10, 0, 5, 0, 10, 0, 5, 8, 6, 8, 5, 8, 6, 11, 2, 11, 6, 10, 2, 6 }, -/* 214: 1, 2, 4, 6, 7, */ { 2, 9, 0, 9, 2, 5, 11, 5, 2, 5, 11, 4, 8, 4, 11, 4, 8, 0, 4, 0, 9 }, -/* 186: 1, 3, 4, 5, 7, */ { 2, 3, 6, 8, 6, 3, 6, 8, 5, 0, 5, 8, 5, 0, 1, 2, 1, 0, 3, 2, 0 }, -/* 234: 1, 3, 5, 6, 7, */ { 0, 1, 4, 10, 4, 1, 4, 10, 7, 2, 7, 10, 7, 2, 3, 0, 3, 2, 1, 0, 2 }, -/* 124: 2, 3, 4, 5, 6, */ { 3, 11, 1, 6, 1, 11, 1, 6, 9, 7, 9, 6, 9, 7, 8, 3, 8, 7, 11, 3, 7 }, -/* 188: 2, 3, 4, 5, 7, */ { 3, 10, 1, 10, 3, 6, 8, 6, 3, 6, 8, 5, 9, 5, 8, 5, 9, 1, 5, 1, 10 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 6.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling6_2[48][15] = { -/* 67: 0, 1, 6, */ { 1, 10, 3, 6, 3, 10, 3, 6, 8, 5, 8, 6, 8, 5, 9 }, -/* 131: 0, 1, 7, */ { 1, 11, 3, 11, 1, 6, 9, 6, 1, 6, 9, 7, 8, 7, 9 }, -/* 21: 0, 2, 4, */ { 4, 1, 0, 1, 4, 10, 7, 10, 4, 10, 7, 2, 3, 2, 7 }, -/* 69: 0, 2, 6, */ { 6, 3, 2, 3, 6, 8, 5, 8, 6, 8, 5, 0, 1, 0, 5 }, -/* 41: 0, 3, 5, */ { 0, 9, 2, 5, 2, 9, 2, 5, 11, 4, 11, 5, 11, 4, 8 }, -/* 73: 0, 3, 6, */ { 0, 10, 2, 10, 0, 5, 8, 5, 0, 5, 8, 6, 11, 6, 8 }, -/* 81: 0, 4, 6, */ { 4, 5, 0, 10, 0, 5, 0, 10, 3, 6, 3, 10, 3, 6, 7 }, -/* 97: 0, 5, 6, */ { 4, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 9 }, -/* 193: 0, 6, 7, */ { 5, 8, 7, 8, 5, 0, 10, 0, 5, 0, 10, 3, 11, 3, 10 }, -/* 22: 1, 2, 4, */ { 2, 8, 0, 8, 2, 7, 10, 7, 2, 7, 10, 4, 9, 4, 10 }, -/* 134: 1, 2, 7, */ { 2, 11, 0, 7, 0, 11, 0, 7, 9, 6, 9, 7, 9, 6, 10 }, -/* 42: 1, 3, 5, */ { 5, 2, 1, 2, 5, 11, 4, 11, 5, 11, 4, 3, 0, 3, 4 }, -/* 138: 1, 3, 7, */ { 7, 0, 3, 0, 7, 9, 6, 9, 7, 9, 6, 1, 2, 1, 6 }, -/* 146: 1, 4, 7, */ { 6, 9, 4, 9, 6, 1, 11, 1, 6, 1, 11, 0, 8, 0, 11 }, -/* 162: 1, 5, 7, */ { 5, 6, 1, 11, 1, 6, 1, 11, 0, 7, 0, 11, 0, 7, 4 }, -/* 194: 1, 6, 7, */ { 5, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 10 }, -/* 28: 2, 3, 4, */ { 3, 8, 1, 4, 1, 8, 1, 4, 10, 7, 10, 4, 10, 7, 11 }, -/* 44: 2, 3, 5, */ { 3, 9, 1, 9, 3, 4, 11, 4, 3, 4, 11, 5, 10, 5, 11 }, -/* 52: 2, 4, 5, */ { 7, 10, 5, 10, 7, 2, 8, 2, 7, 2, 8, 1, 9, 1, 8 }, -/* 84: 2, 4, 6, */ { 6, 7, 2, 8, 2, 7, 2, 8, 1, 4, 1, 8, 1, 4, 5 }, -/* 148: 2, 4, 7, */ { 6, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 11 }, -/* 56: 3, 4, 5, */ { 7, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 8 }, -/* 104: 3, 5, 6, */ { 4, 11, 6, 11, 4, 3, 9, 3, 4, 3, 9, 2, 10, 2, 9 }, -/* 168: 3, 5, 7, */ { 7, 4, 3, 9, 3, 4, 3, 9, 2, 5, 2, 9, 2, 5, 6 }, -/* 87: 0, 1, 2, 4, 6, */ { 3, 4, 7, 4, 3, 9, 2, 9, 3, 9, 2, 5, 6, 5, 2 }, -/* 151: 0, 1, 2, 4, 7, */ { 6, 11, 4, 3, 4, 11, 4, 3, 9, 2, 9, 3, 9, 2, 10 }, -/* 199: 0, 1, 2, 6, 7, */ { 5, 11, 7, 11, 5, 2, 9, 2, 5, 2, 9, 3, 8, 3, 9 }, -/* 107: 0, 1, 3, 5, 6, */ { 4, 10, 6, 10, 4, 1, 8, 1, 4, 1, 8, 2, 11, 2, 8 }, -/* 171: 0, 1, 3, 5, 7, */ { 2, 7, 6, 7, 2, 8, 1, 8, 2, 8, 1, 4, 5, 4, 1 }, -/* 203: 0, 1, 3, 6, 7, */ { 5, 10, 7, 2, 7, 10, 7, 2, 8, 1, 8, 2, 8, 1, 9 }, -/* 211: 0, 1, 4, 6, 7, */ { 1, 9, 3, 4, 3, 9, 3, 4, 11, 5, 11, 4, 11, 5, 10 }, -/* 227: 0, 1, 5, 6, 7, */ { 1, 8, 3, 8, 1, 4, 10, 4, 1, 4, 10, 7, 11, 7, 10 }, -/* 61: 0, 2, 3, 4, 5, */ { 7, 9, 5, 9, 7, 0, 11, 0, 7, 0, 11, 1, 10, 1, 11 }, -/* 93: 0, 2, 3, 4, 6, */ { 1, 6, 5, 6, 1, 11, 0, 11, 1, 11, 0, 7, 4, 7, 0 }, -/* 109: 0, 2, 3, 5, 6, */ { 4, 9, 6, 1, 6, 9, 6, 1, 11, 0, 11, 1, 11, 0, 8 }, -/* 117: 0, 2, 4, 5, 6, */ { 3, 0, 7, 9, 7, 0, 7, 9, 6, 1, 6, 9, 6, 1, 2 }, -/* 213: 0, 2, 4, 6, 7, */ { 1, 2, 5, 11, 5, 2, 5, 11, 4, 3, 4, 11, 4, 3, 0 }, -/* 121: 0, 3, 4, 5, 6, */ { 0, 11, 2, 11, 0, 7, 9, 7, 0, 7, 9, 6, 10, 6, 9 }, -/* 233: 0, 3, 5, 6, 7, */ { 0, 8, 2, 7, 2, 8, 2, 7, 10, 4, 10, 7, 10, 4, 9 }, -/* 62: 1, 2, 3, 4, 5, */ { 7, 8, 5, 0, 5, 8, 5, 0, 10, 3, 10, 0, 10, 3, 11 }, -/* 158: 1, 2, 3, 4, 7, */ { 6, 8, 4, 8, 6, 3, 10, 3, 6, 3, 10, 0, 9, 0, 10 }, -/* 174: 1, 2, 3, 5, 7, */ { 0, 5, 4, 5, 0, 10, 3, 10, 0, 10, 3, 6, 7, 6, 3 }, -/* 182: 1, 2, 4, 5, 7, */ { 2, 10, 0, 5, 0, 10, 0, 5, 8, 6, 8, 5, 8, 6, 11 }, -/* 214: 1, 2, 4, 6, 7, */ { 2, 9, 0, 9, 2, 5, 11, 5, 2, 5, 11, 4, 8, 4, 11 }, -/* 186: 1, 3, 4, 5, 7, */ { 2, 3, 6, 8, 6, 3, 6, 8, 5, 0, 5, 8, 5, 0, 1 }, -/* 234: 1, 3, 5, 6, 7, */ { 0, 1, 4, 10, 4, 1, 4, 10, 7, 2, 7, 10, 7, 2, 3 }, -/* 124: 2, 3, 4, 5, 6, */ { 3, 11, 1, 6, 1, 11, 1, 6, 9, 7, 9, 6, 9, 7, 8 }, -/* 188: 2, 3, 4, 5, 7, */ { 3, 10, 1, 10, 3, 6, 8, 6, 3, 6, 8, 5, 9, 5, 8 } -}; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief test table for case 7 - * 3 faces to test + eventually the interior - * When the tests on the 3 specified faces are positive : - * - if the test on the interior is positive : 5 first triangles - * - if the test on the interior is negative : 9 next triangles - * When the tests on the first and the second specified faces are positive : 9 next triangles - * When the tests on the first and the third specified faces are positive : 9 next triangles - * When the tests on the second and the third specified faces are positive : 9 next triangles - * When the test on the first specified face is positive : 5 next triangles - * When the test on the second specified face is positive : 5 next triangles - * When the test on the third specified face is positive : 5 next triangles - * When the tests on the 3 specified faces are negative : 3 last triangles - * The support edge for the interior test is marked as the 5th column. - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test7[16][5] = { -/* 37: 0, 2, 5, */ { 1, 2, 5, 7, 1 }, -/* 133: 0, 2, 7, */ { 3, 4, 5, 7, 3 }, -/* 161: 0, 5, 7, */ { 4, 1, 6, 7, 4 }, -/* 26: 1, 3, 4, */ { 4, 1, 5, 7, 0 }, -/* 74: 1, 3, 6, */ { 2, 3, 5, 7, 2 }, -/* 82: 1, 4, 6, */ { 1, 2, 6, 7, 5 }, -/* 164: 2, 5, 7, */ { 2, 3, 6, 7, 6 }, -/* 88: 3, 4, 6, */ { 3, 4, 6, 7, 7 }, -/* 167: 0, 1, 2, 5, 7, */ { -3, -4, -6, -7, 7 }, -/* 91: 0, 1, 3, 4, 6, */ { -2, -3, -6, -7, 6 }, -/* 173: 0, 2, 3, 5, 7, */ { -1, -2, -6, -7, 5 }, -/* 181: 0, 2, 4, 5, 7, */ { -2, -3, -5, -7, 2 }, -/* 229: 0, 2, 5, 6, 7, */ { -4, -1, -5, -7, 0 }, -/* 94: 1, 2, 3, 4, 6, */ { -4, -1, -6, -7, 4 }, -/* 122: 1, 3, 4, 5, 6, */ { -3, -4, -5, -7, 3 }, -/* 218: 1, 3, 4, 6, 7, */ { -1, -2, -5, -7, 1 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 7.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling7_1[16][9] = { -/* 37: 0, 2, 5, */ { 9, 5, 4, 10, 1, 2, 8, 3, 0 }, -/* 133: 0, 2, 7, */ { 11, 7, 6, 8, 3, 0, 10, 1, 2 }, -/* 161: 0, 5, 7, */ { 3, 0, 8, 5, 4, 9, 7, 6, 11 }, -/* 26: 1, 3, 4, */ { 8, 4, 7, 9, 0, 1, 11, 2, 3 }, -/* 74: 1, 3, 6, */ { 10, 6, 5, 11, 2, 3, 9, 0, 1 }, -/* 82: 1, 4, 6, */ { 0, 1, 9, 6, 5, 10, 4, 7, 8 }, -/* 164: 2, 5, 7, */ { 1, 2, 10, 7, 6, 11, 5, 4, 9 }, -/* 88: 3, 4, 6, */ { 2, 3, 11, 4, 7, 8, 6, 5, 10 }, -/* 167: 0, 1, 2, 5, 7, */ { 11, 3, 2, 8, 7, 4, 10, 5, 6 }, -/* 91: 0, 1, 3, 4, 6, */ { 10, 2, 1, 11, 6, 7, 9, 4, 5 }, -/* 173: 0, 2, 3, 5, 7, */ { 9, 1, 0, 10, 5, 6, 8, 7, 4 }, -/* 181: 0, 2, 4, 5, 7, */ { 5, 6, 10, 3, 2, 11, 1, 0, 9 }, -/* 229: 0, 2, 5, 6, 7, */ { 7, 4, 8, 1, 0, 9, 3, 2, 11 }, -/* 94: 1, 2, 3, 4, 6, */ { 8, 0, 3, 9, 4, 5, 11, 6, 7 }, -/* 122: 1, 3, 4, 5, 6, */ { 6, 7, 11, 0, 3, 8, 2, 1, 10 }, -/* 218: 1, 3, 4, 6, 7, */ { 4, 5, 9, 2, 1, 10, 0, 3, 8 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 7.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling7_2[16][3][15] = { -/* 37: 0, 2, 5, */ { - /* 1,0 */ { 1, 2, 10, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 }, - /* 0,1 */ { 3, 0, 8, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 }, - /* 1,1 */ { 9, 5, 4, 0, 10, 1, 10, 0, 8, 10, 8, 2, 3, 2, 8 } -}, -/* 133: 0, 2, 7, */ { - /* 1,0 */ { 3, 0, 8, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 }, - /* 0,1 */ { 1, 2, 10, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 }, - /* 1,1 */ { 11, 7, 6, 2, 8, 3, 8, 2, 10, 8, 10, 0, 1, 0, 10 } -}, -/* 161: 0, 5, 7, */ { - /* 1,0 */ { 9, 5, 4, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 }, - /* 0,1 */ { 11, 7, 6, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 }, - /* 1,1 */ { 3, 0, 8, 4, 9, 7, 11, 7, 9, 5, 11, 9, 11, 5, 6 } -}, -/* 26: 1, 3, 4, */ { - /* 1,0 */ { 0, 1, 9, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 }, - /* 0,1 */ { 2, 3, 11, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 }, - /* 1,1 */ { 8, 4, 7, 3, 9, 0, 9, 3, 11, 9, 11, 1, 2, 1, 11 } -}, -/* 74: 1, 3, 6, */ { - /* 1,0 */ { 2, 3, 11, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 }, - /* 0,1 */ { 0, 1, 9, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 }, - /* 1,1 */ { 6, 5, 10, 1, 11, 2, 11, 1, 9, 11, 9, 3, 0, 3, 9 } -}, -/* 82: 1, 4, 6, */ { - /* 1,0 */ { 6, 5, 10, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 }, - /* 0,1 */ { 8, 4, 7, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 }, - /* 1,1 */ { 0, 1, 9, 5, 10, 4, 8, 4, 10, 6, 8, 10, 8, 6, 7 } -}, -/* 164: 2, 5, 7, */ { - /* 1,0 */ { 11, 7, 6, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 }, - /* 0,1 */ { 9, 5, 4, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 }, - /* 1,1 */ { 1, 2, 10, 6, 11, 5, 9, 5, 11, 7, 9, 11, 9, 7, 4 } -}, -/* 88: 3, 4, 6, */ { - /* 1,0 */ { 8, 4, 7, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 }, - /* 0,1 */ { 6, 5, 10, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 }, - /* 1,1 */ { 2, 3, 11, 7, 8, 6, 10, 6, 8, 4, 10, 8, 10, 4, 5 } -}, -/* 167: 0, 1, 2, 5, 7, */ { - /* 1,0 */ { 7, 4, 8, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 }, - /* 0,1 */ { 10, 5, 6, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 }, - /* 1,1 */ { 11, 3, 2, 6, 8, 7, 8, 6, 10, 8, 10, 4, 5, 4, 10 } -}, -/* 91: 0, 1, 3, 4, 6, */ { - /* 1,0 */ { 6, 7, 11, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 }, - /* 0,1 */ { 4, 5, 9, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 }, - /* 1,1 */ { 10, 2, 1, 5, 11, 6, 11, 5, 9, 11, 9, 7, 4, 7, 9 } -}, -/* 173: 0, 2, 3, 5, 7, */ { - /* 1,0 */ { 10, 5, 6, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 }, - /* 0,1 */ { 7, 4, 8, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 }, - /* 1,1 */ { 9, 1, 0, 4, 10, 5, 10, 4, 8, 10, 8, 6, 7, 6, 8 } -}, -/* 181: 0, 2, 4, 5, 7, */ { - /* 1,0 */ { 11, 3, 2, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 }, - /* 0,1 */ { 9, 1, 0, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 }, - /* 1,1 */ { 10, 5, 6, 2, 11, 1, 9, 1, 11, 3, 9, 11, 9, 3, 0 } -}, -/* 229: 0, 2, 5, 6, 7, */ { - /* 1,0 */ { 9, 1, 0, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 }, - /* 0,1 */ { 11, 3, 2, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 }, - /* 1,1 */ { 7, 4, 8, 0, 9, 3, 11, 3, 9, 1, 11, 9, 11, 1, 2 } -}, -/* 94: 1, 2, 3, 4, 6, */ { - /* 1,0 */ { 4, 5, 9, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 }, - /* 0,1 */ { 6, 7, 11, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 }, - /* 1,1 */ { 8, 0, 3, 7, 9, 4, 9, 7, 11, 9, 11, 5, 6, 5, 11 } -}, -/* 122: 1, 3, 4, 5, 6, */ { - /* 1,0 */ { 8, 0, 3, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 }, - /* 0,1 */ { 10, 2, 1, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 }, - /* 1,1 */ { 6, 7, 11, 3, 8, 2, 10, 2, 8, 0, 10, 8, 10, 0, 1 } -}, -/* 218: 1, 3, 4, 6, 7, */ { - /* 1,0 */ { 10, 2, 1, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 }, - /* 0,1 */ { 8, 0, 3, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 }, - /* 1,1 */ { 4, 5, 9, 1, 10, 0, 8, 0, 10, 2, 8, 10, 8, 2, 3 } } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 7.3 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling7_3[16][3][27] = { -/* 37: 0, 2, 5, */ { - /* 1,0 */ { 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 }, - /* 0,1 */ { 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 }, - /* 1,1 */ { 5, 4, 12, 10, 5, 12, 2, 10, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 } -}, -/* 133: 0, 2, 7, */ { - /* 1,0 */ { 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 }, - /* 0,1 */ { 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 }, - /* 1,1 */ { 7, 6, 12, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 } -}, -/* 161: 0, 5, 7, */ { - /* 1,0 */ { 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12 }, - /* 0,1 */ { 3, 0, 12, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12, 8, 7, 12, 0, 8, 12 }, - /* 1,1 */ { 12, 3, 0, 12, 0, 9, 12, 9, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 } -}, -/* 26: 1, 3, 4, */ { - /* 1,0 */ { 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 }, - /* 0,1 */ { 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 8, 12, 8, 4 }, - /* 1,1 */ { 4, 7, 12, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 8, 0, 12, 7, 8, 12 } -}, -/* 74: 1, 3, 6, */ { - /* 1,0 */ { 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 }, - /* 0,1 */ { 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 10, 12, 10, 6 }, - /* 1,1 */ { 6, 5, 12, 11, 6, 12, 3, 11, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12 } -}, -/* 82: 1, 4, 6, */ { - /* 1,0 */ { 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12 }, - /* 0,1 */ { 0, 1, 12, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12, 9, 4, 12, 1, 9, 12 }, - /* 1,1 */ { 12, 0, 1, 12, 1, 10, 12, 10, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 } -}, -/* 164: 2, 5, 7, */ { - /* 1,0 */ { 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12 }, - /* 0,1 */ { 1, 2, 12, 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 6, 11, 12, 5, 6, 12, 10, 5, 12, 2, 10, 12 }, - /* 1,1 */ { 12, 1, 2, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 } -}, -/* 88: 3, 4, 6, */ { - /* 1,0 */ { 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12 }, - /* 0,1 */ { 2, 3, 12, 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 7, 8, 12, 6, 7, 12, 11, 6, 12, 3, 11, 12 }, - /* 1,1 */ { 12, 2, 3, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 } -}, -/* 167: 0, 1, 2, 5, 7, */ { - /* 1,0 */ { 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4 }, - /* 0,1 */ { 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 7, 12, 7, 6, 12, 6, 11, 12, 11, 3 }, - /* 1,1 */ { 3, 2, 12, 8, 3, 12, 4, 8, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 } -}, -/* 91: 0, 1, 3, 4, 6, */ { - /* 1,0 */ { 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7 }, - /* 0,1 */ { 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 6, 12, 6, 5, 12, 5, 10, 12, 10, 2 }, - /* 1,1 */ { 2, 1, 12, 11, 2, 12, 7, 11, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 } -}, -/* 173: 0, 2, 3, 5, 7, */ { - /* 1,0 */ { 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6 }, - /* 0,1 */ { 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 5, 12, 5, 4, 12, 4, 9, 12, 9, 1 }, - /* 1,1 */ { 1, 0, 12, 10, 1, 12, 6, 10, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 } -}, -/* 181: 0, 2, 4, 5, 7, */ { - /* 1,0 */ { 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 }, - /* 0,1 */ { 5, 6, 12, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 10, 1, 12, 6, 10, 12 }, - /* 1,1 */ { 12, 5, 6, 12, 6, 11, 12, 11, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5 } -}, -/* 229: 0, 2, 5, 6, 7, */ { - /* 1,0 */ { 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 2, 11, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12 }, - /* 0,1 */ { 7, 4, 12, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 8, 3, 12, 4, 8, 12 }, - /* 1,1 */ { 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 8, 12, 8, 7 } -}, -/* 94: 1, 2, 3, 4, 6, */ { - /* 1,0 */ { 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5 }, - /* 0,1 */ { 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 4, 12, 4, 7, 12, 7, 8, 12, 8, 0 }, - /* 1,1 */ { 0, 3, 12, 9, 0, 12, 5, 9, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 } -}, -/* 122: 1, 3, 4, 5, 6, */ { - /* 1,0 */ { 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 }, - /* 0,1 */ { 6, 7, 12, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 }, - /* 1,1 */ { 12, 6, 7, 12, 7, 8, 12, 8, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 } -}, -/* 218: 1, 3, 4, 6, 7, */ { - /* 1,0 */ { 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12 }, - /* 0,1 */ { 4, 5, 12, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 }, - /* 1,1 */ { 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 } } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 7.4.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling7_4_1[16][15] = { -/* 37: 0, 2, 5, */ { 3, 4, 8, 4, 3, 10, 2, 10, 3, 4, 10, 5, 9, 1, 0 }, -/* 133: 0, 2, 7, */ { 1, 6, 10, 6, 1, 8, 0, 8, 1, 6, 8, 7, 11, 3, 2 }, -/* 161: 0, 5, 7, */ { 11, 3, 6, 9, 6, 3, 6, 9, 5, 0, 9, 3, 7, 4, 8 }, -/* 26: 1, 3, 4, */ { 2, 7, 11, 7, 2, 9, 1, 9, 2, 7, 9, 4, 8, 0, 3 }, -/* 74: 1, 3, 6, */ { 0, 5, 9, 5, 0, 11, 3, 11, 0, 5, 11, 6, 10, 2, 1 }, -/* 82: 1, 4, 6, */ { 8, 0, 7, 10, 7, 0, 7, 10, 6, 1, 10, 0, 4, 5, 9 }, -/* 164: 2, 5, 7, */ { 9, 1, 4, 11, 4, 1, 4, 11, 7, 2, 11, 1, 5, 6, 10 }, -/* 88: 3, 4, 6, */ { 10, 2, 5, 8, 5, 2, 5, 8, 4, 3, 8, 2, 6, 7, 11 }, -/* 167: 0, 1, 2, 5, 7, */ { 5, 2, 10, 2, 5, 8, 4, 8, 5, 2, 8, 3, 11, 7, 6 }, -/* 91: 0, 1, 3, 4, 6, */ { 4, 1, 9, 1, 4, 11, 7, 11, 4, 1, 11, 2, 10, 6, 5 }, -/* 173: 0, 2, 3, 5, 7, */ { 7, 0, 8, 0, 7, 10, 6, 10, 7, 0, 10, 1, 9, 5, 4 }, -/* 181: 0, 2, 4, 5, 7, */ { 9, 5, 0, 11, 0, 5, 0, 11, 3, 6, 11, 5, 1, 2, 10 }, -/* 229: 0, 2, 5, 6, 7, */ { 11, 7, 2, 9, 2, 7, 2, 9, 1, 4, 9, 7, 3, 0, 8 }, -/* 94: 1, 2, 3, 4, 6, */ { 6, 3, 11, 3, 6, 9, 5, 9, 6, 3, 9, 0, 8, 4, 7 }, -/* 122: 1, 3, 4, 5, 6, */ { 10, 6, 1, 8, 1, 6, 1, 8, 0, 7, 8, 6, 2, 3, 11 }, -/* 218: 1, 3, 4, 6, 7, */ { 8, 4, 3, 10, 3, 4, 3, 10, 2, 5, 10, 4, 0, 1, 9 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 7.4.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling7_4_2[16][27] = { -/* 37: 0, 2, 5, */ { 9, 4, 8, 4, 9, 5, 10, 5, 9, 1, 10, 9, 10, 1, 2, 0, 2, 1, 2, 0, 3, 8, 3, 0, 9, 8, 0 }, -/* 133: 0, 2, 7, */ { 11, 6, 10, 6, 11, 7, 8, 7, 11, 3, 8, 11, 8, 3, 0, 2, 0, 3, 0, 2, 1, 10, 1, 2, 11, 10, 2 }, -/* 161: 0, 5, 7, */ { 11, 3, 8, 0, 8, 3, 8, 0, 9, 8, 9, 4, 5, 4, 9, 4, 5, 7, 6, 7, 5, 7, 6, 11, 7, 11, 8 }, -/* 26: 1, 3, 4, */ { 8, 7, 11, 7, 8, 4, 9, 4, 8, 0, 9, 8, 9, 0, 1, 3, 1, 0, 1, 3, 2, 11, 2, 3, 8, 11, 3 }, -/* 74: 1, 3, 6, */ { 10, 5, 9, 5, 10, 6, 11, 6, 10, 2, 11, 10, 11, 2, 3, 1, 3, 2, 3, 1, 0, 9, 0, 1, 10, 9, 1 }, -/* 82: 1, 4, 6, */ { 8, 0, 9, 1, 9, 0, 9, 1, 10, 9, 10, 5, 6, 5, 10, 5, 6, 4, 7, 4, 6, 4, 7, 8, 4, 8, 9 }, -/* 164: 2, 5, 7, */ { 9, 1, 10, 2, 10, 1, 10, 2, 11, 10, 11, 6, 7, 6, 11, 6, 7, 5, 4, 5, 7, 5, 4, 9, 5, 9, 10 }, -/* 88: 3, 4, 6, */ { 10, 2, 11, 3, 11, 2, 11, 3, 8, 11, 8, 7, 4, 7, 8, 7, 4, 6, 5, 6, 4, 6, 5, 10, 6, 10, 11 }, -/* 167: 0, 1, 2, 5, 7, */ { 11, 2, 10, 2, 11, 3, 8, 3, 11, 7, 8, 11, 8, 7, 4, 6, 4, 7, 4, 6, 5, 10, 5, 6, 11, 10, 6 }, -/* 91: 0, 1, 3, 4, 6, */ { 10, 1, 9, 1, 10, 2, 11, 2, 10, 6, 11, 10, 11, 6, 7, 5, 7, 6, 7, 5, 4, 9, 4, 5, 10, 9, 5 }, -/* 173: 0, 2, 3, 5, 7, */ { 9, 0, 8, 0, 9, 1, 10, 1, 9, 5, 10, 9, 10, 5, 6, 4, 6, 5, 6, 4, 7, 8, 7, 4, 9, 8, 4 }, -/* 181: 0, 2, 4, 5, 7, */ { 9, 5, 10, 6, 10, 5, 10, 6, 11, 10, 11, 2, 3, 2, 11, 2, 3, 1, 0, 1, 3, 1, 0, 9, 1, 9, 10 }, -/* 229: 0, 2, 5, 6, 7, */ { 11, 7, 8, 4, 8, 7, 8, 4, 9, 8, 9, 0, 1, 0, 9, 0, 1, 3, 2, 3, 1, 3, 2, 11, 3, 11, 8 }, -/* 94: 1, 2, 3, 4, 6, */ { 8, 3, 11, 3, 8, 0, 9, 0, 8, 4, 9, 8, 9, 4, 5, 7, 5, 4, 5, 7, 6, 11, 6, 7, 8, 11, 7 }, -/* 122: 1, 3, 4, 5, 6, */ { 10, 6, 11, 7, 11, 6, 11, 7, 8, 11, 8, 3, 0, 3, 8, 3, 0, 2, 1, 2, 0, 2, 1, 10, 2, 10, 11 }, -/* 218: 1, 3, 4, 6, 7, */ { 8, 4, 9, 5, 9, 4, 9, 5, 10, 9, 10, 1, 2, 1, 10, 1, 2, 0, 3, 0, 2, 0, 3, 8, 0, 8, 9 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 8 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling8[6][6] = { -/* 15: 0, 1, 2, 3, */ { 9, 8, 10, 10, 8, 11 }, -/* 51: 0, 1, 4, 5, */ { 1, 5, 3, 3, 5, 7 }, -/* 153: 0, 3, 4, 7, */ { 0, 4, 2, 4, 6, 2 }, -/* 102: 1, 2, 5, 6, */ { 0, 2, 4, 4, 2, 6 }, -/* 204: 2, 3, 6, 7, */ { 1, 3, 5, 3, 7, 5 }, -/* 240: 4, 5, 6, 7, */ { 9, 10, 8, 10, 11, 8 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 9 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling9[8][12] = { -/* 39: 0, 1, 2, 5, */ { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8 }, -/* 27: 0, 1, 3, 4, */ { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1 }, -/* 141: 0, 2, 3, 7, */ { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8 }, -/* 177: 0, 4, 5, 7, */ { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5 }, -/* 78: 1, 2, 3, 6, */ { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9 }, -/* 114: 1, 4, 5, 6, */ { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0 }, -/* 228: 2, 5, 6, 7, */ { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2 }, -/* 216: 3, 4, 6, 7, */ { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4 } -}; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief test table for case 10 - * 2 faces to test + eventually the interior - * When the tests on both specified faces are positive : 4 middle triangles (1) - * When the test on the first specified face is positive : 8 first triangles - * When the test on the second specified face is positive : 8 next triangles - * When the tests on both specified faces are negative : - * - if the test on the interior is negative : 4 middle triangles - * - if the test on the interior is positive : 8 last triangles - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test10[6][3] = { -/* 195: 0, 1, 6, 7, */ { 2, 4, 7 }, -/* 85: 0, 2, 4, 6, */ { 5, 6, 7 }, -/* 105: 0, 3, 5, 6, */ { 1, 3, 7 }, -/* 150: 1, 2, 4, 7, */ { 1, 3, 7 }, -/* 170: 1, 3, 5, 7, */ { 5, 6, 7 }, -/* 60: 2, 3, 4, 5, */ { 2, 4, 7 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 10.1.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling10_1_1[6][12] = { -/* 195: 0, 1, 6, 7, */ { 5, 10, 7, 11, 7, 10, 8, 1, 9, 1, 8, 3 }, -/* 85: 0, 2, 4, 6, */ { 1, 2, 5, 6, 5, 2, 4, 3, 0, 3, 4, 7 }, -/* 105: 0, 3, 5, 6, */ { 11, 0, 8, 0, 11, 2, 4, 9, 6, 10, 6, 9 }, -/* 150: 1, 2, 4, 7, */ { 9, 0, 10, 2, 10, 0, 6, 8, 4, 8, 6, 11 }, -/* 170: 1, 3, 5, 7, */ { 7, 2, 3, 2, 7, 6, 0, 1, 4, 5, 4, 1 }, -/* 60: 2, 3, 4, 5, */ { 7, 9, 5, 9, 7, 8, 10, 1, 11, 3, 11, 1 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 10.1.1 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling10_1_1_[6][12] = { -/* 195: 0, 1, 6, 7, */ { 5, 9, 7, 8, 7, 9, 11, 1, 10, 1, 11, 3 }, -/* 85: 0, 2, 4, 6, */ { 3, 2, 7, 6, 7, 2, 4, 1, 0, 1, 4, 5 }, -/* 105: 0, 3, 5, 6, */ { 10, 0, 9, 0, 10, 2, 4, 8, 6, 11, 6, 8 }, -/* 150: 1, 2, 4, 7, */ { 8, 0, 11, 2, 11, 0, 6, 9, 4, 9, 6, 10 }, -/* 170: 1, 3, 5, 7, */ { 5, 2, 1, 2, 5, 6, 0, 3, 4, 7, 4, 3 }, -/* 60: 2, 3, 4, 5, */ { 7, 10, 5, 10, 7, 11, 9, 1, 8, 3, 8, 1 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 10.1.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling10_1_2[6][24] = { -/* 195: 0, 1, 6, 7, */ { 3, 11, 7, 3, 7, 8, 9, 8, 7, 5, 9, 7, 9, 5, 10, 9, 10, 1, 3, 1, 10, 11, 3, 10 }, -/* 85: 0, 2, 4, 6, */ { 7, 6, 5, 7, 5, 4, 0, 4, 5, 1, 0, 5, 0, 1, 2, 0, 2, 3, 7, 3, 2, 6, 7, 2 }, -/* 105: 0, 3, 5, 6, */ { 11, 2, 10, 6, 11, 10, 11, 6, 4, 11, 4, 8, 0, 8, 4, 9, 0, 4, 0, 9, 10, 0, 10, 2 }, -/* 150: 1, 2, 4, 7, */ { 11, 2, 10, 11, 10, 6, 4, 6, 10, 9, 4, 10, 4, 9, 0, 4, 0, 8, 11, 8, 0, 2, 11, 0 }, -/* 170: 1, 3, 5, 7, */ { 7, 6, 5, 4, 7, 5, 7, 4, 0, 7, 0, 3, 2, 3, 0, 1, 2, 0, 2, 1, 5, 2, 5, 6 }, -/* 60: 2, 3, 4, 5, */ { 7, 8, 3, 11, 7, 3, 7, 11, 10, 7, 10, 5, 9, 5, 10, 1, 9, 10, 9, 1, 3, 9, 3, 8 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 10.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling10_2[6][24] = { -/* 195: 0, 1, 6, 7, */ { 12, 5, 9, 12, 9, 8, 12, 8, 3, 12, 3, 1, 12, 1, 10, 12, 10, 11, 12, 11, 7, 12, 7, 5 }, -/* 85: 0, 2, 4, 6, */ { 12, 1, 0, 12, 0, 4, 12, 4, 7, 12, 7, 3, 12, 3, 2, 12, 2, 6, 12, 6, 5, 12, 5, 1 }, -/* 105: 0, 3, 5, 6, */ { 4, 8, 12, 6, 4, 12, 10, 6, 12, 9, 10, 12, 0, 9, 12, 2, 0, 12, 11, 2, 12, 8, 11, 12 }, -/* 150: 1, 2, 4, 7, */ { 12, 9, 4, 12, 4, 6, 12, 6, 11, 12, 11, 8, 12, 8, 0, 12, 0, 2, 12, 2, 10, 12, 10, 9 }, -/* 170: 1, 3, 5, 7, */ { 0, 3, 12, 4, 0, 12, 5, 4, 12, 1, 5, 12, 2, 1, 12, 6, 2, 12, 7, 6, 12, 3, 7, 12 }, -/* 60: 2, 3, 4, 5, */ { 10, 5, 12, 11, 10, 12, 3, 11, 12, 1, 3, 12, 9, 1, 12, 8, 9, 12, 7, 8, 12, 5, 7, 12 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 10.2 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling10_2_[6][24] = { -/* 195: 0, 1, 6, 7, */ { 8, 7, 12, 9, 8, 12, 1, 9, 12, 3, 1, 12, 11, 3, 12, 10, 11, 12, 5, 10, 12, 7, 5, 12 }, -/* 85: 0, 2, 4, 6, */ { 4, 5, 12, 0, 4, 12, 3, 0, 12, 7, 3, 12, 6, 7, 12, 2, 6, 12, 1, 2, 12, 5, 1, 12 }, -/* 105: 0, 3, 5, 6, */ { 12, 11, 6, 12, 6, 4, 12, 4, 9, 12, 9, 10, 12, 10, 2, 12, 2, 0, 12, 0, 8, 12, 8, 11 }, -/* 150: 1, 2, 4, 7, */ { 6, 10, 12, 4, 6, 12, 8, 4, 12, 11, 8, 12, 2, 11, 12, 0, 2, 12, 9, 0, 12, 10, 9, 12 }, -/* 170: 1, 3, 5, 7, */ { 12, 7, 4, 12, 4, 0, 12, 0, 1, 12, 1, 5, 12, 5, 6, 12, 6, 2, 12, 2, 3, 12, 3, 7 }, -/* 60: 2, 3, 4, 5, */ { 12, 7, 11, 12, 11, 10, 12, 10, 1, 12, 1, 3, 12, 3, 8, 12, 8, 9, 12, 9, 5, 12, 5, 7 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 11 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling11[12][12] = { -/* 23: 0, 1, 2, 4, */ { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4 }, -/* 139: 0, 1, 3, 7, */ { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6 }, -/* 99: 0, 1, 5, 6, */ { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10 }, -/* 77: 0, 2, 3, 6, */ { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6 }, -/* 57: 0, 3, 4, 5, */ { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11 }, -/* 209: 0, 4, 6, 7, */ { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0 }, -/* 46: 1, 2, 3, 5, */ { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3 }, -/* 198: 1, 2, 6, 7, */ { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7 }, -/* 178: 1, 4, 5, 7, */ { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11 }, -/* 156: 2, 3, 4, 7, */ { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1 }, -/* 116: 2, 4, 5, 6, */ { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7 }, -/* 232: 3, 5, 6, 7, */ { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief test table for case 12 - * 2 faces to test + eventually the interior - * When the tests on both specified faces are positive : 4 middle triangles (1) - * When the test on the first specified face is positive : 8 first triangles - * When the test on the second specified face is positive : 8 next triangles - * When the tests on both specified faces are negative : - * - if the test on the interior is negative : 4 middle triangles - * - if the test on the interior is positive : 8 last triangles - * The support edge for the interior test is marked as the 4th column. - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test12[24][4] = { -/* 135: 0, 1, 2, 7, */ { 4, 3, 7, 11 }, -/* 75: 0, 1, 3, 6, */ { 3, 2, 7, 10 }, -/* 83: 0, 1, 4, 6, */ { 2, 6, 7, 5 }, -/* 163: 0, 1, 5, 7, */ { 6, 4, 7, 7 }, -/* 45: 0, 2, 3, 5, */ { 2, 1, 7, 9 }, -/* 53: 0, 2, 4, 5, */ { 5, 2, 7, 1 }, -/* 149: 0, 2, 4, 7, */ { 5, 3, 7, 2 }, -/* 101: 0, 2, 5, 6, */ { 5, 1, 7, 0 }, -/* 197: 0, 2, 6, 7, */ { 5, 4, 7, 3 }, -/* 89: 0, 3, 4, 6, */ { 6, 3, 7, 6 }, -/* 169: 0, 3, 5, 7, */ { 1, 6, 7, 4 }, -/* 225: 0, 5, 6, 7, */ { 1, 4, 7, 8 }, -/* 30: 1, 2, 3, 4, */ { 4, 1, 7, 8 }, -/* 86: 1, 2, 4, 6, */ { 6, 1, 7, 4 }, -/* 166: 1, 2, 5, 7, */ { 3, 6, 7, 6 }, -/* 58: 1, 3, 4, 5, */ { 4, 5, 7, 3 }, -/* 154: 1, 3, 4, 7, */ { 1, 5, 7, 0 }, -/* 106: 1, 3, 5, 6, */ { 3, 5, 7, 2 }, -/* 202: 1, 3, 6, 7, */ { 2, 5, 7, 1 }, -/* 210: 1, 4, 6, 7, */ { 1, 2, 7, 9 }, -/* 92: 2, 3, 4, 6, */ { 4, 6, 7, 7 }, -/* 172: 2, 3, 5, 7, */ { 6, 2, 7, 5 }, -/* 180: 2, 4, 5, 7, */ { 2, 3, 7, 10 }, -/* 120: 3, 4, 5, 6, */ { 3, 4, 7, 11 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 12.1.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling12_1_1[24][12] = { -/* 135: 0, 1, 2, 7, */ { 7, 6, 11, 10, 3, 2, 3, 10, 8, 9, 8, 10 }, -/* 75: 0, 1, 3, 6, */ { 6, 5, 10, 9, 2, 1, 2, 9, 11, 8, 11, 9 }, -/* 83: 0, 1, 4, 6, */ { 10, 6, 5, 7, 9, 4, 9, 7, 1, 3, 1, 7 }, -/* 163: 0, 1, 5, 7, */ { 7, 6, 11, 4, 8, 5, 3, 5, 8, 5, 3, 1 }, -/* 45: 0, 2, 3, 5, */ { 5, 4, 9, 8, 1, 0, 1, 8, 10, 11, 10, 8 }, -/* 53: 0, 2, 4, 5, */ { 1, 2, 10, 0, 9, 3, 5, 3, 9, 3, 5, 7 }, -/* 149: 0, 2, 4, 7, */ { 10, 1, 2, 0, 11, 3, 11, 0, 6, 4, 6, 0 }, -/* 101: 0, 2, 5, 6, */ { 8, 3, 0, 2, 9, 1, 9, 2, 4, 6, 4, 2 }, -/* 197: 0, 2, 6, 7, */ { 3, 0, 8, 2, 11, 1, 7, 1, 11, 1, 7, 5 }, -/* 89: 0, 3, 4, 6, */ { 6, 5, 10, 7, 11, 4, 2, 4, 11, 4, 2, 0 }, -/* 169: 0, 3, 5, 7, */ { 9, 5, 4, 6, 8, 7, 8, 6, 0, 2, 0, 6 }, -/* 225: 0, 5, 6, 7, */ { 8, 3, 0, 7, 4, 11, 9, 11, 4, 11, 9, 10 }, -/* 30: 1, 2, 3, 4, */ { 4, 7, 8, 11, 0, 3, 0, 11, 9, 10, 9, 11 }, -/* 86: 1, 2, 4, 6, */ { 4, 7, 8, 5, 9, 6, 0, 6, 9, 6, 0, 2 }, -/* 166: 1, 2, 5, 7, */ { 11, 7, 6, 4, 10, 5, 10, 4, 2, 0, 2, 4 }, -/* 58: 1, 3, 4, 5, */ { 11, 2, 3, 1, 8, 0, 8, 1, 7, 5, 7, 1 }, -/* 154: 1, 3, 4, 7, */ { 0, 1, 9, 3, 8, 2, 4, 2, 8, 2, 4, 6 }, -/* 106: 1, 3, 5, 6, */ { 2, 3, 11, 1, 10, 0, 6, 0, 10, 0, 6, 4 }, -/* 202: 1, 3, 6, 7, */ { 9, 0, 1, 3, 10, 2, 10, 3, 5, 7, 5, 3 }, -/* 210: 1, 4, 6, 7, */ { 9, 0, 1, 4, 5, 8, 10, 8, 5, 8, 10, 11 }, -/* 92: 2, 3, 4, 6, */ { 8, 4, 7, 5, 11, 6, 11, 5, 3, 1, 3, 5 }, -/* 172: 2, 3, 5, 7, */ { 5, 4, 9, 6, 10, 7, 1, 7, 10, 7, 1, 3 }, -/* 180: 2, 4, 5, 7, */ { 10, 1, 2, 5, 6, 9, 11, 9, 6, 9, 11, 8 }, -/* 120: 3, 4, 5, 6, */ { 11, 2, 3, 6, 7, 10, 8, 10, 7, 10, 8, 9 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 12.1.1 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling12_1_1_[24][12] = { -/* 135: 0, 1, 2, 7, */ { 3, 2, 11, 10, 7, 6, 7, 10, 8, 9, 8, 10 }, -/* 75: 0, 1, 3, 6, */ { 2, 1, 10, 9, 6, 5, 6, 9, 11, 8, 11, 9 }, -/* 83: 0, 1, 4, 6, */ { 9, 4, 5, 7, 10, 6, 10, 7, 1, 3, 1, 7 }, -/* 163: 0, 1, 5, 7, */ { 7, 4, 8, 6, 11, 5, 3, 5, 11, 5, 3, 1 }, -/* 45: 0, 2, 3, 5, */ { 1, 0, 9, 8, 5, 4, 5, 8, 10, 11, 10, 8 }, -/* 53: 0, 2, 4, 5, */ { 1, 0, 9, 2, 10, 3, 5, 3, 10, 3, 5, 7 }, -/* 149: 0, 2, 4, 7, */ { 11, 3, 2, 0, 10, 1, 10, 0, 6, 4, 6, 0 }, -/* 101: 0, 2, 5, 6, */ { 9, 1, 0, 2, 8, 3, 8, 2, 4, 6, 4, 2 }, -/* 197: 0, 2, 6, 7, */ { 3, 2, 11, 0, 8, 1, 7, 1, 8, 1, 7, 5 }, -/* 89: 0, 3, 4, 6, */ { 6, 7, 11, 5, 10, 4, 2, 4, 10, 4, 2, 0 }, -/* 169: 0, 3, 5, 7, */ { 8, 7, 4, 6, 9, 5, 9, 6, 0, 2, 0, 6 }, -/* 225: 0, 5, 6, 7, */ { 8, 7, 4, 3, 0, 11, 9, 11, 0, 11, 9, 10 }, -/* 30: 1, 2, 3, 4, */ { 0, 3, 8, 11, 4, 7, 4, 11, 9, 10, 9, 11 }, -/* 86: 1, 2, 4, 6, */ { 4, 5, 9, 7, 8, 6, 0, 6, 8, 6, 0, 2 }, -/* 166: 1, 2, 5, 7, */ { 10, 5, 6, 4, 11, 7, 11, 4, 2, 0, 2, 4 }, -/* 58: 1, 3, 4, 5, */ { 8, 0, 3, 1, 11, 2, 11, 1, 7, 5, 7, 1 }, -/* 154: 1, 3, 4, 7, */ { 0, 3, 8, 1, 9, 2, 4, 2, 9, 2, 4, 6 }, -/* 106: 1, 3, 5, 6, */ { 2, 1, 10, 3, 11, 0, 6, 0, 11, 0, 6, 4 }, -/* 202: 1, 3, 6, 7, */ { 10, 2, 1, 3, 9, 0, 9, 3, 5, 7, 5, 3 }, -/* 210: 1, 4, 6, 7, */ { 9, 4, 5, 0, 1, 8, 10, 8, 1, 8, 10, 11 }, -/* 92: 2, 3, 4, 6, */ { 11, 6, 7, 5, 8, 4, 8, 5, 3, 1, 3, 5 }, -/* 172: 2, 3, 5, 7, */ { 5, 6, 10, 4, 9, 7, 1, 7, 9, 7, 1, 3 }, -/* 180: 2, 4, 5, 7, */ { 10, 5, 6, 1, 2, 9, 11, 9, 2, 9, 11, 8 }, -/* 120: 3, 4, 5, 6, */ { 11, 6, 7, 2, 3, 10, 8, 10, 3, 10, 8, 9 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 12.1.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling12_1_2[24][24] = { -/* 135: 0, 1, 2, 7, */ { 7, 3, 11, 3, 7, 8, 9, 8, 7, 6, 9, 7, 9, 6, 10, 2, 10, 6, 11, 2, 6, 2, 11, 3 }, -/* 75: 0, 1, 3, 6, */ { 6, 2, 10, 2, 6, 11, 8, 11, 6, 5, 8, 6, 8, 5, 9, 1, 9, 5, 10, 1, 5, 1, 10, 2 }, -/* 83: 0, 1, 4, 6, */ { 10, 9, 5, 9, 10, 1, 3, 1, 10, 6, 3, 10, 3, 6, 7, 4, 7, 6, 5, 4, 6, 4, 5, 9 }, -/* 163: 0, 1, 5, 7, */ { 7, 8, 11, 3, 11, 8, 11, 3, 1, 11, 1, 6, 5, 6, 1, 6, 5, 4, 6, 4, 7, 8, 7, 4 }, -/* 45: 0, 2, 3, 5, */ { 5, 1, 9, 1, 5, 10, 11, 10, 5, 4, 11, 5, 11, 4, 8, 0, 8, 4, 9, 0, 4, 0, 9, 1 }, -/* 53: 0, 2, 4, 5, */ { 1, 9, 10, 5, 10, 9, 10, 5, 7, 10, 7, 2, 3, 2, 7, 2, 3, 0, 2, 0, 1, 9, 1, 0 }, -/* 149: 0, 2, 4, 7, */ { 10, 11, 2, 11, 10, 6, 4, 6, 10, 1, 4, 10, 4, 1, 0, 3, 0, 1, 2, 3, 1, 3, 2, 11 }, -/* 101: 0, 2, 5, 6, */ { 8, 9, 0, 9, 8, 4, 6, 4, 8, 3, 6, 8, 6, 3, 2, 1, 2, 3, 0, 1, 3, 1, 0, 9 }, -/* 197: 0, 2, 6, 7, */ { 3, 11, 8, 7, 8, 11, 8, 7, 5, 8, 5, 0, 1, 0, 5, 0, 1, 2, 0, 2, 3, 11, 3, 2 }, -/* 89: 0, 3, 4, 6, */ { 6, 11, 10, 2, 10, 11, 10, 2, 0, 10, 0, 5, 4, 5, 0, 5, 4, 7, 5, 7, 6, 11, 6, 7 }, -/* 169: 0, 3, 5, 7, */ { 9, 8, 4, 8, 9, 0, 2, 0, 9, 5, 2, 9, 2, 5, 6, 7, 6, 5, 4, 7, 5, 7, 4, 8 }, -/* 225: 0, 5, 6, 7, */ { 8, 4, 0, 9, 0, 4, 0, 9, 10, 0, 10, 3, 11, 3, 10, 3, 11, 7, 3, 7, 8, 4, 8, 7 }, -/* 30: 1, 2, 3, 4, */ { 4, 0, 8, 0, 4, 9, 10, 9, 4, 7, 10, 4, 10, 7, 11, 3, 11, 7, 8, 3, 7, 3, 8, 0 }, -/* 86: 1, 2, 4, 6, */ { 4, 9, 8, 0, 8, 9, 8, 0, 2, 8, 2, 7, 6, 7, 2, 7, 6, 5, 7, 5, 4, 9, 4, 5 }, -/* 166: 1, 2, 5, 7, */ { 11, 10, 6, 10, 11, 2, 0, 2, 11, 7, 0, 11, 0, 7, 4, 5, 4, 7, 6, 5, 7, 5, 6, 10 }, -/* 58: 1, 3, 4, 5, */ { 11, 8, 3, 8, 11, 7, 5, 7, 11, 2, 5, 11, 5, 2, 1, 0, 1, 2, 3, 0, 2, 0, 3, 8 }, -/* 154: 1, 3, 4, 7, */ { 0, 8, 9, 4, 9, 8, 9, 4, 6, 9, 6, 1, 2, 1, 6, 1, 2, 3, 1, 3, 0, 8, 0, 3 }, -/* 106: 1, 3, 5, 6, */ { 2, 10, 11, 6, 11, 10, 11, 6, 4, 11, 4, 3, 0, 3, 4, 3, 0, 1, 3, 1, 2, 10, 2, 1 }, -/* 202: 1, 3, 6, 7, */ { 9, 10, 1, 10, 9, 5, 7, 5, 9, 0, 7, 9, 7, 0, 3, 2, 3, 0, 1, 2, 0, 2, 1, 10 }, -/* 210: 1, 4, 6, 7, */ { 9, 5, 1, 10, 1, 5, 1, 10, 11, 1, 11, 0, 8, 0, 11, 0, 8, 4, 0, 4, 9, 5, 9, 4 }, -/* 92: 2, 3, 4, 6, */ { 8, 11, 7, 11, 8, 3, 1, 3, 8, 4, 1, 8, 1, 4, 5, 6, 5, 4, 7, 6, 4, 6, 7, 11 }, -/* 172: 2, 3, 5, 7, */ { 5, 10, 9, 1, 9, 10, 9, 1, 3, 9, 3, 4, 7, 4, 3, 4, 7, 6, 4, 6, 5, 10, 5, 6 }, -/* 180: 2, 4, 5, 7, */ { 10, 6, 2, 11, 2, 6, 2, 11, 8, 2, 8, 1, 9, 1, 8, 1, 9, 5, 1, 5, 10, 6, 10, 5 }, -/* 120: 3, 4, 5, 6, */ { 11, 7, 3, 8, 3, 7, 3, 8, 9, 3, 9, 2, 10, 2, 9, 2, 10, 6, 2, 6, 11, 7, 11, 6 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 12.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling12_2[24][24] = { -/* 135: 0, 1, 2, 7, */ { 9, 8, 12, 10, 9, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12 }, -/* 75: 0, 1, 3, 6, */ { 8, 11, 12, 9, 8, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12 }, -/* 83: 0, 1, 4, 6, */ { 3, 1, 12, 7, 3, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 }, -/* 163: 0, 1, 5, 7, */ { 12, 3, 1, 12, 1, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 }, -/* 45: 0, 2, 3, 5, */ { 11, 10, 12, 8, 11, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12 }, -/* 53: 0, 2, 4, 5, */ { 12, 5, 7, 12, 7, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 }, -/* 149: 0, 2, 4, 7, */ { 4, 6, 12, 0, 4, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 }, -/* 101: 0, 2, 5, 6, */ { 6, 4, 12, 2, 6, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 }, -/* 197: 0, 2, 6, 7, */ { 12, 7, 5, 12, 5, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 }, -/* 89: 0, 3, 4, 6, */ { 12, 2, 0, 12, 0, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 }, -/* 169: 0, 3, 5, 7, */ { 2, 0, 12, 6, 2, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 }, -/* 225: 0, 5, 6, 7, */ { 12, 9, 10, 12, 10, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9 }, -/* 30: 1, 2, 3, 4, */ { 10, 9, 12, 11, 10, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12 }, -/* 86: 1, 2, 4, 6, */ { 12, 0, 2, 12, 2, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 }, -/* 166: 1, 2, 5, 7, */ { 0, 2, 12, 4, 0, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 }, -/* 58: 1, 3, 4, 5, */ { 5, 7, 12, 1, 5, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 }, -/* 154: 1, 3, 4, 7, */ { 12, 4, 6, 12, 6, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 }, -/* 106: 1, 3, 5, 6, */ { 12, 6, 4, 12, 4, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 }, -/* 202: 1, 3, 6, 7, */ { 7, 5, 12, 3, 7, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 }, -/* 210: 1, 4, 6, 7, */ { 12, 10, 11, 12, 11, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10 }, -/* 92: 2, 3, 4, 6, */ { 1, 3, 12, 5, 1, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 }, -/* 172: 2, 3, 5, 7, */ { 12, 1, 3, 12, 3, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 }, -/* 180: 2, 4, 5, 7, */ { 12, 11, 8, 12, 8, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11 }, -/* 120: 3, 4, 5, 6, */ { 12, 8, 9, 12, 9, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 12.2 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling12_2_[24][24] = { -/* 135: 0, 1, 2, 7, */ { 12, 2, 11, 12, 11, 7, 12, 7, 6, 12, 6, 10, 12, 10, 9, 12, 9, 8, 12, 8, 3, 12, 3, 2 }, -/* 75: 0, 1, 3, 6, */ { 12, 1, 10, 12, 10, 6, 12, 6, 5, 12, 5, 9, 12, 9, 8, 12, 8, 11, 12, 11, 2, 12, 2, 1 }, -/* 83: 0, 1, 4, 6, */ { 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 3, 12, 3, 1, 12, 1, 9, 12, 9, 4 }, -/* 163: 0, 1, 5, 7, */ { 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 1, 5, 12, 3, 1, 12, 11, 3, 12, 6, 11, 12 }, -/* 45: 0, 2, 3, 5, */ { 12, 0, 9, 12, 9, 5, 12, 5, 4, 12, 4, 8, 12, 8, 11, 12, 11, 10, 12, 10, 1, 12, 1, 0 }, -/* 53: 0, 2, 4, 5, */ { 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 7, 3, 12, 5, 7, 12, 10, 5, 12, 2, 10, 12 }, -/* 149: 0, 2, 4, 7, */ { 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 4, 12, 4, 6, 12, 6, 10, 12, 10, 1 }, -/* 101: 0, 2, 5, 6, */ { 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 6, 12, 6, 4, 12, 4, 8, 12, 8, 3 }, -/* 197: 0, 2, 6, 7, */ { 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 5, 1, 12, 7, 5, 12, 8, 7, 12, 0, 8, 12 }, -/* 89: 0, 3, 4, 6, */ { 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 0, 4, 12, 2, 0, 12, 10, 2, 12, 5, 10, 12 }, -/* 169: 0, 3, 5, 7, */ { 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 2, 12, 2, 0, 12, 0, 8, 12, 8, 7 }, -/* 225: 0, 5, 6, 7, */ { 8, 7, 12, 0, 8, 12, 3, 0, 12, 11, 3, 12, 10, 11, 12, 9, 10, 12, 4, 9, 12, 7, 4, 12 }, -/* 30: 1, 2, 3, 4, */ { 12, 7, 8, 12, 8, 0, 12, 0, 3, 12, 3, 11, 12, 11, 10, 12, 10, 9, 12, 9, 4, 12, 4, 7 }, -/* 86: 1, 2, 4, 6, */ { 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 2, 6, 12, 0, 2, 12, 8, 0, 12, 7, 8, 12 }, -/* 166: 1, 2, 5, 7, */ { 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 0, 12, 0, 2, 12, 2, 10, 12, 10, 5 }, -/* 58: 1, 3, 4, 5, */ { 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 5, 12, 5, 7, 12, 7, 8, 12, 8, 0 }, -/* 154: 1, 3, 4, 7, */ { 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 6, 2, 12, 4, 6, 12, 8, 4, 12, 3, 8, 12 }, -/* 106: 1, 3, 5, 6, */ { 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 4, 0, 12, 6, 4, 12, 10, 6, 12, 1, 10, 12 }, -/* 202: 1, 3, 6, 7, */ { 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 7, 12, 7, 5, 12, 5, 10, 12, 10, 2 }, -/* 210: 1, 4, 6, 7, */ { 9, 0, 12, 5, 9, 12, 4, 5, 12, 8, 4, 12, 11, 8, 12, 10, 11, 12, 1, 10, 12, 0, 1, 12 }, -/* 92: 2, 3, 4, 6, */ { 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 1, 12, 1, 3, 12, 3, 11, 12, 11, 6 }, -/* 172: 2, 3, 5, 7, */ { 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 3, 7, 12, 1, 3, 12, 9, 1, 12, 4, 9, 12 }, -/* 180: 2, 4, 5, 7, */ { 10, 1, 12, 6, 10, 12, 5, 6, 12, 9, 5, 12, 8, 9, 12, 11, 8, 12, 2, 11, 12, 1, 2, 12 }, -/* 120: 3, 4, 5, 6, */ { 11, 2, 12, 7, 11, 12, 6, 7, 12, 10, 6, 12, 9, 10, 12, 8, 9, 12, 3, 8, 12, 2, 3, 12 } -}; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief test table for case 13 - * All faces are to be tested - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13: face test */ -static const char test13[2][7] = { -/* 165: 0, 2, 5, 7, */ { 1,2,3,4,5,6,7 }, -/* 90: 1, 3, 4, 6, */ { 2,3,4,1,5,6,7 }, -}; - - - -//_____________________________________________________________________________ -/** - * \brief subconfiguration table for case 13 - * Hard-coded tests for the subconfiguration determination - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13: sub configs */ -static const char subconfig13[64] = { -/* 0: 0,0,0,0,0,0 */ 0, -/* 1: 1,0,0,0,0,0 */ 1, -/* 2: 0,1,0,0,0,0 */ 2, -/* 3: 1,1,0,0,0,0 */ 7, -/* 4: 0,0,1,0,0,0 */ 3, -/* 5: 1,0,1,0,0,0 */ -1, -/* 6: 0,1,1,0,0,0 */ 11, -/* 7: 1,1,1,0,0,0 */ -1, -/* 8: 0,0,0,1,0,0 */ 4, -/* 9: 1,0,0,1,0,0 */ 8, -/* 10: 0,1,0,1,0,0 */ -1, -/* 11: 1,1,0,1,0,0 */ -1, -/* 12: 0,0,1,1,0,0 */ 14, -/* 13: 1,0,1,1,0,0 */ -1, -/* 14: 0,1,1,1,0,0 */ -1, -/* 15: 1,1,1,1,0,0 */ -1, -/* 16: 0,0,0,0,1,0 */ 5, -/* 17: 1,0,0,0,1,0 */ 9, -/* 18: 0,1,0,0,1,0 */ 12, -/* 19: 1,1,0,0,1,0 */ 23, -/* 20: 0,0,1,0,1,0 */ 15, -/* 21: 1,0,1,0,1,0 */ -1, -/* 22: 0,1,1,0,1,0 */ 21, -/* 23: 1,1,1,0,1,0 */ 38, -/* 24: 0,0,0,1,1,0 */ 17, -/* 25: 1,0,0,1,1,0 */ 20, -/* 26: 0,1,0,1,1,0 */ -1, -/* 27: 1,1,0,1,1,0 */ 36, -/* 28: 0,0,1,1,1,0 */ 26, -/* 29: 1,0,1,1,1,0 */ 33, -/* 30: 0,1,1,1,1,0 */ 30, -/* 31: 1,1,1,1,1,0 */ 44, -/* 32: 0,0,0,0,0,1 */ 6, -/* 33: 1,0,0,0,0,1 */ 10, -/* 34: 0,1,0,0,0,1 */ 13, -/* 35: 1,1,0,0,0,1 */ 19, -/* 36: 0,0,1,0,0,1 */ 16, -/* 37: 1,0,1,0,0,1 */ -1, -/* 38: 0,1,1,0,0,1 */ 25, -/* 39: 1,1,1,0,0,1 */ 37, -/* 40: 0,0,0,1,0,1 */ 18, -/* 41: 1,0,0,1,0,1 */ 24, -/* 42: 0,1,0,1,0,1 */ -1, -/* 43: 1,1,0,1,0,1 */ 35, -/* 44: 0,0,1,1,0,1 */ 22, -/* 45: 1,0,1,1,0,1 */ 32, -/* 46: 0,1,1,1,0,1 */ 29, -/* 47: 1,1,1,1,0,1 */ 43, -/* 48: 0,0,0,0,1,1 */ -1, -/* 49: 1,0,0,0,1,1 */ -1, -/* 50: 0,1,0,0,1,1 */ -1, -/* 51: 1,1,0,0,1,1 */ 34, -/* 52: 0,0,1,0,1,1 */ -1, -/* 53: 1,0,1,0,1,1 */ -1, -/* 54: 0,1,1,0,1,1 */ 28, -/* 55: 1,1,1,0,1,1 */ 42, -/* 56: 0,0,0,1,1,1 */ -1, -/* 57: 1,0,0,1,1,1 */ 31, -/* 58: 0,1,0,1,1,1 */ -1, -/* 59: 1,1,0,1,1,1 */ 41, -/* 60: 0,0,1,1,1,1 */ 27, -/* 61: 1,0,1,1,1,1 */ 40, -/* 62: 0,1,1,1,1,1 */ 39, -/* 63: 1,1,1,1,1,1 */ 45, -}; - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.1 */ -static const char tiling13_1[2][12] = { -/* 165: 0, 2, 5, 7, */ { 11, 7, 6, 1, 2, 10, 8, 3, 0, 9, 5, 4 }, -/* 90: 1, 3, 4, 6, */ { 8, 4, 7, 2, 3, 11, 9, 0, 1, 10, 6, 5 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.1 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.1 */ -static const char tiling13_1_[2][12] = { -/* 165: 0, 2, 5, 7, */ { 7, 4, 8, 11, 3, 2, 1, 0, 9, 5, 6, 10 }, -/* 90: 1, 3, 4, 6, */ { 6, 7, 11, 10, 2, 1, 0, 3, 8, 4, 5, 9 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.2 */ -static const char tiling13_2[2][6][18] = { -/* 165: 0, 2, 5, 7, */ { - /* 1 */ { 1, 2, 10, 11, 7, 6, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 }, - /* 2 */ { 8, 3, 0, 11, 7, 6, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 }, - /* 3 */ { 9, 5, 4, 8, 3, 0, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 }, - /* 4 */ { 9, 5, 4, 1, 2, 10, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 }, - /* 5 */ { 9, 5, 4, 11, 7, 6, 0, 10, 1, 10, 0, 8, 10, 8, 2, 3, 2, 8 }, - /* 6 */ { 1, 2, 10, 3, 0, 8, 4, 9, 7, 11, 7, 9, 5, 11, 9, 11, 5, 6 } -}, -/* 90: 1, 3, 4, 6, */ { - /* 1 */ { 2, 3, 11, 8, 4, 7, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 }, - /* 2 */ { 9, 0, 1, 8, 4, 7, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 }, - /* 3 */ { 6, 5, 10, 9, 0, 1, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 }, - /* 4 */ { 6, 5, 10, 2, 3, 11, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 }, - /* 5 */ { 6, 5, 10, 8, 4, 7, 1, 11, 2, 11, 1, 9, 11, 9, 3, 0, 3, 9 }, - /* 6 */ { 2, 3, 11, 0, 1, 9, 5, 10, 4, 8, 4, 10, 6, 8, 10, 8, 6, 7 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.2 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.2 */ -static const char tiling13_2_[2][6][18] = { -/* 165: 0, 2, 5, 7, */ { - /* 1 */ { 10, 5, 6, 11, 3, 2, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 }, - /* 2 */ { 11, 3, 2, 7, 4, 8, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 }, - /* 3 */ { 1, 0, 9, 7, 4, 8, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 }, - /* 4 */ { 10, 5, 6, 1, 0, 9, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 }, - /* 5 */ { 10, 5, 6, 7, 4, 8, 2, 11, 1, 9, 1, 11, 3, 9, 11, 9, 3, 0 }, - /* 6 */ { 11, 3, 2, 9, 1, 0, 4, 10, 5, 10, 4, 8, 10, 8, 6, 7, 6, 8 } -}, -/* 90: 1, 3, 4, 6, */ { - /* 1 */ { 6, 7, 11, 8, 0, 3, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 }, - /* 2 */ { 8, 0, 3, 4, 5, 9, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 }, - /* 3 */ { 2, 1, 10, 4, 5, 9, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 }, - /* 4 */ { 6, 7, 11, 2, 1, 10, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 }, - /* 5 */ { 6, 7, 11, 4, 5, 9, 3, 8, 2, 10, 2, 8, 0, 10, 8, 10, 0, 1 }, - /* 6 */ { 8, 0, 3, 10, 2, 1, 5, 11, 6, 11, 5, 9, 11, 9, 7, 4, 7, 9 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.3 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.3 */ -static const char tiling13_3[2][12][30] = { -/* 165: 0, 2, 5, 7, */ { - /* 1,2 */ { 11, 7, 6, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 }, - /* 1,4 */ { 1, 2, 10, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12 }, - /* 1,5 */ { 11, 7, 6, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 }, - /* 1,6 */ { 1, 2, 10, 12, 3, 0, 12, 0, 9, 12, 9, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 }, - /* 2,3 */ { 8, 3, 0, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12 }, - /* 2,5 */ { 11, 7, 6, 5, 4, 12, 10, 5, 12, 2, 10, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 }, - /* 2,6 */ { 8, 3, 0, 1, 2, 12, 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 6, 11, 12, 5, 6, 12, 10, 5, 12, 2, 10, 12 }, - /* 3,4 */ { 9, 5, 4, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 }, - /* 3,5 */ { 9, 5, 4, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 }, - /* 3,6 */ { 8, 3, 0, 12, 1, 2, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 }, - /* 4,5 */ { 9, 5, 4, 7, 6, 12, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 }, - /* 4,6 */ { 1, 2, 10, 3, 0, 12, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12, 8, 7, 12, 0, 8, 12 } -}, -/* 90: 1, 3, 4, 6, */ { - /* 1,2 */ { 8, 4, 7, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 }, - /* 1,4 */ { 2, 3, 11, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12 }, - /* 1,5 */ { 8, 4, 7, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 10, 12, 10, 6 }, - /* 1,6 */ { 2, 3, 11, 12, 0, 1, 12, 1, 10, 12, 10, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 }, - /* 2,3 */ { 0, 1, 9, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12 }, - /* 2,5 */ { 8, 4, 7, 6, 5, 12, 11, 6, 12, 3, 11, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12 }, - /* 2,6 */ { 9, 0, 1, 2, 3, 12, 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 7, 8, 12, 6, 7, 12, 11, 6, 12, 3, 11, 12 }, - /* 3,4 */ { 6, 5, 10, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 }, - /* 3,5 */ { 6, 5, 10, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 8, 12, 8, 4 }, - /* 3,6 */ { 9, 0, 1, 12, 2, 3, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 }, - /* 4,5 */ { 6, 5, 10, 4, 7, 12, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 8, 0, 12, 7, 8, 12 }, - /* 4,6 */ { 2, 3, 11, 0, 1, 12, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12, 9, 4, 12, 1, 9, 12 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.3, inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.3 */ -static const char tiling13_3_[2][12][30] = { -/* 165: 0, 2, 5, 7, */ { - /* 1,2 */ { 3, 2, 11, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 6, 10, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12 }, - /* 1,4 */ { 5, 6, 10, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2 }, - /* 1,5 */ { 10, 5, 6, 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 8, 12, 8, 7 }, - /* 1,6 */ { 11, 3, 2, 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 5, 12, 5, 4, 12, 4, 9, 12, 9, 1 }, - /* 2,3 */ { 7, 4, 8, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 }, - /* 2,5 */ { 7, 4, 8, 5, 6, 12, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 10, 1, 12, 6, 10, 12 }, - /* 2,6 */ { 11, 3, 2, 1, 0, 12, 10, 1, 12, 6, 10, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 }, - /* 3,4 */ { 1, 0, 9, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4 }, - /* 3,5 */ { 7, 4, 8, 12, 5, 6, 12, 6, 11, 12, 11, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5 }, - /* 3,6 */ { 1, 0, 9, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 7, 12, 7, 6, 12, 6, 11, 12, 11, 3 }, - /* 4,5 */ { 10, 5, 6, 7, 4, 12, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 8, 3, 12, 4, 8, 12 }, - /* 4,6 */ { 9, 1, 0, 3, 2, 12, 8, 3, 12, 4, 8, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 } -}, -/* 90: 1, 3, 4, 6, */ { - /* 1,2 */ { 0, 3, 8, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 7, 11, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12 }, - /* 1,4 */ { 11, 6, 7, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3 }, - /* 1,5 */ { 6, 7, 11, 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 }, - /* 1,6 */ { 8, 0, 3, 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 6, 12, 6, 5, 12, 5, 10, 12, 10, 2 }, - /* 2,3 */ { 4, 5, 9, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 }, - /* 2,5 */ { 4, 5, 9, 6, 7, 12, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 }, - /* 2,6 */ { 8, 0, 3, 2, 1, 12, 11, 2, 12, 7, 11, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 }, - /* 3,4 */ { 2, 1, 10, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5 }, - /* 3,5 */ { 4, 5, 9, 12, 6, 7, 12, 7, 8, 12, 8, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 }, - /* 3,6 */ { 2, 1, 10, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 4, 12, 4, 7, 12, 7, 8, 12, 8, 0 }, - /* 4,5 */ { 6, 7, 11, 4, 5, 12, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 }, - /* 4,6 */ { 10, 2, 1, 0, 3, 12, 9, 0, 12, 5, 9, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.4 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.4 */ -static const char tiling13_4[2][4][36] = { -/* 165: 0, 2, 5, 7, */ { -/* 1,2,6 */ { 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 }, -/* 1,4,5 */ { 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 }, -/* 2,3,5 */ { 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12 }, -/* 3,4,6 */ { 12, 0, 8, 12, 8, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 } -}, -/* 90: 1, 3, 4, 6, */ { -/* 1,2,6 */ { 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 }, -/* 1,4,5 */ { 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 }, -/* 2,3,5 */ { 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12 }, -/* 3,4,6 */ { 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.5.1 - * The support edge for the interior test is marked as the 1st column. - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.5.1 */ -static const char tiling13_5_1[2][4][18] = { -/* 165: 0, 2, 5, 7, */ { -/* 1,2,5 */ { 7, 6, 11, 1, 0, 9, 10, 3, 2, 3, 10, 5, 3, 5, 8, 4, 8, 5 }, -/* 1,4,6 */ { 1, 2, 10, 7, 4, 8, 3, 0, 11, 6, 11, 0, 9, 6, 0, 6, 9, 5 }, -/* 2,3,6 */ { 3, 0, 8, 5, 6, 10, 1, 2, 9, 4, 9, 2, 11, 4, 2, 4, 11, 7 }, -/* 3,4,5 */ { 5, 4, 9, 3, 2, 11, 8, 1, 0, 1, 8, 7, 1, 7, 10, 6, 10, 7 } -}, -/* 90: 1, 3, 4, 6, */ { -/* 1,2,5 */ { 4, 7, 8, 2, 1, 10, 11, 0, 3, 0, 11, 6, 0, 6, 9, 5, 9, 6 }, -/* 1,4,6 */ { 2, 3, 11, 4, 5, 9, 0, 1, 8, 7, 8, 1, 10, 7, 1, 7, 10, 6 }, -/* 2,3,6 */ { 0, 1, 9, 6, 7, 11, 2, 3, 10, 5, 10, 3, 8, 5, 3, 5, 8, 4 }, -/* 3,4,5 */ { 6, 5, 10, 0, 3, 8, 9, 2, 1, 2, 9, 4, 2, 4, 11, 7, 11, 4 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.5.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.5.2 */ -static const char tiling13_5_2[2][4][30] = { -/* 165: 0, 2, 5, 7, */ { -/* 1,2,5 */ { 1, 0, 9, 7, 4, 8, 7, 8, 3, 7, 3, 11, 2, 11, 3, 11, 2, 10, 11, 10, 6, 5, 6, 10, 6, 5, 7, 4, 7, 5 }, -/* 1,4,6 */ { 7, 4, 8, 11, 3, 2, 6, 11, 2, 10, 6, 2, 6, 10, 5, 9, 5, 10, 1, 9, 10, 9, 1, 0, 2, 0, 1, 0, 2, 3 }, -/* 2,3,6 */ { 5, 6, 10, 9, 1, 0, 4, 9, 0, 8, 4, 0, 4, 8, 7, 11, 7, 8, 3, 11, 8, 11, 3, 2, 0, 2, 3, 2, 0, 1 }, -/* 3,4,5 */ { 3, 2, 11, 5, 6, 10, 5, 10, 1, 5, 1, 9, 0, 9, 1, 9, 0, 8, 9, 8, 4, 4, 8, 7, 4, 7, 5, 6, 5, 7 } -}, -/* 90: 1, 3, 4, 6, */ { -/* 1,2,5 */ { 2, 1, 10, 4, 5, 9, 4, 9, 0, 4, 0, 8, 3, 8, 0, 8, 3, 11, 8, 11, 7, 6, 7, 11, 7, 6, 4, 5, 4, 6 }, -/* 1,4,6 */ { 4, 5, 9, 8, 0, 3, 7, 8, 3, 11, 7, 3, 7, 11, 6, 10, 6, 11, 2, 10, 11, 10, 2, 1, 3, 1, 2, 1, 3, 0 }, -/* 2,3,6 */ { 6, 7, 11, 10, 2, 1, 5, 10, 1, 9, 5, 1, 5, 9, 4, 8, 4, 9, 0, 8, 9, 8, 0, 3, 1, 3, 0, 3, 1, 2 }, -/* 3,4,5 */ { 0, 3, 8, 6, 7, 11, 6, 11, 2, 6, 2, 10, 1, 10, 2, 10, 1, 9, 10, 9, 5, 5, 9, 4, 5, 4, 6, 7, 6, 4 } -} }; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 14 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling14[12][12] = { -/* 71: 0, 1, 2, 6, */ { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8 }, -/* 43: 0, 1, 3, 5, */ { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5 }, -/* 147: 0, 1, 4, 7, */ { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6 }, -/* 29: 0, 2, 3, 4, */ { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4 }, -/* 201: 0, 3, 6, 7, */ { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5 }, -/* 113: 0, 4, 5, 6, */ { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10 }, -/* 142: 1, 2, 3, 7, */ { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7 }, -/* 54: 1, 2, 4, 5, */ { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2 }, -/* 226: 1, 5, 6, 7, */ { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11 }, -/* 108: 2, 3, 5, 6, */ { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3 }, -/* 212: 2, 4, 6, 7, */ { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8 }, -/* 184: 3, 4, 5, 7, */ { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2 } -}; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief original Marching Cubes implementation - * For each of the possible vertex states listed in this table there is a - * specific triangulation of the edge intersection points. The table lists - * all of them in the form of 0-5 edge triples with the list terminated by - * the invalid value -1. For example: casesClassic[3] list the 2 triangles - * formed when cube[0] and cube[1] are inside of the surface, but the rest of - * the cube is not. - */ -//----------------------------------------------------------------------------- -static const char casesClassic[256][16] = { -/* 0: */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 1: 0, */ { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 2: 1, */ { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 3: 0, 1, */ { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 4: 2, */ { 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 5: 0, 2, */ { 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 6: 1, 2, */ { 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 7: 0, 1, 2, */ { 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 8: 3, */ { 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 9: 0, 3, */ { 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 10: 1, 3, */ { 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 11: 0, 1, 3, */ { 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 12: 2, 3, */ { 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 13: 0, 2, 3, */ { 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 14: 1, 2, 3, */ { 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 15: 0, 1, 2, 3, */ { 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 16: 4, */ { 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 17: 0, 4, */ { 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 18: 1, 4, */ { 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 19: 0, 1, 4, */ { 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 20: 2, 4, */ { 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 21: 0, 2, 4, */ { 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 22: 1, 2, 4, */ { 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 23: 0, 1, 2, 4, */ { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, -/* 24: 3, 4, */ { 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 25: 0, 3, 4, */ { 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 26: 1, 3, 4, */ { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 27: 0, 1, 3, 4, */ { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 }, -/* 28: 2, 3, 4, */ { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 29: 0, 2, 3, 4, */ { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 }, -/* 30: 1, 2, 3, 4, */ { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, -/* 31: 0, 1, 2, 3, 4, */ { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 32: 5, */ { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 33: 0, 5, */ { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 34: 1, 5, */ { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 35: 0, 1, 5, */ { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 36: 2, 5, */ { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 37: 0, 2, 5, */ { 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 38: 1, 2, 5, */ { 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 39: 0, 1, 2, 5, */ { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 }, -/* 40: 3, 5, */ { 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 41: 0, 3, 5, */ { 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 42: 1, 3, 5, */ { 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 43: 0, 1, 3, 5, */ { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 }, -/* 44: 2, 3, 5, */ { 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 45: 0, 2, 3, 5, */ { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 }, -/* 46: 1, 2, 3, 5, */ { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, -/* 47: 0, 1, 2, 3, 5, */ { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 48: 4, 5, */ { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 49: 0, 4, 5, */ { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 50: 1, 4, 5, */ { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 51: 0, 1, 4, 5, */ { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 52: 2, 4, 5, */ { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 53: 0, 2, 4, 5, */ { 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 }, -/* 54: 1, 2, 4, 5, */ { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 }, -/* 55: 0, 1, 2, 4, 5, */ { 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 56: 3, 4, 5, */ { 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 57: 0, 3, 4, 5, */ { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, -/* 58: 1, 3, 4, 5, */ { 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 }, -/* 59: 0, 1, 3, 4, 5, */ { 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 60: 2, 3, 4, 5, */ { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 }, -/* 61: 0, 2, 3, 4, 5, */ { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 }, -/* 62: 1, 2, 3, 4, 5, */ { 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 }, -/* 63: 0, 1, 2, 3, 4, 5, */ { 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 64: 6, */ { 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 65: 0, 6, */ { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 66: 1, 6, */ { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 67: 0, 1, 6, */ { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 68: 2, 6, */ { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 69: 0, 2, 6, */ { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 70: 1, 2, 6, */ { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 71: 0, 1, 2, 6, */ { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 }, -/* 72: 3, 6, */ { 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 73: 0, 3, 6, */ { 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 74: 1, 3, 6, */ { 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 75: 0, 1, 3, 6, */ { 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 }, -/* 76: 2, 3, 6, */ { 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 77: 0, 2, 3, 6, */ { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, -/* 78: 1, 2, 3, 6, */ { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 }, -/* 79: 0, 1, 2, 3, 6, */ { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 80: 4, 6, */ { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 81: 0, 4, 6, */ { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 82: 1, 4, 6, */ { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 83: 0, 1, 4, 6, */ { 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, -/* 84: 2, 4, 6, */ { 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 85: 0, 2, 4, 6, */ { 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 }, -/* 86: 1, 2, 4, 6, */ { 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 }, -/* 87: 0, 1, 2, 4, 6, */ { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 }, -/* 88: 3, 4, 6, */ { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 89: 0, 3, 4, 6, */ { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, -/* 90: 1, 3, 4, 6, */ { 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 }, -/* 91: 0, 1, 3, 4, 6, */ { 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 }, -/* 92: 2, 3, 4, 6, */ { 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, -/* 93: 0, 2, 3, 4, 6, */ { 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 }, -/* 94: 1, 2, 3, 4, 6, */ { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 }, -/* 95: 0, 1, 2, 3, 4, 6, */ { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 }, -/* 96: 5, 6, */ { 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 97: 0, 5, 6, */ { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 98: 1, 5, 6, */ { 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 99: 0, 1, 5, 6, */ { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, -/* 100: 2, 5, 6, */ { 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 101: 0, 2, 5, 6, */ { 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 }, -/* 102: 1, 2, 5, 6, */ { 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 103: 0, 1, 2, 5, 6, */ { 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 104: 3, 5, 6, */ { 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 105: 0, 3, 5, 6, */ { 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 }, -/* 106: 1, 3, 5, 6, */ { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, -/* 107: 0, 1, 3, 5, 6, */ { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 }, -/* 108: 2, 3, 5, 6, */ { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 }, -/* 109: 0, 2, 3, 5, 6, */ { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 }, -/* 110: 1, 2, 3, 5, 6, */ { 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 111: 0, 1, 2, 3, 5, 6, */ { 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 112: 4, 5, 6, */ { 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 113: 0, 4, 5, 6, */ { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 }, -/* 114: 1, 4, 5, 6, */ { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 }, -/* 115: 0, 1, 4, 5, 6, */ { 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 116: 2, 4, 5, 6, */ { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, -/* 117: 0, 2, 4, 5, 6, */ { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 }, -/* 118: 1, 2, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 119: 0, 1, 2, 4, 5, 6, */ { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 120: 3, 4, 5, 6, */ { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, -/* 121: 0, 3, 4, 5, 6, */ { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 }, -/* 122: 1, 3, 4, 5, 6, */ { 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 }, -/* 123: 0, 1, 3, 4, 5, 6, */ { 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 }, -/* 124: 2, 3, 4, 5, 6, */ { 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 }, -/* 125: 0, 2, 3, 4, 5, 6, */ { 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 126: 1, 2, 3, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 }, -/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 128: 7, */ { 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 129: 0, 7, */ { 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 130: 1, 7, */ { 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 131: 0, 1, 7, */ { 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 132: 2, 7, */ { 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 133: 0, 2, 7, */ { 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 134: 1, 2, 7, */ { 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 135: 0, 1, 2, 7, */ { 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 }, -/* 136: 3, 7, */ { 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 137: 0, 3, 7, */ { 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 138: 1, 3, 7, */ { 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 139: 0, 1, 3, 7, */ { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 }, -/* 140: 2, 3, 7, */ { 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 141: 0, 2, 3, 7, */ { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 }, -/* 142: 1, 2, 3, 7, */ { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 }, -/* 143: 0, 1, 2, 3, 7, */ { 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 144: 4, 7, */ { 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 145: 0, 4, 7, */ { 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 146: 1, 4, 7, */ { 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 147: 0, 1, 4, 7, */ { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 }, -/* 148: 2, 4, 7, */ { 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 149: 0, 2, 4, 7, */ { 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 }, -/* 150: 1, 2, 4, 7, */ { 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 }, -/* 151: 0, 1, 2, 4, 7, */ { 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 }, -/* 152: 3, 4, 7, */ { 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 153: 0, 3, 4, 7, */ { 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 154: 1, 3, 4, 7, */ { 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 }, -/* 155: 0, 1, 3, 4, 7, */ { 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 156: 2, 3, 4, 7, */ { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 }, -/* 157: 0, 2, 3, 4, 7, */ { 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 158: 1, 2, 3, 4, 7, */ { 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 }, -/* 159: 0, 1, 2, 3, 4, 7, */ { 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 160: 5, 7, */ { 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 161: 0, 5, 7, */ { 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 162: 1, 5, 7, */ { 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 163: 0, 1, 5, 7, */ { 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 }, -/* 164: 2, 5, 7, */ { 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 165: 0, 2, 5, 7, */ { 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 }, -/* 166: 1, 2, 5, 7, */ { 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 }, -/* 167: 0, 1, 2, 5, 7, */ { 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 }, -/* 168: 3, 5, 7, */ { 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 169: 0, 3, 5, 7, */ { 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 }, -/* 170: 1, 3, 5, 7, */ { 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 }, -/* 171: 0, 1, 3, 5, 7, */ { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 }, -/* 172: 2, 3, 5, 7, */ { 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 }, -/* 173: 0, 2, 3, 5, 7, */ { 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 }, -/* 174: 1, 2, 3, 5, 7, */ { 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 }, -/* 175: 0, 1, 2, 3, 5, 7, */ { 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 }, -/* 176: 4, 5, 7, */ { 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 177: 0, 4, 5, 7, */ { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 }, -/* 178: 1, 4, 5, 7, */ { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 }, -/* 179: 0, 1, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 180: 2, 4, 5, 7, */ { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 }, -/* 181: 0, 2, 4, 5, 7, */ { 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 }, -/* 182: 1, 2, 4, 5, 7, */ { 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 }, -/* 183: 0, 1, 2, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 }, -/* 184: 3, 4, 5, 7, */ { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 }, -/* 185: 0, 3, 4, 5, 7, */ { 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 186: 1, 3, 4, 5, 7, */ { 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 }, -/* 187: 0, 1, 3, 4, 5, 7, */ { 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 188: 2, 3, 4, 5, 7, */ { 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 }, -/* 189: 0, 2, 3, 4, 5, 7, */ { 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 }, -/* 190: 1, 2, 3, 4, 5, 7, */ { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 192: 6, 7, */ { 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 193: 0, 6, 7, */ { 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 194: 1, 6, 7, */ { 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 195: 0, 1, 6, 7, */ { 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 }, -/* 196: 2, 6, 7, */ { 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 197: 0, 2, 6, 7, */ { 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 }, -/* 198: 1, 2, 6, 7, */ { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 }, -/* 199: 0, 1, 2, 6, 7, */ { 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 }, -/* 200: 3, 6, 7, */ { 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 201: 0, 3, 6, 7, */ { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 }, -/* 202: 1, 3, 6, 7, */ { 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 }, -/* 203: 0, 1, 3, 6, 7, */ { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 }, -/* 204: 2, 3, 6, 7, */ { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 205: 0, 2, 3, 6, 7, */ { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 206: 1, 2, 3, 6, 7, */ { 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 207: 0, 1, 2, 3, 6, 7, */ { 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 208: 4, 6, 7, */ { 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 209: 0, 4, 6, 7, */ { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 }, -/* 210: 1, 4, 6, 7, */ { 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 }, -/* 211: 0, 1, 4, 6, 7, */ { 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 }, -/* 212: 2, 4, 6, 7, */ { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 }, -/* 213: 0, 2, 4, 6, 7, */ { 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 }, -/* 214: 1, 2, 4, 6, 7, */ { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 }, -/* 215: 0, 1, 2, 4, 6, 7, */ { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 216: 3, 4, 6, 7, */ { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 }, -/* 217: 0, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 218: 1, 3, 4, 6, 7, */ { 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 }, -/* 219: 0, 1, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 }, -/* 220: 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 221: 0, 2, 3, 4, 6, 7, */ { 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 222: 1, 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 }, -/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 224: 5, 6, 7, */ { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 225: 0, 5, 6, 7, */ { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 }, -/* 226: 1, 5, 6, 7, */ { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 }, -/* 227: 0, 1, 5, 6, 7, */ { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 }, -/* 228: 2, 5, 6, 7, */ { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 }, -/* 229: 0, 2, 5, 6, 7, */ { 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 }, -/* 230: 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 231: 0, 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 }, -/* 232: 3, 5, 6, 7, */ { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 }, -/* 233: 0, 3, 5, 6, 7, */ { 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 }, -/* 234: 1, 3, 5, 6, 7, */ { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 }, -/* 235: 0, 1, 3, 5, 6, 7, */ { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 236: 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 237: 0, 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 }, -/* 238: 1, 2, 3, 5, 6, 7, */ { 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 240: 4, 5, 6, 7, */ { 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 241: 0, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 242: 1, 4, 5, 6, 7, */ { 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 243: 0, 1, 4, 5, 6, 7, */ { 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 244: 2, 4, 5, 6, 7, */ { 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 }, -/* 246: 1, 2, 4, 5, 6, 7, */ { 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 248: 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 249: 0, 3, 4, 5, 6, 7, */ { 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 250: 1, 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 }, -/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 252: 2, 3, 4, 5, 6, 7, */ { 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 255: 0, 1, 2, 3, 4, 5, 6, 7, */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } -}; -//_____________________________________________________________________________ - -} //namespace McCubes - -#endif // _LOOKUPTABLE_H_ diff --git a/3rdParty/MarchingCubes/McPly.cpp b/3rdParty/MarchingCubes/McPly.cpp deleted file mode 100644 index e56d01d7db4fda45646ff3ca7ad2138d322fece2..0000000000000000000000000000000000000000 --- a/3rdParty/MarchingCubes/McPly.cpp +++ /dev/null @@ -1,3320 +0,0 @@ -/* - -The interface routines for reading and writing PLY polygon files. - -Greg Turk - ---------------------------------------------------------------- - -A PLY file contains a single polygonal _object_. - -An object is composed of lists of _elements_. Typical elements are -vertices, faces, edges and materials. - -Each type of element for a given object has one or more _properties_ -associated with the element type. For instance, a vertex element may -have as properties the floating-point values x,y,z and the three unsigned -chars representing red, green and blue. - ------------------------------------------------------------------------ - -Copyright (c) 1998 Georgia Institute of Technology. All rights reserved. - -Permission to use, copy, modify and distribute this software and its -documentation for any purpose is hereby granted without fee, provided -that the above copyright notice and this permission notice appear in -all copies of this software and that you do not sell the software. - -THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND, -EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -*/ - -#include "./McPly.h" -#include <iostream> -#include <cstdio> - -namespace McCubes{ - -const char *type_names[] = { /* names of scalar types */ -"invalid", -"int8", "int16", "int32", "uint8", "uint16", "uint32", "float32", "float64" -}; - -const char *old_type_names[] = { /* old names of types for backward compatability */ -"invalid", -"char", "short", "int", "uchar", "ushort", "uint", "float", "double" -}; - -int ply_type_size[] = { -0, 1, 2, 4, 1, 2, 4, 4, 8 -}; - -#define NO_OTHER_PROPS -1 - -#define DONT_STORE_PROP 0 -#define STORE_PROP 1 - -#define OTHER_PROP 0 -#define NAMED_PROP 1 - -/* returns 1 if strings are equal, 0 if not */ -int equal_strings( const char * , const char * ); - -/* find an element in a plyfile's list */ -PlyElement *find_element( PlyFile * , const char * ); - -/* find a property in an element's list */ -PlyProperty *find_property( PlyElement * , const char * , int * ); - -/* write to a file the word describing a PLY file data type */ -void write_scalar_type( FILE * , int ); - -/* read a line from a file and break it up into separate words */ -char* *get_words( FILE * , int * , char ** ); - -/* write an item to a file */ -void write_binary_item( FILE * , int, unsigned int, double, int ); -void write_ascii_item( FILE * , int, unsigned int, double, int ); - -/* add information to a PLY file descriptor */ -void add_element( PlyFile * , char ** , int ); -void add_property( PlyFile * , char ** , int ); -void add_comment( PlyFile * , const char * ); -void add_obj_info( PlyFile * , const char * ); - -/* copy a property */ -void copy_property( PlyProperty * , PlyProperty * ); - -/* store a value into where a pointer and a type specify */ -void store_item( char * , int, int, unsigned int, double ); - -/* return the value of a stored item */ -void get_stored_item( void * , int, int * , unsigned int * , double * ); - -/* return the value stored in an item, given ptr to it and its type */ -double get_item_value( const char * , int ); - -/* get binary or ascii item and store it according to ptr and type */ -void get_ascii_item( const char * , int, int * , unsigned int * , double * ); -void get_binary_item( FILE * , int, int * , unsigned int * , double * ); - -/* get a bunch of elements from a file */ -void ascii_get_element( PlyFile * , char * ); -void binary_get_element( PlyFile * , char * ); - -/* memory allocation */ -static char *my_alloc( int, int, const char * ); - - -/*************/ -/* Writing */ -/*************/ - - -/****************************************************************************** -Given a file pointer, get ready to write PLY data to the file. - -Entry: -fp - the given file pointer -nelems - number of elements in object -elem_names - list of element names -file_type - file type, either ascii or binary - -Exit: -returns a pointer to a PlyFile, used to refer to this file, or NULL if error -******************************************************************************/ - -PlyFile *ply_write( FILE *fp, int nelems, char **elem_names, int file_type ) -{ - int i; - PlyFile *plyfile; - PlyElement *elem; - - /* check for NULL file pointer */ - if ( fp == NULL ) - return ( NULL ); - - /* create a record for this object */ - - plyfile = ( PlyFile * ) myalloc ( sizeof ( PlyFile ) ); - plyfile->file_type = file_type; - plyfile->num_comments = 0; - plyfile->num_obj_info = 0; - plyfile->num_elem_types = nelems; - plyfile->version = 1.0; - plyfile->fp = fp; - plyfile->other_elems = NULL; - - /* tuck aside the names of the elements */ - - plyfile->elems = ( PlyElement * * ) myalloc ( sizeof ( PlyElement * ) * nelems ); - for ( i = 0; i < nelems; i++ ) - { - elem = ( PlyElement * ) myalloc ( sizeof ( PlyElement ) ); - plyfile->elems[i] = elem; - elem->name = strdup ( elem_names[i] ); - elem->num = 0; - elem->nprops = 0; - } - - /* return pointer to the file descriptor */ - return ( plyfile ); -} - - -/****************************************************************************** -Open a polygon file for writing. - -Entry: -filename - name of file to read from -nelems - number of elements in object -elem_names - list of element names -file_type - file type, either ascii or binary - -Exit: -returns a file identifier, used to refer to this file, or NULL if error -******************************************************************************/ - -PlyFile *open_for_writing_ply( const char *filename, int nelems, char **elem_names, int file_type ) -{ - PlyFile *plyfile; - char *name; - FILE *fp; - - /* tack on the extension .ply, if necessary */ - - name = ( char * ) myalloc ( sizeof ( char ) * ( (int)strlen ( filename ) + 5 ) ); - strcpy ( name, filename ); - if ( strlen ( name ) < 4 || strcmp ( name + strlen ( name ) - 4, ".ply" ) != 0 ) - strcat ( name, ".ply" ); - - /* open the file for writing */ - - fp = fopen ( name, "w" ); - if ( fp == NULL ) - { - return ( NULL ); - } - - /* create the actual PlyFile structure */ - - plyfile = ply_write ( fp, nelems, elem_names, file_type ); - if ( plyfile == NULL ) - return ( NULL ); - - /* return pointer to the file descriptor */ - return ( plyfile ); -} - - -/****************************************************************************** -Describe an element, including its properties and how many will be written -to the file. - -Entry: -plyfile - file identifier -elem_name - name of element that information is being specified about -nelems - number of elements of this type to be written -nprops - number of properties contained in the element -prop_list - list of properties -******************************************************************************/ - -void element_layout_ply( PlyFile *plyfile, const char *elem_name, int nelems, int nprops, PlyProperty *prop_list ) -{ - int i; - PlyElement *elem; - PlyProperty *prop; - - /* look for appropriate element */ - elem = find_element ( plyfile, elem_name ); - if ( elem == NULL ) - { - fprintf( stderr,"element_layout_ply: can't find element '%s'\n",elem_name ); - exit ( -1 ); - } - - elem->num = nelems; - - /* copy the list of properties */ - - elem->nprops = nprops; - elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) * nprops ); - elem->store_prop = ( char * ) myalloc ( sizeof ( char ) * nprops ); - - for ( i = 0; i < nprops; i++ ) - { - prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); - elem->props[i] = prop; - elem->store_prop[i] = NAMED_PROP; - copy_property ( prop, &prop_list[i] ); - } -} - - -/****************************************************************************** -Describe a property of an element. - -Entry: -plyfile - file identifier -elem_name - name of element that information is being specified about -prop - the new property -******************************************************************************/ - -void ply_describe_property( PlyFile *plyfile, const char *elem_name, PlyProperty *prop ) -{ - PlyElement *elem; - PlyProperty *elem_prop; - - /* look for appropriate element */ - elem = find_element ( plyfile, elem_name ); - if ( elem == NULL ) - { - fprintf( stderr, "ply_describe_property: can't find element '%s'\n", - elem_name ); - return; - } - - /* create room for new property */ - - if ( elem->nprops == 0 ) - { - elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) ); - elem->store_prop = ( char * ) myalloc ( sizeof ( char ) ); - elem->nprops = 1; - } - else - { - elem->nprops++; - elem->props = ( PlyProperty * * ) - realloc ( elem->props, sizeof ( PlyProperty * ) * elem->nprops ); - elem->store_prop = ( char * ) - realloc ( elem->store_prop, sizeof ( char ) * elem->nprops ); - } - - /* copy the new property */ - - elem_prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); - elem->props[elem->nprops - 1] = elem_prop; - elem->store_prop[elem->nprops - 1] = NAMED_PROP; - copy_property ( elem_prop, prop ); -} - - -/****************************************************************************** -State how many of a given element will be written. - -Entry: -plyfile - file identifier -elem_name - name of element that information is being specified about -nelems - number of elements of this type to be written -******************************************************************************/ - -void element_count_ply( PlyFile *plyfile, const char *elem_name, int nelems ) -{ - PlyElement *elem; - - /* look for appropriate element */ - elem = find_element ( plyfile, elem_name ); - if ( elem == NULL ) - { - fprintf( stderr,"element_count_ply: can't find element '%s'\n",elem_name ); - exit ( -1 ); - } - - elem->num = nelems; -} - - -/****************************************************************************** -Signal that we've described everything a PLY file's header and that the -header should be written to the file. - -Entry: -plyfile - file identifier -******************************************************************************/ - -void header_complete_ply( PlyFile *plyfile ) -{ - int i,j; - FILE *fp = plyfile->fp; - PlyElement *elem; - PlyProperty *prop; - - fprintf ( fp, "ply\n" ); - - switch ( plyfile->file_type ) - { - case PLY_ASCII: - fprintf ( fp, "format ascii 1.0\n" ); - break; - case PLY_BINARY_BE: - fprintf ( fp, "format binary_big_endian 1.0\n" ); - break; - case PLY_BINARY_LE: - fprintf ( fp, "format binary_little_endian 1.0\n" ); - break; - default: - fprintf ( stderr, "ply_header_complete: bad file type = %d\n", - plyfile->file_type ); - exit ( -1 ); - } - - /* write out the comments */ - - for ( i = 0; i < plyfile->num_comments; i++ ) - fprintf ( fp, "comment %s\n", plyfile->comments[i] ); - - /* write out object information */ - - for ( i = 0; i < plyfile->num_obj_info; i++ ) - fprintf ( fp, "obj_info %s\n", plyfile->obj_info[i] ); - - /* write out information about each element */ - - for ( i = 0; i < plyfile->num_elem_types; i++ ) - { - elem = plyfile->elems[i]; - fprintf ( fp, "element %s %d\n", elem->name, elem->num ); - - /* write out each property */ - for ( j = 0; j < elem->nprops; j++ ) - { - prop = elem->props[j]; - if ( prop->is_list == PLY_LIST ) - { - fprintf ( fp, "property list " ); - write_scalar_type ( fp, prop->count_external ); - fprintf ( fp, " " ); - write_scalar_type ( fp, prop->external_type ); - fprintf ( fp, " %s\n", prop->name ); - } - else if ( prop->is_list == PLY_STRING ) - { - fprintf ( fp, "property string" ); - fprintf ( fp, " %s\n", prop->name ); - } - else - { - fprintf ( fp, "property " ); - write_scalar_type ( fp, prop->external_type ); - fprintf ( fp, " %s\n", prop->name ); - } - } - } - - fprintf ( fp, "end_header\n" ); -} - - -/****************************************************************************** -Specify which elements are going to be written. This should be called -before a call to the routine ply_put_element(). - -Entry: -plyfile - file identifier -elem_name - name of element we're talking about -******************************************************************************/ - -void put_element_setup_ply( PlyFile *plyfile, const char *elem_name ) -{ - PlyElement *elem; - - elem = find_element ( plyfile, elem_name ); - if ( elem == NULL ) - { - fprintf( stderr, "put_element_setup_ply: can't find element '%s'\n", elem_name ); - exit ( -1 ); - } - - plyfile->which_elem = elem; -} - - -/****************************************************************************** -Write an element to the file. This routine assumes that we're -writing the type of element specified in the last call to the routine -put_element_setup_ply(). - -Entry: -plyfile - file identifier -elem_ptr - pointer to the element -******************************************************************************/ - -void put_element_ply( PlyFile *plyfile, void *elem_ptr ) -{ - int j,k; - FILE *fp = plyfile->fp; - PlyElement *elem; - PlyProperty *prop; - char *item; - char *elem_data; - char* *item_ptr; - int list_count; - int item_size; - int int_val; - unsigned int uint_val; - double double_val; - char* *other_ptr; - - elem = plyfile->which_elem; - elem_data = ( char * ) elem_ptr; - other_ptr = ( char * * ) ( ( ( char * ) elem_ptr ) + elem->other_offset ); - - /* write out either to an ascii or binary file */ - - if ( plyfile->file_type == PLY_ASCII ) - { - /* write an ascii file */ - - /* write out each property of the element */ - for ( j = 0; j < elem->nprops; j++ ) - { - prop = elem->props[j]; - - if ( elem->store_prop[j] == OTHER_PROP ) - elem_data = *other_ptr; - else - elem_data = ( char * ) elem_ptr; - - if ( prop->is_list == PLY_LIST ) - { - /* list */ - item = elem_data + prop->count_offset; - get_stored_item ( ( void * ) item, prop->count_internal, - &int_val, &uint_val, &double_val ); - write_ascii_item ( fp, int_val, uint_val, double_val, - prop->count_external ); - list_count = uint_val; - item_ptr = ( char * * ) ( elem_data + prop->offset ); - item = item_ptr[0]; - item_size = ply_type_size[prop->internal_type]; - for ( k = 0; k < list_count; k++ ) - { - get_stored_item ( ( void * ) item, prop->internal_type, - &int_val, &uint_val, &double_val ); - write_ascii_item ( fp, int_val, uint_val, double_val, - prop->external_type ); - item += item_size; - } - } - else if ( prop->is_list == PLY_STRING ) - { - /* string */ - char* *str; - item = elem_data + prop->offset; - str = ( char * * ) item; - fprintf ( fp, "\"%s\"", *str ); - } - else - { - /* scalar */ - item = elem_data + prop->offset; - get_stored_item ( ( void * ) item, prop->internal_type, - &int_val, &uint_val, &double_val ); - write_ascii_item ( fp, int_val, uint_val, double_val, - prop->external_type ); - } - } - - fprintf ( fp, "\n" ); - } - else - { - /* write a binary file */ - - /* write out each property of the element */ - for ( j = 0; j < elem->nprops; j++ ) - { - prop = elem->props[j]; - if ( elem->store_prop[j] == OTHER_PROP ) - elem_data = *other_ptr; - else - elem_data = ( char * ) elem_ptr; - if ( prop->is_list == PLY_LIST ) - { - /* list */ - item = elem_data + prop->count_offset; - item_size = ply_type_size[prop->count_internal]; - get_stored_item ( ( void * ) item, prop->count_internal, - &int_val, &uint_val, &double_val ); - write_binary_item ( fp, int_val, uint_val, double_val, - prop->count_external ); - list_count = uint_val; - item_ptr = ( char * * ) ( elem_data + prop->offset ); - item = item_ptr[0]; - item_size = ply_type_size[prop->internal_type]; - for ( k = 0; k < list_count; k++ ) - { - get_stored_item ( ( void * ) item, prop->internal_type, - &int_val, &uint_val, &double_val ); - write_binary_item ( fp, int_val, uint_val, double_val, - prop->external_type ); - item += item_size; - } - } - else if ( prop->is_list == PLY_STRING ) - { - /* string */ - int len; - char* *str; - item = elem_data + prop->offset; - str = ( char * * ) item; - - /* write the length */ - len = (int)strlen( *str ) + 1; - fwrite ( &len, sizeof( int ), 1, fp ); - - /* write the string, including the null character */ - fwrite ( *str, len, 1, fp ); - } - else - { - /* scalar */ - item = elem_data + prop->offset; - item_size = ply_type_size[prop->internal_type]; - get_stored_item ( ( void * ) item, prop->internal_type, - &int_val, &uint_val, &double_val ); - write_binary_item ( fp, int_val, uint_val, double_val, - prop->external_type ); - } - } - } -} - - - - - - -/*************/ -/* Reading */ -/*************/ - - - -/****************************************************************************** -Given a file pointer, get ready to read PLY data from the file. - -Entry: -fp - the given file pointer - -Exit: -nelems - number of elements in object -elem_names - list of element names -returns a pointer to a PlyFile, used to refer to this file, or NULL if error -******************************************************************************/ - -PlyFile *ply_read( FILE *fp, int *nelems, char ***elem_names ) -{ - int i,j; - PlyFile *plyfile; - int nwords; - char* *words; - int found_format = 0; - char* *elist; - PlyElement *elem; - char *orig_line; - - /* check for NULL file pointer */ - if ( fp == NULL ) - return ( NULL ); - - /* create record for this object */ - - plyfile = ( PlyFile * ) myalloc ( sizeof ( PlyFile ) ); - plyfile->num_elem_types = 0; - plyfile->comments = NULL; - plyfile->num_comments = 0; - plyfile->obj_info = NULL; - plyfile->num_obj_info = 0; - plyfile->fp = fp; - plyfile->other_elems = NULL; - plyfile->rule_list = NULL; - - /* read and parse the file's header */ - - words = get_words ( plyfile->fp, &nwords, &orig_line ); - if ( !words || !equal_strings ( words[0], "ply" ) ) - return ( NULL ); - - while ( words ) - { - /* parse words */ - - if ( equal_strings ( words[0], "format" ) ) - { - if ( nwords != 3 ) - return ( NULL ); - if ( equal_strings ( words[1], "ascii" ) ) - plyfile->file_type = PLY_ASCII; - else if ( equal_strings ( words[1], "binary_big_endian" ) ) - plyfile->file_type = PLY_BINARY_BE; - else if ( equal_strings ( words[1], "binary_little_endian" ) ) - plyfile->file_type = PLY_BINARY_LE; - else - return ( NULL ); - plyfile->version = ( float ) atof ( words[2] ); - found_format = 1; - } - else if ( equal_strings ( words[0], "element" ) ) - add_element ( plyfile, words, nwords ); - else if ( equal_strings ( words[0], "property" ) ) - add_property ( plyfile, words, nwords ); - else if ( equal_strings ( words[0], "comment" ) ) - add_comment ( plyfile, orig_line ); - else if ( equal_strings ( words[0], "obj_info" ) ) - add_obj_info ( plyfile, orig_line ); - else if ( equal_strings ( words[0], "end_header" ) ) - break; - - /* free up words space */ - free ( words ); - - words = get_words ( plyfile->fp, &nwords, &orig_line ); - } - - /* create tags for each property of each element, to be used */ - /* later to say whether or not to store each property for the user */ - - for ( i = 0; i < plyfile->num_elem_types; i++ ) - { - elem = plyfile->elems[i]; - elem->store_prop = ( char * ) myalloc ( sizeof ( char ) * elem->nprops ); - for ( j = 0; j < elem->nprops; j++ ) - elem->store_prop[j] = DONT_STORE_PROP; - elem->other_offset = NO_OTHER_PROPS; /* no "other" props by default */ - } - - /* set return values about the elements */ - - elist = ( char * * ) myalloc ( sizeof ( char * ) * plyfile->num_elem_types ); - for ( i = 0; i < plyfile->num_elem_types; i++ ) - elist[i] = strdup ( plyfile->elems[i]->name ); - - *elem_names = elist; - *nelems = plyfile->num_elem_types; - - /* return a pointer to the file's information */ - - return ( plyfile ); -} - - -/****************************************************************************** -Open a polygon file for reading. - -Entry: -filename - name of file to read from - -Exit: -nelems - number of elements in object -elem_names - list of element names -file_type - file type, either ascii or binary -version - version number of PLY file -returns a file identifier, used to refer to this file, or NULL if error -******************************************************************************/ - -PlyFile *ply_open_for_reading( const char *filename, int *nelems, char ***elem_names, int *file_type, float *version ) -{ - FILE *fp; - PlyFile *plyfile; - char *name; - - /* tack on the extension .ply, if necessary */ - - name = ( char * ) myalloc ( sizeof ( char ) * ( (int)strlen ( filename ) + 5 ) ); - strcpy ( name, filename ); - if ( strlen ( name ) < 4 || strcmp ( name + strlen ( name ) - 4, ".ply" ) != 0 ) - strcat ( name, ".ply" ); - - /* open the file for reading */ - - fp = fopen ( name, "r" ); - if ( fp == NULL ) - return ( NULL ); - - /* create the PlyFile data structure */ - - plyfile = ply_read ( fp, nelems, elem_names ); - - /* determine the file type and version */ - - *file_type = plyfile->file_type; - *version = plyfile->version; - - /* return a pointer to the file's information */ - - return ( plyfile ); -} - - -/****************************************************************************** -Get information about a particular element. - -Entry: -plyfile - file identifier -elem_name - name of element to get information about - -Exit: -nelems - number of elements of this type in the file -nprops - number of properties -returns a list of properties, or NULL if the file doesn't contain that elem -******************************************************************************/ - -PlyProperty **get_element_description_ply( PlyFile *plyfile, const char *elem_name, int *nelems, int *nprops ) -{ - int i; - PlyElement *elem; - PlyProperty *prop; - PlyProperty* *prop_list; - - /* find information about the element */ - elem = find_element ( plyfile, elem_name ); - if ( elem == NULL ) - return ( NULL ); - - *nelems = elem->num; - *nprops = elem->nprops; - - /* make a copy of the element's property list */ - prop_list = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) * elem->nprops ); - for ( i = 0; i < elem->nprops; i++ ) - { - prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); - copy_property ( prop, elem->props[i] ); - prop_list[i] = prop; - } - - /* return this duplicate property list */ - return ( prop_list ); -} - - -/****************************************************************************** -Specify which properties of an element are to be returned. This should be -called before a call to the routine get_element_ply(). - -Entry: -plyfile - file identifier -elem_name - which element we're talking about -nprops - number of properties -prop_list - list of properties -******************************************************************************/ - -void get_element_setup_ply( PlyFile *plyfile, const char *elem_name, int nprops, PlyProperty *prop_list ) -{ - int i; - PlyElement *elem; - PlyProperty *prop; - int index; - - /* find information about the element */ - elem = find_element ( plyfile, elem_name ); - plyfile->which_elem = elem; - - /* deposit the property information into the element's description */ - for ( i = 0; i < nprops; i++ ) - { - /* look for actual property */ - prop = find_property ( elem, prop_list[i].name, &index ); - if ( prop == NULL ) - { - fprintf ( stderr, "Warning: Can't find property '%s' in element '%s'\n", - prop_list[i].name, elem_name ); - continue; - } - - /* store its description */ - prop->internal_type = prop_list[i].internal_type; - prop->offset = prop_list[i].offset; - prop->count_internal = prop_list[i].count_internal; - prop->count_offset = prop_list[i].count_offset; - - /* specify that the user wants this property */ - elem->store_prop[index] = STORE_PROP; - } -} - - -/****************************************************************************** -Specify a property of an element that is to be returned. This should be -called (usually multiple times) before a call to the routine ply_get_element(). -This routine should be used in preference to the less flexible old routine -called ply_get_element_setup(). - -Entry: -plyfile - file identifier -elem_name - which element we're talking about -prop - property to add to those that will be returned -******************************************************************************/ - -void ply_get_property( PlyFile *plyfile, const char *elem_name, PlyProperty *prop ) -{ - PlyElement *elem; - PlyProperty *prop_ptr; - int index; - - /* find information about the element */ - elem = find_element ( plyfile, elem_name ); - plyfile->which_elem = elem; - - /* deposit the property information into the element's description */ - - prop_ptr = find_property ( elem, prop->name, &index ); - if ( prop_ptr == NULL ) - { - fprintf ( stderr, "Warning: Can't find property '%s' in element '%s'\n", - prop->name, elem_name ); - return; - } - prop_ptr->internal_type = prop->internal_type; - prop_ptr->offset = prop->offset; - prop_ptr->count_internal = prop->count_internal; - prop_ptr->count_offset = prop->count_offset; - - /* specify that the user wants this property */ - elem->store_prop[index] = STORE_PROP; -} - - -/****************************************************************************** -Read one element from the file. This routine assumes that we're reading -the type of element specified in the last call to the routine -ply_get_element_setup(). - -Entry: -plyfile - file identifier -elem_ptr - pointer to location where the element information should be put -******************************************************************************/ - -void ply_get_element( PlyFile *plyfile, void *elem_ptr ) -{ - if ( plyfile->file_type == PLY_ASCII ) - ascii_get_element ( plyfile, ( char * ) elem_ptr ); - else - binary_get_element ( plyfile, ( char * ) elem_ptr ); -} - - -/****************************************************************************** -Extract the comments from the header information of a PLY file. - -Entry: -plyfile - file identifier - -Exit: -num_comments - number of comments returned -returns a pointer to a list of comments -******************************************************************************/ - -char **get_comments_ply( PlyFile *plyfile, int *num_comments ) -{ - *num_comments = plyfile->num_comments; - return ( plyfile->comments ); -} - - -/****************************************************************************** -Extract the object information (arbitrary text) from the header information -of a PLY file. - -Entry: -plyfile - file identifier - -Exit: -num_obj_info - number of lines of text information returned -returns a pointer to a list of object info lines -******************************************************************************/ - -char **get_obj_info_ply( PlyFile *plyfile, int *num_obj_info ) -{ - *num_obj_info = plyfile->num_obj_info; - return ( plyfile->obj_info ); -} - - -/****************************************************************************** -ake ready for "other" properties of an element-- those properties that -the user has not explicitly asked for, but that are to be stashed away -in a special structure to be carried along with the element's other -information. - -Entry: -plyfile - file identifier -elem - element for which we want to save away other properties -******************************************************************************/ - -void setup_other_props( PlyFile *plyfile, PlyElement *elem ) -{ - int i; - PlyProperty *prop; - int size = 0; - int type_size; - - /* Examine each property in decreasing order of size. */ - /* We do this so that all data types will be aligned by */ - /* word, half-word, or whatever within the structure. */ - - for ( type_size = 8; type_size > 0; type_size /= 2 ) - { - /* add up the space taken by each property, and save this information */ - /* away in the property descriptor */ - - for ( i = 0; i < elem->nprops; i++ ) - { - /* don't bother with properties we've been asked to store explicitly */ - if ( elem->store_prop[i] ) - continue; - - prop = elem->props[i]; - - /* internal types will be same as external */ - prop->internal_type = prop->external_type; - prop->count_internal = prop->count_external; - - /* list case */ - if ( prop->is_list == PLY_LIST ) - { - /* pointer to list */ - if ( type_size == sizeof ( void * ) ) - { - prop->offset = size; - size += sizeof ( void * ); /* always use size of a pointer here */ - } - - /* count of number of list elements */ - if ( type_size == ply_type_size[prop->count_external] ) - { - prop->count_offset = size; - size += ply_type_size[prop->count_external]; - } - } - /* string */ - else if ( prop->is_list == PLY_STRING ) - { - /* pointer to string */ - if ( type_size == sizeof ( char * ) ) - { - prop->offset = size; - size += sizeof ( char * ); - } - } - /* scalar */ - else if ( type_size == ply_type_size[prop->external_type] ) - { - prop->offset = size; - size += ply_type_size[prop->external_type]; - } - } - } - - /* save the size for the other_props structure */ - elem->other_size = size; -} - - -/****************************************************************************** -Specify that we want the "other" properties of an element to be tucked -away within the user's structure. - -Entry: -plyfile - file identifier -elem - the element that we want to store other_props in -offset - offset to where other_props will be stored inside user's structure - -Exit: -returns pointer to structure containing description of other_props -******************************************************************************/ - -static PlyOtherProp *get_other_properties( PlyFile *plyfile, PlyElement *elem, int offset ) -{ - int i; - PlyOtherProp *other; - PlyProperty *prop; - int nprops; - - /* remember that this is the "current" element */ - plyfile->which_elem = elem; - - /* save the offset to where to store the other_props */ - elem->other_offset = offset; - - /* place the appropriate pointers, etc. in the element's property list */ - setup_other_props ( plyfile, elem ); - - /* create structure for describing other_props */ - other = ( PlyOtherProp * ) myalloc ( sizeof ( PlyOtherProp ) ); - other->name = strdup ( elem->name ); -#if 0 -if (elem->other_offset == NO_OTHER_PROPS) { -other->size = 0; -other->props = NULL; -other->nprops = 0; -return (other); -} -#endif - other->size = elem->other_size; - other->props = ( PlyProperty * * ) myalloc ( sizeof( PlyProperty ) * elem->nprops ); - - /* save descriptions of each "other" property */ - nprops = 0; - for ( i = 0; i < elem->nprops; i++ ) - { - if ( elem->store_prop[i] ) - continue; - prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); - copy_property ( prop, elem->props[i] ); - other->props[nprops] = prop; - nprops++; - } - other->nprops = nprops; - - /* set other_offset pointer appropriately if there are NO other properties */ - if ( other->nprops == 0 ) - { - elem->other_offset = NO_OTHER_PROPS; - } - - /* return structure */ - return ( other ); -} - - -/****************************************************************************** -Specify that we want the "other" properties of an element to be tucked -away within the user's structure. The user needn't be concerned for how -these properties are stored. - -Entry: -plyfile - file identifier -elem_name - name of element that we want to store other_props in -offset - offset to where other_props will be stored inside user's structure - -Exit: -returns pointer to structure containing description of other_props -******************************************************************************/ - -PlyOtherProp *ply_get_other_properties( PlyFile *plyfile, const char *elem_name, int offset ) -{ - PlyElement *elem; - PlyOtherProp *other; - - /* find information about the element */ - elem = find_element ( plyfile, elem_name ); - if ( elem == NULL ) - { - fprintf ( stderr, "ply_get_other_properties: Can't find element '%s'\n", - elem_name ); - return ( NULL ); - } - - other = get_other_properties ( plyfile, elem, offset ); - return ( other ); -} - - - - -/*************************/ -/* Other Element Stuff */ -/*************************/ - - - - - -/****************************************************************************** -Grab all the data for the current element that a user does not want to -explicitly read in. Stores this in the PLY object's data structure. - -Entry: -plyfile - pointer to file - -Exit: -returns pointer to ALL the "other" element data for this PLY file -******************************************************************************/ - -PlyOtherElems *get_other_element_ply( PlyFile *plyfile ) -{ - int i; - PlyElement *elem; - char *elem_name; - int elem_count; - PlyOtherElems *other_elems; - OtherElem *other; - - elem = plyfile->which_elem; - elem_name = elem->name; - elem_count = elem->num; - - /* create room for the new "other" element, initializing the */ - /* other data structure if necessary */ - - if ( plyfile->other_elems == NULL ) - { - plyfile->other_elems = ( PlyOtherElems * ) myalloc ( sizeof ( PlyOtherElems ) ); - other_elems = plyfile->other_elems; - other_elems->other_list = ( OtherElem * ) myalloc ( sizeof ( OtherElem ) ); - other = &( other_elems->other_list[0] ); - other_elems->num_elems = 1; - } - else - { - other_elems = plyfile->other_elems; - other_elems->other_list = ( OtherElem * ) realloc ( other_elems->other_list, - sizeof ( OtherElem ) * other_elems->num_elems + 1 ); - other = &( other_elems->other_list[other_elems->num_elems] ); - other_elems->num_elems++; - } - - /* count of element instances in file */ - other->elem_count = elem_count; - - /* save name of element */ - other->elem_name = strdup ( elem_name ); - - /* create a list to hold all the current elements */ - other->other_data = ( OtherData * * ) - malloc ( sizeof ( OtherData * ) * other->elem_count ); - - /* set up for getting elements */ - other->other_props = ply_get_other_properties ( plyfile, elem_name, - offsetof( OtherData,other_props ) ); - - /* grab all these elements */ - for ( i = 0; i < other->elem_count; i++ ) - { - /* grab and element from the file */ - other->other_data[i] = ( OtherData * ) malloc ( sizeof ( OtherData ) ); - ply_get_element ( plyfile, ( void * ) other->other_data[i] ); - } - - /* return pointer to the other elements data */ - return ( other_elems ); -} - - -/****************************************************************************** -Write out the "other" elements specified for this PLY file. - -Entry: -plyfile - pointer to PLY file to write out other elements for -******************************************************************************/ - -void put_other_elements_ply( PlyFile *plyfile ) -{ - int i,j; - OtherElem *other; - - /* make sure we have other elements to write */ - if ( plyfile->other_elems == NULL ) - return; - - /* write out the data for each "other" element */ - - for ( i = 0; i < plyfile->other_elems->num_elems; i++ ) - { - other = &( plyfile->other_elems->other_list[i] ); - put_element_setup_ply ( plyfile, other->elem_name ); - - /* write out each instance of the current element */ - for ( j = 0; j < other->elem_count; j++ ) - put_element_ply ( plyfile, ( void * ) other->other_data[j] ); - } -} - - -/****************************************************************************** -Free up storage used by an "other" elements data structure. - -Entry: -other_elems - data structure to free up -******************************************************************************/ - -void free_other_elements_ply( PlyOtherElems *other_elems ) -{ -} - - - -/*******************/ -/* Miscellaneous */ -/*******************/ - - - -/****************************************************************************** -Close a PLY file. - -Entry: -plyfile - identifier of file to close -******************************************************************************/ - -void ply_close( PlyFile *plyfile ) -{ - fclose ( plyfile->fp ); - - /* free up memory associated with the PLY file */ - free ( plyfile ); -} - - -/****************************************************************************** -Get version number and file type of a PlyFile. - -Entry: -ply - pointer to PLY file - -Exit: -version - version of the file -file_type - PLY_ASCII, PLY_BINARY_BE, or PLY_BINARY_LE -******************************************************************************/ - -void get_info_ply( PlyFile *ply, float *version, int *file_type ) -{ - if ( ply == NULL ) - return; - - *version = ply->version; - *file_type = ply->file_type; -} - - -/****************************************************************************** -Compare two strings. Returns 1 if they are the same, 0 if not. -******************************************************************************/ - -int equal_strings( const char *s1, const char *s2 ) -{ - while ( *s1 && *s2 ) - if ( *s1++ != *s2++ ) - return ( 0 ); - - if ( *s1 != *s2 ) - return ( 0 ); - else - return ( 1 ); -} - - -/****************************************************************************** -Re-create the command line that was used to invoke this program. - -Entry: -argc - number of words in argv -argv - array of words in command line -******************************************************************************/ - -char *recreate_command_line( int argc, char *argv[] ) -{ - int i; - char *line; - int len = 0; - - /* count total number of characters needed, including separating spaces */ - for ( i = 0; i < argc; i++ ) - len += (int)strlen( argv[i] ) + 1; - - /* create empty line */ - line = ( char * ) malloc ( sizeof( char ) * len ); - line[0] = '\0'; - - /* repeatedly append argv */ - for ( i = 0; i < argc; i++ ) - { - strcat ( line, argv[i] ); - if ( i != argc - 1 ) - strcat ( line, " " ); - } - - return ( line ); -} - - -/****************************************************************************** -Find an element from the element list of a given PLY object. - -Entry: -plyfile - file id for PLY file -element - name of element we're looking for - -Exit: -returns the element, or NULL if not found -******************************************************************************/ - -PlyElement *find_element( PlyFile *plyfile, const char *element ) -{ - int i; - - for ( i = 0; i < plyfile->num_elem_types; i++ ) - if ( equal_strings ( element, plyfile->elems[i]->name ) ) - return ( plyfile->elems[i] ); - - return ( NULL ); -} - - -/****************************************************************************** -Find a property in the list of properties of a given element. - -Entry: -elem - pointer to element in which we want to find the property -prop_name - name of property to find - -Exit: -index - index to position in list -returns a pointer to the property, or NULL if not found -******************************************************************************/ - -PlyProperty *find_property( PlyElement *elem, const char *prop_name, int *index ) -{ - int i; - - for ( i = 0; i < elem->nprops; i++ ) - if ( equal_strings ( prop_name, elem->props[i]->name ) ) - { - *index = i; - return ( elem->props[i] ); - } - - *index = -1; - return ( NULL ); -} - - -/****************************************************************************** -Read an element from an ascii file. - -Entry: -plyfile - file identifier -elem_ptr - pointer to element -******************************************************************************/ - -void ascii_get_element( PlyFile *plyfile, char *elem_ptr ) -{ - int j,k; - PlyElement *elem=NULL; - PlyProperty *prop=NULL; - char* *words=NULL; - int nwords; - int which_word; - char *elem_data=NULL,*item=NULL; - char *item_ptr=NULL; - int item_size; - int int_val; - unsigned int uint_val; - double double_val; - int list_count; - int store_it; - char* *store_array=NULL; - char *orig_line=NULL; - char *other_data=NULL; - int other_flag; - - /* the kind of element we're reading currently */ - elem = plyfile->which_elem; - - /* do we need to setup for other_props? */ - - if ( elem->other_offset != NO_OTHER_PROPS ) - { - char* *ptr; - other_flag = 1; - /* make room for other_props */ - other_data = ( char * ) myalloc ( elem->other_size ); - /* store pointer in user's structure to the other_props */ - ptr = ( char * * ) ( elem_ptr + elem->other_offset ); - *ptr = other_data; - } - else - other_flag = 0; - - /* read in the element */ - - words = get_words ( plyfile->fp, &nwords, &orig_line ); - if ( words == NULL ) - { - fprintf ( stderr, "ply_get_element: unexpected end of file\n" ); - exit ( -1 ); - } - - which_word = 0; - - for ( j = 0; j < elem->nprops; j++ ) - { - prop = elem->props[j]; - store_it = ( elem->store_prop[j] | other_flag ); - - /* store either in the user's structure or in other_props */ - if ( elem->store_prop[j] ) - elem_data = elem_ptr; - else - elem_data = other_data; - - if ( prop->is_list == PLY_LIST ) - { - /* a list */ - - /* get and store the number of items in the list */ - get_ascii_item ( words[which_word++], prop->count_external, - &int_val, &uint_val, &double_val ); - if ( store_it ) - { - item = elem_data + prop->count_offset; - store_item( item, prop->count_internal, int_val, uint_val, double_val ); - } - - /* allocate space for an array of items and store a ptr to the array */ - list_count = int_val; - item_size = ply_type_size[prop->internal_type]; - store_array = ( char * * ) ( elem_data + prop->offset ); - - if ( list_count == 0 ) - { - if ( store_it ) - *store_array = NULL; - } - else - { - if ( store_it ) - { - item_ptr = ( char * ) myalloc ( sizeof ( char ) * item_size * list_count ); - item = item_ptr; - *store_array = item_ptr; - } - - /* read items and store them into the array */ - for ( k = 0; k < list_count; k++ ) - { - get_ascii_item ( words[which_word++], prop->external_type, - &int_val, &uint_val, &double_val ); - if ( store_it ) - { - store_item ( item, prop->internal_type, - int_val, uint_val, double_val ); - item += item_size; - } - } - } - } - else if ( prop->is_list == PLY_STRING ) - { - /* a string */ - if ( store_it ) - { - char *str; - char* *str_ptr; - str = strdup ( words[which_word++] ); - item = elem_data + prop->offset; - str_ptr = ( char * * ) item; - *str_ptr = str; - } - else - { - which_word++; - } - } - else - { - /* a scalar */ - get_ascii_item ( words[which_word++], prop->external_type, - &int_val, &uint_val, &double_val ); - if ( store_it ) - { - item = elem_data + prop->offset; - store_item ( item, prop->internal_type, int_val, uint_val, double_val ); - } - } - } - - free ( words ); -} - - -/****************************************************************************** -Read an element from a binary file. - -Entry: -plyfile - file identifier -elem_ptr - pointer to an element -******************************************************************************/ - -void binary_get_element( PlyFile *plyfile, char *elem_ptr ) -{ - int j,k; - PlyElement *elem= NULL; - PlyProperty *prop= NULL; - FILE *fp = plyfile->fp; - char *elem_data; - char *item = NULL; - char *item_ptr= NULL; - int item_size; - int int_val; - unsigned int uint_val; - double double_val; - int list_count; - int store_it; - char* *store_array= NULL; - char *other_data= NULL; - int other_flag; - - /* the kind of element we're reading currently */ - elem = plyfile->which_elem; - - /* do we need to setup for other_props? */ - - if ( elem->other_offset != NO_OTHER_PROPS ) - { - char* *ptr; - other_flag = 1; - /* make room for other_props */ - other_data = ( char * ) myalloc ( elem->other_size ); - /* store pointer in user's structure to the other_props */ - ptr = ( char * * ) ( elem_ptr + elem->other_offset ); - *ptr = other_data; - } - else - other_flag = 0; - - /* read in a number of elements */ - - for ( j = 0; j < elem->nprops; j++ ) - { - prop = elem->props[j]; - store_it = ( elem->store_prop[j] | other_flag ); - - /* store either in the user's structure or in other_props */ - if ( elem->store_prop[j] ) - elem_data = elem_ptr; - else - elem_data = other_data; - - if ( prop->is_list == PLY_LIST ) - { - /* list */ - - /* get and store the number of items in the list */ - get_binary_item ( fp, prop->count_external, - &int_val, &uint_val, &double_val ); - if ( store_it ) - { - item = elem_data + prop->count_offset; - store_item( item, prop->count_internal, int_val, uint_val, double_val ); - } - - /* allocate space for an array of items and store a ptr to the array */ - list_count = int_val; - item_size = ply_type_size[prop->internal_type]; - store_array = ( char * * ) ( elem_data + prop->offset ); - if ( list_count == 0 ) - { - if ( store_it ) - *store_array = NULL; - } - else - { - if ( store_it ) - { - item_ptr = ( char * ) myalloc ( sizeof ( char ) * item_size * list_count ); - item = item_ptr; - *store_array = item_ptr; - } - - /* read items and store them into the array */ - for ( k = 0; k < list_count; k++ ) - { - get_binary_item ( fp, prop->external_type, - &int_val, &uint_val, &double_val ); - if ( store_it ) - { - store_item ( item, prop->internal_type, - int_val, uint_val, double_val ); - item += item_size; - } - } - } - } - else if ( prop->is_list == PLY_STRING ) - { - /* string */ - int len; - char *str; - fread ( &len, sizeof( int ), 1, fp ); - str = ( char * ) myalloc ( len ); - fread ( str, len, 1, fp ); - if ( store_it ) - { - char* *str_ptr; - item = elem_data + prop->offset; - str_ptr = ( char * * ) item; - *str_ptr = str; - } - } - else - { - /* scalar */ - get_binary_item ( fp, prop->external_type, - &int_val, &uint_val, &double_val ); - if ( store_it ) - { - item = elem_data + prop->offset; - store_item ( item, prop->internal_type, int_val, uint_val, double_val ); - } - } - } -} - - -/****************************************************************************** -Write to a file the word that represents a PLY data type. - -Entry: -fp - file pointer -code - code for type -******************************************************************************/ - -void write_scalar_type( FILE *fp, int code ) -{ - /* make sure this is a valid code */ - - if ( code <= StartType || code >= EndType ) - { - fprintf ( stderr, "write_scalar_type: bad data code = %d\n", code ); - exit ( -1 ); - } - - /* write the code to a file */ - - fprintf ( fp, "%s", type_names[code] ); -} - - -/****************************************************************************** -Get a text line from a file and break it up into words. - -IMPORTANT: The calling routine should call "free" on the returned pointer once -finished with it. - -Entry: -fp - file to read from - -Exit: -nwords - number of words returned -orig_line - the original line of characters -returns a list of words from the line, or NULL if end-of-file -******************************************************************************/ - -char **get_words( FILE *fp, int *nwords, char **orig_line ) -{ -#define BIG_STRING 4096 - static char str[BIG_STRING]; - static char str_copy[BIG_STRING]; - char* *words; - int max_words = 10; - int num_words = 0; - char *ptr,*ptr2; - char *result; - - words = ( char * * ) myalloc ( sizeof ( char * ) * max_words ); - - /* read in a line */ - result = fgets ( str, BIG_STRING, fp ); - if ( result == NULL ) - { - *nwords = 0; - *orig_line = NULL; - return ( NULL ); - } - - /* convert line-feed and tabs into spaces */ - /* (this guarentees that there will be a space before the */ - /* null character at the end of the string) */ - - str[BIG_STRING - 2] = ' '; - str[BIG_STRING - 1] = '\0'; - - for ( ptr = str, ptr2 = str_copy; *ptr != '\0'; ptr++, ptr2++ ) - { - *ptr2 = *ptr; - if ( *ptr == '\t' ) - { - *ptr = ' '; - *ptr2 = ' '; - } - else if ( *ptr == '\n' ) - { - *ptr = ' '; - *ptr2 = ' '; - break; - } - else if ( *ptr == '\r' ) - { - *ptr = ' '; - *ptr2 = '\0'; - } - } - - /* find the words in the line */ - - ptr = str; - while ( *ptr != '\0' ) - { - /* jump over leading spaces */ - while ( *ptr == ' ' ) - ptr++; - - /* break if we reach the end */ - if ( *ptr == '\0' ) - break; - - /* allocate more room for words if necessary */ - if ( num_words >= max_words ) - { - max_words += 10; - words = ( char * * ) realloc ( words, sizeof ( char * ) * max_words ); - } - - if ( *ptr == '\"' ) - { - /* a quote indidicates that we have a string */ - - /* skip over leading quote */ - ptr++; - - /* save pointer to beginning of word */ - words[num_words++] = ptr; - - /* find trailing quote or end of line */ - while ( *ptr != '\"' && *ptr != '\0' ) - ptr++; - - /* replace quote with a null character to mark the end of the word */ - /* if we are not already at the end of the line */ - if ( *ptr != '\0' ) - *ptr++ = '\0'; - } - else - { - /* non-string */ - - /* save pointer to beginning of word */ - words[num_words++] = ptr; - - /* jump over non-spaces */ - while ( *ptr != ' ' ) - ptr++; - - /* place a null character here to mark the end of the word */ - *ptr++ = '\0'; - } - } - - /* return the list of words */ - *nwords = num_words; - *orig_line = str_copy; - return ( words ); -} - - -/****************************************************************************** -Return the value of an item, given a pointer to it and its type. - -Entry: -item - pointer to item -type - data type that "item" points to - -Exit: -returns a double-precision float that contains the value of the item -******************************************************************************/ - -double get_item_value( const char *item, int type ) -{ - unsigned char *puchar; - char *pchar; - short int *pshort; - unsigned short int *pushort; - int *pint; - unsigned int *puint; - float *pfloat; - double *pdouble; - int int_value; - unsigned int uint_value; - double double_value; - - switch ( type ) - { - case Int8: - pchar = ( char * ) item; - int_value = *pchar; - return ( ( double ) int_value ); - case Uint8: - puchar = ( unsigned char * ) item; - int_value = *puchar; - return ( ( double ) int_value ); - case Int16: - pshort = ( short int * ) item; - int_value = *pshort; - return ( ( double ) int_value ); - case Uint16: - pushort = ( unsigned short int * ) item; - int_value = *pushort; - return ( ( double ) int_value ); - case Int32: - pint = ( int * ) item; - int_value = *pint; - return ( ( double ) int_value ); - case Uint32: - puint = ( unsigned int * ) item; - uint_value = *puint; - return ( ( double ) uint_value ); - case Float32: - pfloat = ( float * ) item; - double_value = *pfloat; - return ( double_value ); - case Float64: - pdouble = ( double * ) item; - double_value = *pdouble; - return ( double_value ); - default: - fprintf ( stderr, "get_item_value: bad type = %d\n", type ); - exit ( -1 ); - } - - return ( 0.0 ); /* never actually gets here */ -} - - -/****************************************************************************** -Write out an item to a file as raw binary bytes. - -Entry: -fp - file to write to -int_val - integer version of item -uint_val - unsigned integer version of item -double_val - double-precision float version of item -type - data type to write out -******************************************************************************/ - -void write_binary_item( FILE *fp, int int_val, unsigned int uint_val, double double_val, int type ) -{ - unsigned char uchar_val; - char char_val; - unsigned short ushort_val; - short short_val; - float float_val; - - switch ( type ) - { - case Int8: - char_val = int_val; - fwrite ( &char_val, 1, 1, fp ); - break; - case Int16: - short_val = int_val; - fwrite ( &short_val, 2, 1, fp ); - break; - case Int32: - fwrite ( &int_val, 4, 1, fp ); - break; - case Uint8: - uchar_val = uint_val; - fwrite ( &uchar_val, 1, 1, fp ); - break; - case Uint16: - ushort_val = uint_val; - fwrite ( &ushort_val, 2, 1, fp ); - break; - case Uint32: - fwrite ( &uint_val, 4, 1, fp ); - break; - case Float32: - float_val = ( float ) double_val; - fwrite ( &float_val, 4, 1, fp ); - break; - case Float64: - fwrite ( &double_val, 8, 1, fp ); - break; - default: - fprintf ( stderr, "write_binary_item: bad type = %d\n", type ); - exit ( -1 ); - } -} - - -/****************************************************************************** -Write out an item to a file as ascii characters. - -Entry: -fp - file to write to -int_val - integer version of item -uint_val - unsigned integer version of item -double_val - double-precision float version of item -type - data type to write out -******************************************************************************/ - -void write_ascii_item( FILE *fp, int int_val, unsigned int uint_val, double double_val, int type ) -{ - switch ( type ) - { - case Int8: - case Int16: - case Int32: - fprintf ( fp, "%d ", int_val ); - break; - case Uint8: - case Uint16: - case Uint32: - fprintf ( fp, "%u ", uint_val ); - break; - case Float32: - case Float64: - fprintf ( fp, "%12f ", double_val ); - break; - default: - fprintf ( stderr, "write_ascii_item: bad type = %d\n", type ); - exit ( -1 ); - } -} - - -/****************************************************************************** -Get the value of an item that is in memory, and place the result -into an integer, an unsigned integer and a double. - -Entry: -ptr - pointer to the item -type - data type supposedly in the item - -Exit: -int_val - integer value -uint_val - unsigned integer value -double_val - double-precision floating point value -******************************************************************************/ - -void get_stored_item( void *ptr, int type, int *int_val, unsigned int *uint_val, double *double_val ) -{ - switch ( type ) - { - case Int8: - *int_val = *( ( char * ) ptr ); - *uint_val = *int_val; - *double_val = *int_val; - break; - case Uint8: - *uint_val = *( ( unsigned char * ) ptr ); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case Int16: - *int_val = *( ( short int * ) ptr ); - *uint_val = *int_val; - *double_val = *int_val; - break; - case Uint16: - *uint_val = *( ( unsigned short int * ) ptr ); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case Int32: - *int_val = *( ( int * ) ptr ); - *uint_val = *int_val; - *double_val = *int_val; - break; - case Uint32: - *uint_val = *( ( unsigned int * ) ptr ); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case Float32: - *double_val = *( ( float * ) ptr ); - *int_val = ( int ) *double_val; - *uint_val = ( unsigned int ) *double_val; - break; - case Float64: - *double_val = *( ( double * ) ptr ); - *int_val = ( int ) *double_val; - *uint_val = ( unsigned int ) *double_val; - break; - default: - fprintf ( stderr, "get_stored_item: bad type = %d\n", type ); - exit ( -1 ); - } -} - - -/****************************************************************************** -Get the value of an item from a binary file, and place the result -into an integer, an unsigned integer and a double. - -Entry: -fp - file to get item from -type - data type supposedly in the word - -Exit: -int_val - integer value -uint_val - unsigned integer value -double_val - double-precision floating point value -******************************************************************************/ - -void get_binary_item( FILE *fp, int type, int *int_val, unsigned int *uint_val, double *double_val ) -{ - char c[8]; - void *ptr; - - ptr = ( void * ) c; - - switch ( type ) - { - case Int8: - fread ( ptr, 1, 1, fp ); - *int_val = *( ( char * ) ptr ); - *uint_val = *int_val; - *double_val = *int_val; - break; - case Uint8: - fread ( ptr, 1, 1, fp ); - *uint_val = *( ( unsigned char * ) ptr ); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case Int16: - fread ( ptr, 2, 1, fp ); - *int_val = *( ( short int * ) ptr ); - *uint_val = *int_val; - *double_val = *int_val; - break; - case Uint16: - fread ( ptr, 2, 1, fp ); - *uint_val = *( ( unsigned short int * ) ptr ); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case Int32: - fread ( ptr, 4, 1, fp ); - *int_val = *( ( int * ) ptr ); - *uint_val = *int_val; - *double_val = *int_val; - break; - case Uint32: - fread ( ptr, 4, 1, fp ); - *uint_val = *( ( unsigned int * ) ptr ); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case Float32: - fread ( ptr, 4, 1, fp ); - *double_val = *( ( float * ) ptr ); - *int_val = ( int ) *double_val; - *uint_val = ( unsigned int ) *double_val; - break; - case Float64: - fread ( ptr, 8, 1, fp ); - *double_val = *( ( double * ) ptr ); - *int_val = ( int ) *double_val; - *uint_val = ( unsigned int ) *double_val; - break; - default: - fprintf ( stderr, "get_binary_item: bad type = %d\n", type ); - exit ( -1 ); - } -} - - -/****************************************************************************** -Extract the value of an item from an ascii word, and place the result -into an integer, an unsigned integer and a double. - -Entry: -word - word to extract value from -type - data type supposedly in the word - -Exit: -int_val - integer value -uint_val - unsigned integer value -double_val - double-precision floating point value -******************************************************************************/ - -void get_ascii_item( const char *word, int type, int *int_val, unsigned int *uint_val, double *double_val ) -{ - switch ( type ) - { - case Int8: - case Uint8: - case Int16: - case Uint16: - case Int32: - *int_val = atoi ( word ); - *uint_val = *int_val; - *double_val = *int_val; - break; - - case Uint32: - *uint_val = strtoul ( word, ( char * * ) NULL, 10 ); - *int_val = *uint_val; - *double_val = *uint_val; - break; - - case Float32: - case Float64: - *double_val = atof ( word ); - *int_val = ( int ) *double_val; - *uint_val = ( unsigned int ) *double_val; - break; - - default: - fprintf ( stderr, "get_ascii_item: bad type = %d\n", type ); - exit ( -1 ); - } -} - - -/****************************************************************************** -Store a value into a place being pointed to, guided by a data type. - -Entry: -item - place to store value -type - data type -int_val - integer version of value -uint_val - unsigned integer version of value -double_val - double version of value - -Exit: -item - pointer to stored value -******************************************************************************/ - -void store_item( char *item, int type, int int_val, unsigned int uint_val, double double_val ) -{ - unsigned char *puchar; - short int *pshort; - unsigned short int *pushort; - int *pint; - unsigned int *puint; - float *pfloat; - double *pdouble; - - switch ( type ) - { - case Int8: - *item = int_val; - break; - case Uint8: - puchar = ( unsigned char * ) item; - *puchar = uint_val; - break; - case Int16: - pshort = ( short * ) item; - *pshort = int_val; - break; - case Uint16: - pushort = ( unsigned short * ) item; - *pushort = uint_val; - break; - case Int32: - pint = ( int * ) item; - *pint = int_val; - break; - case Uint32: - puint = ( unsigned int * ) item; - *puint = uint_val; - break; - case Float32: - pfloat = ( float * ) item; - *pfloat = ( float ) double_val; - break; - case Float64: - pdouble = ( double * ) item; - *pdouble = double_val; - break; - default: - fprintf ( stderr, "store_item: bad type = %d\n", type ); - exit ( -1 ); - } -} - - -/****************************************************************************** -Add an element to a PLY file descriptor. - -Entry: -plyfile - PLY file descriptor -words - list of words describing the element -nwords - number of words in the list -******************************************************************************/ - -void add_element( PlyFile *plyfile, char **words, int nwords ) -{ - PlyElement *elem; - - /* create the new element */ - elem = ( PlyElement * ) myalloc ( sizeof ( PlyElement ) ); - elem->name = strdup ( words[1] ); - elem->num = atoi ( words[2] ); - elem->nprops = 0; - - /* make room for new element in the object's list of elements */ - if ( plyfile->num_elem_types == 0 ) - plyfile->elems = ( PlyElement * * ) myalloc ( sizeof ( PlyElement * ) ); - else - plyfile->elems = ( PlyElement * * ) realloc ( plyfile->elems, - sizeof ( PlyElement * ) * ( plyfile->num_elem_types + 1 ) ); - - /* add the new element to the object's list */ - plyfile->elems[plyfile->num_elem_types] = elem; - plyfile->num_elem_types++; -} - - -/****************************************************************************** -Return the type of a property, given the name of the property. - -Entry: -name - name of property type - -Exit: -returns integer code for property, or 0 if not found -******************************************************************************/ - -int get_prop_type( const char *type_name ) -{ - int i; - - /* try to match the type name */ - for ( i = StartType + 1; i < EndType; i++ ) - if ( equal_strings ( type_name, type_names[i] ) ) - return ( i ); - - /* see if we can match an old type name */ - for ( i = StartType + 1; i < EndType; i++ ) - if ( equal_strings ( type_name, old_type_names[i] ) ) - return ( i ); - - /* if we get here, we didn't find the type */ - return ( 0 ); -} - - -/****************************************************************************** -Add a property to a PLY file descriptor. - -Entry: -plyfile - PLY file descriptor -words - list of words describing the property -nwords - number of words in the list -******************************************************************************/ - -void add_property( PlyFile *plyfile, char **words, int nwords ) -{ - PlyProperty *prop; - PlyElement *elem; - - /* create the new property */ - - prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); - - if ( equal_strings ( words[1], "list" ) ) - { - /* list */ - prop->count_external = get_prop_type ( words[2] ); - prop->external_type = get_prop_type ( words[3] ); - prop->name = strdup ( words[4] ); - prop->is_list = PLY_LIST; - } - else if ( equal_strings ( words[1], "string" ) ) - { - /* string */ - prop->count_external = Int8; - prop->external_type = Int8; - prop->name = strdup ( words[2] ); - prop->is_list = PLY_STRING; - } - else - { - /* scalar */ - prop->external_type = get_prop_type ( words[1] ); - prop->name = strdup ( words[2] ); - prop->is_list = PLY_SCALAR; - } - - /* add this property to the list of properties of the current element */ - - elem = plyfile->elems[plyfile->num_elem_types - 1]; - - if ( elem->nprops == 0 ) - elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) ); - else - elem->props = ( PlyProperty * * ) realloc ( elem->props, - sizeof ( PlyProperty * ) * ( elem->nprops + 1 ) ); - - elem->props[elem->nprops] = prop; - elem->nprops++; -} - - -/****************************************************************************** -Add a comment to a PLY file descriptor. - -Entry: -plyfile - PLY file descriptor -line - line containing comment -******************************************************************************/ - -void add_comment( PlyFile *plyfile, const char *line ) -{ - int i; - - /* skip over "comment" and leading spaces and tabs */ - i = 7; - while ( line[i] == ' ' || line[i] == '\t' ) - i++; - - append_comment_ply ( plyfile, &line[i] ); -} - - -/****************************************************************************** -Add a some object information to a PLY file descriptor. - -Entry: -plyfile - PLY file descriptor -line - line containing text info -******************************************************************************/ - -void add_obj_info( PlyFile *plyfile, const char *line ) -{ - int i; - - /* skip over "obj_info" and leading spaces and tabs */ - i = 8; - while ( line[i] == ' ' || line[i] == '\t' ) - i++; - - append_obj_info_ply ( plyfile, &line[i] ); -} - - -/****************************************************************************** -Copy a property. -******************************************************************************/ - -void copy_property( PlyProperty *dest, PlyProperty *src ) -{ - dest->name = strdup ( src->name ); - dest->external_type = src->external_type; - dest->internal_type = src->internal_type; - dest->offset = src->offset; - - dest->is_list = src->is_list; - dest->count_external = src->count_external; - dest->count_internal = src->count_internal; - dest->count_offset = src->count_offset; -} - - -/****************************************************************************** -Allocate some memory. - -Entry: -size - amount of memory requested (in bytes) -lnum - line number from which memory was requested -fname - file name from which memory was requested -******************************************************************************/ - -static char *my_alloc( int size, int lnum, const char *fname ) -{ - char *ptr; - - ptr = ( char * ) malloc ( size ); - - if ( ptr == 0 ) - { - fprintf( stderr, "Memory allocation bombed on line %d in %s\n", lnum, fname ); - } - - return ( ptr ); -} - - -/**** NEW STUFF ****/ -/**** NEW STUFF ****/ -/**** NEW STUFF ****/ -/**** NEW STUFF ****/ - - - -/****************************************************************************** -Given a file pointer, get ready to read PLY data from the file. - -Entry: -fp - the given file pointer - -Exit: -nelems - number of elements in object -elem_names - list of element names -returns a pointer to a PlyFile, used to refer to this file, or NULL if error -******************************************************************************/ - -PlyFile *read_ply( FILE *fp ) -{ - PlyFile *ply; - int num_elems; - char* *elem_names; - - ply = ply_read ( fp, &num_elems, &elem_names ); - - return ( ply ); -} - - -/****************************************************************************** -Given a file pointer, get ready to write PLY data to the file. - -Entry: -fp - the given file pointer -nelems - number of elements in object -elem_names - list of element names -file_type - file type, either ascii or binary - -Exit: -returns a pointer to a PlyFile, used to refer to this file, or NULL if error -******************************************************************************/ - -PlyFile *write_ply( FILE *fp, int nelems, char **elem_names, int file_type ) -{ - PlyFile *ply; - - ply = ply_write ( fp, nelems, elem_names, file_type ); - - return ( ply ); -} - - -/****************************************************************************** -Return a list of the names of the elements in a particular PLY file. - -Entry: -ply - PLY file whose element name list we want - -Exit: -num_elems - the number of element names in the list -returns the list of names -******************************************************************************/ - -char **get_element_list_ply( PlyFile *ply, int *num_elems ) -{ - int i; - char* *elist; - - /* create the list of element names */ - - elist = ( char * * ) myalloc ( sizeof ( char * ) * ply->num_elem_types ); - for ( i = 0; i < ply->num_elem_types; i++ ) - elist[i] = strdup ( ply->elems[i]->name ); - - /* return the number of elements and the list of element names */ - *num_elems = ply->num_elem_types; - return ( elist ); -} - - -/****************************************************************************** -Append a comment to a PLY file. - -Entry: -ply - file to append comment to -comment - the comment to append -******************************************************************************/ - -void append_comment_ply( PlyFile *ply, const char *comment ) -{ - /* (re)allocate space for new comment */ - if ( ply->num_comments == 0 ) - ply->comments = ( char * * ) myalloc ( sizeof ( char * ) ); - else - ply->comments = ( char * * ) realloc ( ply->comments, - sizeof ( char * ) * ( ply->num_comments + 1 ) ); - - /* add comment to list */ - ply->comments[ply->num_comments] = strdup ( comment ); - ply->num_comments++; -} - - -/****************************************************************************** -Copy the comments from one PLY file to another. - -Entry: -out_ply - destination file to copy comments to -in_ply - the source of the comments -******************************************************************************/ - -void copy_comments_ply( PlyFile *out_ply, PlyFile *in_ply ) -{ - int i; - - for ( i = 0; i < in_ply->num_comments; i++ ) - append_comment_ply ( out_ply, in_ply->comments[i] ); -} - - -/****************************************************************************** -Append object information (arbitrary text) to a PLY file. - -Entry: -ply - file to append object info to -obj_info - the object info to append -******************************************************************************/ - -void append_obj_info_ply( PlyFile *ply, const char *obj_info ) -{ - /* (re)allocate space for new info */ - if ( ply->num_obj_info == 0 ) - ply->obj_info = ( char * * ) myalloc ( sizeof ( char * ) ); - else - ply->obj_info = ( char * * ) realloc ( ply->obj_info, - sizeof ( char * ) * ( ply->num_obj_info + 1 ) ); - - /* add info to list */ - ply->obj_info[ply->num_obj_info] = strdup ( obj_info ); - ply->num_obj_info++; -} - - -/****************************************************************************** -Copy the object information from one PLY file to another. - -Entry: -out_ply - destination file to copy object information to -in_ply - the source of the object information -******************************************************************************/ - -void copy_obj_info_ply( PlyFile *out_ply, PlyFile *in_ply ) -{ - int i; - - for ( i = 0; i < in_ply->num_obj_info; i++ ) - append_obj_info_ply ( out_ply, in_ply->obj_info[i] ); -} - - -/****************************************************************************** -Close a PLY file. - -Entry: -plyfile - identifier of file to close -******************************************************************************/ - -void close_ply( PlyFile *plyfile ) -{ - fclose ( plyfile->fp ); -} - - -/****************************************************************************** -Free the memory used by a PLY file. - -Entry: -plyfile - identifier of file -******************************************************************************/ - -void free_ply( PlyFile *plyfile ) -{ - /* free up memory associated with the PLY file */ - free ( plyfile ); -} - - -/****************************************************************************** -Specify the index of the next element to be read in from a PLY file. - -Entry: -ply - file to read from -index - index of the element to be read - -Exit: -elem_count - the number of elements in the file -returns pointer to the name of this next element -******************************************************************************/ - -char *setup_element_read_ply( PlyFile *ply, int index, int *elem_count ) -{ - PlyElement *elem; - - if ( index < 0 || index > ply->num_elem_types ) - { - fprintf ( stderr, "Warning: No element with index %d\n", index ); - return ( 0 ); - } - - elem = ply->elems[index]; - - /* set this to be the current element */ - ply->which_elem = elem; - - /* return the number of such elements in the file and the element's name */ - *elem_count = elem->num; - return ( elem->name ); -} - - -/****************************************************************************** -Read one element from the file. This routine assumes that we're reading -the type of element specified in the last call to the routine -setup_element_read_ply(). - -Entry: -plyfile - file identifier -elem_ptr - pointer to location where the element information should be put -******************************************************************************/ - -void get_element_ply( PlyFile *plyfile, void *elem_ptr ) -{ - if ( plyfile->file_type == PLY_ASCII ) - ascii_get_element ( plyfile, ( char * ) elem_ptr ); - else - binary_get_element ( plyfile, ( char * ) elem_ptr ); -} - - -/****************************************************************************** -Specify one of several properties of the current element that is to be -read from a file. This should be called (usually multiple times) before a -call to the routine get_element_ply(). - -Entry: -plyfile - file identifier -prop - property to add to those that will be returned - -Exit: -0 if the property has not been found -1 if the property has been found -******************************************************************************/ - -int setup_property_ply( PlyFile *plyfile, PlyProperty *prop ) -{ - PlyElement *elem; - PlyProperty *prop_ptr; - int index; - - elem = plyfile->which_elem; - - /* deposit the property information into the element's description */ - - prop_ptr = find_property ( elem, prop->name, &index ); - if ( prop_ptr == NULL ) - { - fprintf ( stderr, "Warning: Can't find property '%s' in element '%s'\n", - prop->name, elem->name ); - return 0; - } - prop_ptr->internal_type = prop->internal_type; - prop_ptr->offset = prop->offset; - prop_ptr->count_internal = prop->count_internal; - prop_ptr->count_offset = prop->count_offset; - - /* specify that the user wants this property */ - elem->store_prop[index] = STORE_PROP; - return 1 ; -} - - -/****************************************************************************** -Specify that we want the "other" properties of the current element to be tucked -away within the user's structure. - -Entry: -plyfile - file identifier -offset - offset to where other_props will be stored inside user's structure - -Exit: -returns pointer to structure containing description of other_props -******************************************************************************/ - -PlyOtherProp *get_other_properties_ply( PlyFile *plyfile, int offset ) -{ - PlyOtherProp *other; - - other = get_other_properties ( plyfile, plyfile->which_elem, offset ); - return ( other ); -} - - -/****************************************************************************** -Describe which element is to be written next and state how many of them will -be written. - -Entry: -plyfile - file identifier -elem_name - name of element that information is being described -nelems - number of elements of this type to be written -******************************************************************************/ - -void describe_element_ply( PlyFile *plyfile, char *elem_name, int nelems ) -{ - PlyElement *elem; - - /* look for appropriate element */ - elem = find_element ( plyfile, elem_name ); - if ( elem == NULL ) - { - fprintf( stderr,"describe_element_ply: can't find element '%s'\n",elem_name ); - exit ( -1 ); - } - - elem->num = nelems; - - /* now this element is the current element */ - plyfile->which_elem = elem; -} - - -/****************************************************************************** -Describe a property of an element. - -Entry: -plyfile - file identifier -prop - the new property -******************************************************************************/ - -void describe_property_ply( PlyFile *plyfile, PlyProperty *prop ) -{ - PlyElement *elem; - PlyProperty *elem_prop; - - elem = plyfile->which_elem; - - /* create room for new property */ - - if ( elem->nprops == 0 ) - { - elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) ); - elem->store_prop = ( char * ) myalloc ( sizeof ( char ) ); - elem->nprops = 1; - } - else - { - elem->nprops++; - elem->props = ( PlyProperty * * ) - realloc ( elem->props, sizeof ( PlyProperty * ) * elem->nprops ); - elem->store_prop = ( char * ) - realloc ( elem->store_prop, sizeof ( char ) * elem->nprops ); - } - - /* copy the new property */ - - elem_prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); - elem->props[elem->nprops - 1] = elem_prop; - elem->store_prop[elem->nprops - 1] = NAMED_PROP; - copy_property ( elem_prop, prop ); -} - - -/****************************************************************************** -Describe what the "other" properties are that are to be stored, and where -they are in an element. -******************************************************************************/ - -void describe_other_properties_ply( PlyFile *plyfile, PlyOtherProp *other, int offset ) -{ - int i; - PlyElement *elem; - PlyProperty *prop; - - /* look for appropriate element */ - elem = find_element ( plyfile, other->name ); - if ( elem == NULL ) - { - fprintf( stderr, "describe_other_properties_ply: can't find element '%s'\n", - other->name ); - return; - } - - /* create room for other properties */ - - if ( elem->nprops == 0 ) - { - elem->props = ( PlyProperty * * ) - myalloc ( sizeof ( PlyProperty * ) * other->nprops ); - elem->store_prop = ( char * ) myalloc ( sizeof ( char ) * other->nprops ); - elem->nprops = 0; - } - else - { - int newsize; - newsize = elem->nprops + other->nprops; - elem->props = ( PlyProperty * * ) - realloc ( elem->props, sizeof ( PlyProperty * ) * newsize ); - elem->store_prop = ( char * ) - realloc ( elem->store_prop, sizeof ( char ) * newsize ); - } - - /* copy the other properties */ - - for ( i = 0; i < other->nprops; i++ ) - { - prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); - copy_property ( prop, other->props[i] ); - elem->props[elem->nprops] = prop; - elem->store_prop[elem->nprops] = OTHER_PROP; - elem->nprops++; - } - - /* save other info about other properties */ - elem->other_size = other->size; - elem->other_offset = offset; -} - - -/****************************************************************************** -Pass along a pointer to "other" elements that we want to save in a given -PLY file. These other elements were presumably read from another PLY file. - -Entry: -plyfile - file pointer in which to store this other element info -other_elems - info about other elements that we want to store -******************************************************************************/ - -void describe_other_elements_ply( PlyFile *plyfile, PlyOtherElems *other_elems ) -{ - int i; - OtherElem *other; - - /* ignore this call if there is no other element */ - if ( other_elems == NULL ) - return; - - /* save pointer to this information */ - plyfile->other_elems = other_elems; - - /* describe the other properties of this element */ - - for ( i = 0; i < other_elems->num_elems; i++ ) - { - other = &( other_elems->other_list[i] ); - element_count_ply ( plyfile, other->elem_name, other->elem_count ); - describe_other_properties_ply ( plyfile, other->other_props, - offsetof( OtherData,other_props ) ); - } -} - - - -/**** Property Propagation Rules ****/ - - -typedef struct RuleName { -int code; -const char *name; -} RuleName; - -const RuleName rule_name_list[] = { -{AVERAGE_RULE, "avg"}, -{RANDOM_RULE, "rnd"}, -{MINIMUM_RULE, "max"}, -{MAXIMUM_RULE, "min"}, -{MAJORITY_RULE, "major"}, -{SAME_RULE, "same"}, -{-1, "end_marker"}, -}; - - - -/****************************************************************************** -Initialize the property propagation rules for an element. Default is to -use averaging (AVERAGE_RULE) for creating all new properties. - -Entry: -ply - PLY object that this is for -elem_name - name of the element that we're making the rules for - -Exit: -returns pointer to the default rules -******************************************************************************/ - -PlyPropRules *init_rule_ply( PlyFile *ply, char *elem_name ) -{ - int i,j; - PlyElement *elem; - PlyPropRules *rules; - PlyRuleList *list; - int found_prop; - - elem = find_element ( ply, elem_name ); - if ( elem == NULL ) - { - fprintf ( stderr, "init_rule_ply: Can't find element '%s'\n", elem_name ); - exit ( -1 ); - } - - rules = ( PlyPropRules * ) myalloc ( sizeof ( PlyPropRules ) ); - rules->elem = elem; - rules->rule_list = ( int * ) myalloc ( sizeof( int ) * elem->nprops ); - rules->max_props = 0; - rules->nprops = 0; - - /* default is to use averaging rule */ - for ( i = 0; i < elem->nprops; i++ ) - rules->rule_list[i] = AVERAGE_RULE; - - /* see if there are other rules we should use */ - - if ( ply->rule_list == NULL ) - return ( rules ); - - /* try to match the element, property and rule name */ - - for ( list = ply->rule_list; list != NULL; list = list->next ) - { - if ( !equal_strings ( list->element, elem->name ) ) - continue; - - found_prop = 0; - - for ( i = 0; i < elem->nprops; i++ ) - if ( equal_strings ( list->property, elem->props[i]->name ) ) - { - found_prop = 1; - - /* look for matching rule name */ - for ( j = 0; rule_name_list[j].code != -1; j++ ) - if ( equal_strings ( list->name, rule_name_list[j].name ) ) - { - rules->rule_list[i] = rule_name_list[j].code; - break; - } - } - - if ( !found_prop ) - { - fprintf ( stderr, "Can't find property '%s' for rule '%s'\n", - list->property, list->name ); - continue; - } - } - - return ( rules ); -} - - -/****************************************************************************** -odify a property propagation rule. - -Entry: -rules - rules for the element -prop_name - name of the property whose rule we're modifying -rule_type - type of rule (MAXIMUM_RULE, MINIMUM_RULE, MAJORITY_RULE, etc.) -******************************************************************************/ - -void modify_rule_ply( PlyPropRules *rules, char *prop_name, int rule_type ) -{ - int i; - PlyElement *elem = rules->elem; - - /* find the property and modify its rule type */ - - for ( i = 0; i < elem->nprops; i++ ) - if ( equal_strings ( elem->props[i]->name, prop_name ) ) - { - rules->rule_list[i] = rule_type; - return; - } - - /* we didn't find the property if we get here */ - fprintf ( stderr, "modify_rule_ply: Can't find property '%s'\n", prop_name ); - exit ( -1 ); -} - - -/****************************************************************************** -Begin to create a set of properties from a set of propagation rules. - -Entry: -ply - PLY object whose rules we're preparing to use -rules - rules for the element -******************************************************************************/ - -void start_props_ply( PlyFile *ply, PlyPropRules *rules ) -{ - /* PlyElement *elem = rules->elem; */ - - /* save pointer to the rules in the PLY object */ - ply->current_rules = rules; - - /* get ready for new sets of properties to combine */ - rules->nprops = 0; -} - - -/****************************************************************************** -Remember a set of properties and their weights for creating a new set of -properties. - -Entry: -weight - weights for this set of properties -other_props - the properties to use -******************************************************************************/ - -void weight_props_ply( PlyFile *ply, float weight, void *other_props ) -{ - PlyPropRules *rules = ply->current_rules; - - /* allocate space for properties and weights, if necessary */ - if ( rules->max_props == 0 ) - { - rules->max_props = 6; - rules->props = ( void * * ) myalloc ( sizeof ( void * ) * rules->max_props ); - rules->weights = ( float * ) myalloc ( sizeof ( float ) * rules->max_props ); - } - if ( rules->nprops == rules->max_props ) - { - rules->max_props *= 2; - rules->props = ( void * * ) realloc ( rules->props, - sizeof ( void * ) * rules->max_props ); - rules->weights = ( float * ) realloc ( rules->weights, - sizeof ( float ) * rules->max_props ); - } - - /* remember these new properties and their weights */ - - rules->props[rules->nprops] = other_props; - rules->weights[rules->nprops] = weight; - rules->nprops++; -} - - -/****************************************************************************** -Return a pointer to a new set of properties that have been created using -a specified set of property combination rules and a given collection of -"other" properties. - -Exit: -returns a pointer to the new properties -******************************************************************************/ - -void *get_new_props_ply( PlyFile *ply ) -{ - int i,j; - static double *vals; - static int max_vals = 0; - PlyPropRules *rules = ply->current_rules; - PlyElement *elem = rules->elem; - PlyProperty *prop; - char *data; - char *new_data; - void *ptr; - int offset; - int type; - double double_val; - int int_val; - unsigned int uint_val; - int random_pick; - - /* return NULL if we've got no "other" properties */ - if ( elem->other_size == 0 ) - { - return ( NULL ); - } - - /* create room for combined other properties */ - new_data = ( char * ) myalloc ( sizeof ( char ) * elem->other_size ); - - /* make sure there is enough room to store values we're to combine */ - - if ( max_vals == 0 ) - { - max_vals = rules->nprops; - vals = ( double * ) myalloc ( sizeof ( double ) * rules->nprops ); - } - if ( rules->nprops >= max_vals ) - { - max_vals = rules->nprops; - vals = ( double * ) realloc ( vals, sizeof ( double ) * rules->nprops ); - } - - /* in case we need a random choice */ - random_pick = ( int ) floor ( (double)rules->nprops ); //* drand48()); - - /* calculate the combination for each "other" property of the element */ - - for ( i = 0; i < elem->nprops; i++ ) - { - /* don't bother with properties we've been asked to store explicitly */ - if ( elem->store_prop[i] ) - continue; - - prop = elem->props[i]; - offset = prop->offset; - type = prop->external_type; - - /* collect together all the values we're to combine */ - - for ( j = 0; j < rules->nprops; j++ ) - { - data = ( char * ) rules->props[j]; - ptr = ( void * ) ( data + offset ); - get_stored_item ( ( void * ) ptr, type, &int_val, &uint_val, &double_val ); - vals[j] = double_val; - } - - /* calculate the combined value */ - - switch ( rules->rule_list[i] ) - { - case AVERAGE_RULE: - { - double sum = 0; - double weight_sum = 0; - for ( j = 0; j < rules->nprops; j++ ) - { - sum += vals[j] * rules->weights[j]; - weight_sum += rules->weights[j]; - } - double_val = sum / weight_sum; - break; - } - case MINIMUM_RULE: - { - double_val = vals[0]; - for ( j = 1; j < rules->nprops; j++ ) - if ( double_val > vals[j] ) - double_val = vals[j]; - break; - } - case MAXIMUM_RULE: - { - double_val = vals[0]; - for ( j = 1; j < rules->nprops; j++ ) - if ( double_val < vals[j] ) - double_val = vals[j]; - break; - } - case RANDOM_RULE: - { - double_val = vals[random_pick]; - break; - } - case SAME_RULE: - { - double_val = vals[0]; - for ( j = 1; j < rules->nprops; j++ ) - if ( double_val != vals[j] ) - { - fprintf ( stderr, - "get_new_props_ply: Error combining properties that should be the same.\n" ); - exit ( -1 ); - } - break; - } - default: - fprintf ( stderr, "get_new_props_ply: Bad rule = %d\n", - rules->rule_list[i] ); - exit ( -1 ); - } - - /* store the combined value */ - - int_val = ( int ) double_val; - uint_val = ( unsigned int ) double_val; - ptr = ( void * ) ( new_data + offset ); - store_item ( ( char * ) ptr, type, int_val, uint_val, double_val ); - } - - return ( ( void * ) new_data ); -} - - -/****************************************************************************** -Set the list of user-specified property combination rules. -******************************************************************************/ - -void set_prop_rules_ply( PlyFile *ply, PlyRuleList *prop_rules ) -{ - ply->rule_list = prop_rules; -} - - -/****************************************************************************** -Append a property rule to a growing list of user-specified rules. - -Entry: -rule_list - current rule list -name - name of property combination rule -property - "element.property" says which property the rule affects - -Exit: -returns pointer to the new rule list -******************************************************************************/ - -PlyRuleList* append_prop_rule( PlyRuleList *rule_list, char *name, char *property ) -{ - PlyRuleList *rule; - PlyRuleList *rule_ptr; - char *str,*str2; - char *ptr; - - /* find . */ - str = strdup ( property ); - for ( ptr = str; *ptr != '\0' && *ptr != '.'; ptr++ ) - ; - - /* split string at . */ - if ( *ptr == '.' ) - { - *ptr = '\0'; - str2 = ptr + 1; - } - else - { - fprintf ( stderr, "Can't find property '%s' for rule '%s'\n", - property, name ); - return ( rule_list ); - } - - rule = ( PlyRuleList * ) malloc ( sizeof ( PlyRuleList ) ); - rule->name = name; - rule->element = str; - rule->property = str2; - rule->next = NULL; - - /* either start rule list or append to it */ - - if ( rule_list == NULL ) - rule_list = rule; - else - { - /* append new rule to current list */ - rule_ptr = rule_list; - while ( rule_ptr->next != NULL ) - rule_ptr = rule_ptr->next; - rule_ptr->next = rule; - } - - /* return pointer to list */ - - return ( rule_list ); -} - - -/****************************************************************************** -See if a name matches the name of any property combination rules. - -Entry: -name - name of rule we're trying to match - -Exit: -returns 1 if we find a match, 0 if not -******************************************************************************/ - -int matches_rule_name( char* name ) -{ - int i; - - for ( i = 0; rule_name_list[i].code != -1; i++ ) - if ( equal_strings ( rule_name_list[i].name, name ) ) - return ( 1 ); - - return ( 0 ); -} - -} //namespace diff --git a/3rdParty/MarchingCubes/McPly.h b/3rdParty/MarchingCubes/McPly.h deleted file mode 100644 index 1005323892b76c19c590b86f96ed6c81aacf4ae8..0000000000000000000000000000000000000000 --- a/3rdParty/MarchingCubes/McPly.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - -Header for PLY polygon files. - -- Greg Turk - -A PLY file contains a single polygonal _object_. - -An object is composed of lists of _elements_. Typical elements are -vertices, faces, edges and materials. - -Each type of element for a given object has one or more _properties_ -associated with the element type. For instance, a vertex element may -have as properties three floating-point values x,y,z and three unsigned -chars for red, green and blue. - ------------------------------------------------------------------------ - -Copyright (c) 1998 Georgia Institute of Technology. All rights reserved. - -Permission to use, copy, modify and distribute this software and its -documentation for any purpose is hereby granted without fee, provided -that the above copyright notice and this permission notice appear in -all copies of this software and that you do not sell the software. - -THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND, -EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -*/ -#ifndef MCPLY_H -#define MCPLY_H - -#include <cmath> -#include <string> -#include <cstring> -#include <cstring> -#include <cstdlib> - -namespace McCubes{ - -static const int PLY_ASCII = 1; // ascii PLY file -static const int PLY_BINARY_BE = 2; // binary PLY file, big endian -static const int PLY_BINARY_LE = 3; // binary PLY file, little endian - -static const int PLY_OKAY = 0; // ply routine worked okay -static const int PLY_ERROR = -1; // error in ply routine - -/* scalar data types supported by PLY format */ - -static const int StartType = 0; -static const int Int8 = 1; -static const int Int16 = 2; -static const int Int32 = 3; -static const int Uint8 = 4; -static const int Uint16 = 5; -static const int Uint32 = 6; -static const int Float32 = 7; -static const int Float64 = 8; -static const int EndType = 9; - -static const int PLY_SCALAR = 0; -static const int PLY_LIST = 1; -static const int PLY_STRING = 2; - - -typedef struct PlyProperty { /* description of a property */ - -char *name; /* property name */ -int external_type; /* file's data type */ -int internal_type; /* program's data type */ -int offset; /* offset bytes of prop in a struct */ - -int is_list; /* 0 = scalar, 1 = list, 2 = char string */ -int count_external; /* file's count type */ -int count_internal; /* program's count type */ -int count_offset; /* offset byte for list count */ - -} PlyProperty; - -typedef struct PlyElement { /* description of an element */ -char *name; /* element name */ -int num; /* number of elements in this object */ -int size; /* size of element (bytes) or -1 if variable */ -int nprops; /* number of properties for this element */ -PlyProperty **props; /* list of properties in the file */ -char *store_prop; /* flags: property wanted by user? */ -int other_offset; /* offset to un-asked-for props, or -1 if none*/ -int other_size; /* size of other_props structure */ -} PlyElement; - -typedef struct PlyOtherProp { /* describes other properties in an element */ -char *name; /* element name */ -int size; /* size of other_props */ -int nprops; /* number of properties in other_props */ -PlyProperty **props; /* list of properties in other_props */ -} PlyOtherProp; - -typedef struct OtherData { /* for storing other_props for an other element */ -void *other_props; -} OtherData; - -typedef struct OtherElem { /* data for one "other" element */ -char *elem_name; /* names of other elements */ -int elem_count; /* count of instances of each element */ -OtherData **other_data; /* actual property data for the elements */ -PlyOtherProp *other_props; /* description of the property data */ -} OtherElem; - -typedef struct PlyOtherElems { /* "other" elements, not interpreted by user */ -int num_elems; /* number of other elements */ -OtherElem *other_list; /* list of data for other elements */ -} PlyOtherElems; - -static const int AVERAGE_RULE = 1; -static const int MAJORITY_RULE = 2; -static const int MINIMUM_RULE = 3; -static const int MAXIMUM_RULE = 4; -static const int SAME_RULE = 5; -static const int RANDOM_RULE = 6; - -typedef struct PlyPropRules { /* rules for combining "other" properties */ -PlyElement *elem; /* element whose rules we are making */ -int *rule_list; /* types of rules (AVERAGE_PLY, MAJORITY_PLY, etc.) */ -int nprops; /* number of properties we're combining so far */ -int max_props; /* maximum number of properties we have room for now */ -void **props; /* list of properties we're combining */ -float *weights; /* list of weights of the properties */ -} PlyPropRules; - -typedef struct PlyRuleList { -char *name; /* name of the rule */ -char *element; /* name of element that rule applies to */ -char *property; /* name of property that rule applies to */ -struct PlyRuleList *next; /* pointer for linked list of rules */ -} PlyRuleList; - -typedef struct PlyFile { /* description of PLY file */ -FILE *fp; /* file pointer */ -int file_type; /* ascii or binary */ -float version; /* version number of file */ -int num_elem_types; /* number of element types of object */ -PlyElement **elems; /* list of elements */ -int num_comments; /* number of comments */ -char **comments; /* list of comments */ -int num_obj_info; /* number of items of object information */ -char **obj_info; /* list of object info items */ -PlyElement *which_elem; /* element we're currently reading or writing */ -PlyOtherElems *other_elems; /* "other" elements from a PLY file */ -PlyPropRules *current_rules; /* current propagation rules */ -PlyRuleList *rule_list; /* rule list from user */ -} PlyFile; - -// memory allocation -//extern char *my_alloc(); -#define myalloc(mem_size) my_alloc((mem_size), __LINE__, __FILE__) - - -// old routines - -#if 0 -extern PlyFile *ply_write(FILE *, int, char **, int); -extern PlyFile *ply_read(FILE *, int *, char ***); -extern PlyFile *ply_open_for_reading( const char *, int *, char ***, int *, float *); -extern void ply_close(PlyFile *); -extern PlyOtherProp *ply_get_other_properties(PlyFile *, const char *, int); -#endif - -extern void ply_describe_property( PlyFile * , const char * , PlyProperty * ); -extern void ply_get_property( PlyFile * , const char * , PlyProperty * ); -extern void ply_get_element( PlyFile * , void * ); - - -//--- delcaration of routines --- - -PlyOtherElems *get_other_element_ply( PlyFile * ); - -PlyFile *read_ply( FILE * ); -PlyFile *write_ply( FILE * , int, char ** , int ); -extern PlyFile *open_for_writing_ply( const char * , int, char ** , int ); -void close_ply( PlyFile * ); -void free_ply( PlyFile * ); - -void get_info_ply( PlyFile * , float * , int * ); -void free_other_elements_ply( PlyOtherElems * ); - -void append_comment_ply( PlyFile *, const char * ); -void append_obj_info_ply( PlyFile * , const char * ); -void copy_comments_ply( PlyFile * , PlyFile * ); -void copy_obj_info_ply( PlyFile * , PlyFile * ); -char* *get_comments_ply( PlyFile * , int * ); -char* *get_obj_info_ply( PlyFile * , int * ); - -char* *get_element_list_ply( PlyFile * , int * ); -int setup_property_ply( PlyFile * , PlyProperty * ); -void get_element_ply( PlyFile * , void * ); -char *setup_element_read_ply( PlyFile * , int, int * ); -PlyOtherProp *get_other_properties_ply( PlyFile * , int ); - -void element_count_ply( PlyFile * , const char * , int ); -void describe_element_ply( PlyFile * , const char * , int ); -void describe_property_ply( PlyFile * , PlyProperty * ); -void describe_other_properties_ply( PlyFile * , PlyOtherProp * , int ); -void describe_other_elements_ply( PlyFile * , PlyOtherElems * ); -void get_element_setup_ply( PlyFile * , const char * , int, PlyProperty * ); -PlyProperty* *get_element_description_ply( PlyFile * , const char * , int * , int * ); -void element_layout_ply( PlyFile * , const char * , int, int, PlyProperty * ); - -void header_complete_ply( PlyFile * ); -void put_element_setup_ply( PlyFile * ,const char * ); -void put_element_ply( PlyFile * , void * ); -void put_other_elements_ply( PlyFile * ); - -PlyPropRules *init_rule_ply( PlyFile * , const char * ); -void modify_rule_ply( PlyPropRules * , const char * , int ); -void start_props_ply( PlyFile * , PlyPropRules * ); -void weight_props_ply( PlyFile * , float, void * ); -void *get_new_props_ply( PlyFile * ); -void set_prop_rules_ply( PlyFile * , PlyRuleList * ); -PlyRuleList *append_prop_rule( PlyRuleList * , const char * , const char * ); -int matches_rule_name( const char * ); - -int equal_strings( const char * , const char * ); -char *recreate_command_line( int, char *argv[] ); - -} //namespace McCubes - -#endif // PLY_H__ - diff --git a/3rdParty/MarchingCubes/McTypes.h b/3rdParty/MarchingCubes/McTypes.h deleted file mode 100644 index f2303476e6fcb62f22e5ae82f30c090db1871a88..0000000000000000000000000000000000000000 --- a/3rdParty/MarchingCubes/McTypes.h +++ /dev/null @@ -1,37 +0,0 @@ -// _ ___ __ __________ _ __ -// | | / (_)____/ /___ ______ _/ / ____/ /_ __(_)___/ /____ -// | | / / / ___/ __/ / / / __ `/ / /_ / / / / / / __ / ___/ -// | |/ / / / / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__ ) -// |___/_/_/ \__/\__,_/\__,_/_/_/ /_/\__,_/_/\__,_/____/ -// -#ifndef MCTYPES_H -#define MCTYPES_H - -//extension by CAB -#include <vector> -#include <string> -#include <fstream> - -#include <basics/utilities/UbException.h> -#include <basics/container/CbArray3D.h> -#include <basics/container/CbArray4D.h> - -namespace McCubes -{ - - #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 double real; - -} //namespace McCubes - -#endif //MCTYPES_H diff --git a/3rdParty/MarchingCubes/McWrapper.h b/3rdParty/MarchingCubes/McWrapper.h deleted file mode 100644 index b36a2a7ea93e30e8be039e91d8984ebc34d237e1..0000000000000000000000000000000000000000 --- a/3rdParty/MarchingCubes/McWrapper.h +++ /dev/null @@ -1,305 +0,0 @@ -// _ ___ __ __________ _ __ -//| | / (_)____/ /___ ______ _/ / ____/ /_ __(_)___/ /____ -//| | / / / ___/ __/ / / / __ `/ / /_ / / / / / / __ / ___/ -//| |/ / / / / /_/ /_/ / /_/ / / __/ / / /_/ / / /_/ (__ ) -//|___/_/_/ \__/\__,_/\__,_/_/_/ /_/\__,_/_/\__,_/____/ -// -//#ifndef MCWRAPPER_H -//#define MCWRAPPER_H -// -//extension by CAB -//#include <vector> -//#include <string> -//#include <fstream> -// -//#include <basics/utilities/UbException.h> -//#include <basics/container/CbUniformMatrix3D.h> -//#include <basics/container/CbUniformMatrix4D.h> -// -//#include <3rdParty/MarchingCubes/McTypes.h> -// -//namespace McCubes{ -// -////////////////////////////////////////////////////////////////////////// -//Standard-Wrapper -// MarchingCubes<DataWrapper> mc( 10,8,5 ); -// for(int z=0; z<mc.size_z(); z++) -// for(int y=0; y<mc.size_y(); y++) -// for(int x=0; x<mc.size_x(); x++) -// mc.set_data(x,x,y,z); -// -// //mc.set_method(false) //<-MC methode, STD=false -// mc.init_all(); -// -// mc.run(3.5); -// mc.writeUCD("c:/temp/triangles.inp"); -// mc.clean_all(); - -//template< typename T=real > -//class McDataWrapper -//{ -//public: -// typedef T value_type; -// typedef typename std::vector< value_type >::reference reference; -// typedef typename std::vector< value_type >::const_reference const_reference; -// typedef typename std::vector< value_type >::pointer pointer; -// typedef typename std::vector< value_type >::const_pointer const_pointer; -// -//public: -// McDataWrapper() : size_x1(-1), size_x2(-1), size_x3(-1) -// { -// } -// /*==========================================================*/ -// McDataWrapper(const int& size_x1, const int& size_x2, const int& size_x3, const T& initVal=T()) -// { -// this->resize(size_x1,size_x2,size_x3,initVal); -// } -// /*=======================================================================*/ -// reference operator() (const int& x1, const int& x2, const int& x3) -// { -// #ifdef _DEBUG -// return this->data.at(x1 + x2*size_x1 + x3*size_x1*size_x2); -// #else -// return this->data[x1 + x2*size_x1 + x3*size_x1*size_x2]; -// #endif -// } -// /*=======================================================================*/ -// const_reference operator() (const int& x1, const int& x2, const int& x3) const -// { -// #ifdef _DEBUG -// return this->data.at(x1 + x2*size_x1 + x3*size_x1*size_x2); -// #else -// return this->data[x1 + x2*size_x1 + x3*size_x1*size_x2]; -// #endif -// } -// /*==========================================================*/ -// inline void setData( const T& val, const int& x1, const int& x2, const int& x3 ) -// { -// #ifdef _DEBUG -// this->data.at(x1 + x2*size_x1 + x3*size_x1*size_x2) = val; -// #else -// this->data[x1 + x2*size_x1 + x3*size_x1*size_x2] = val; -// #endif -// } -// /*==========================================================*/ -// inline value_type getData(const int& x1, const int& x2, const int& x3 ) const -// { -// #ifdef _DEBUG -// return this->data.at(x1 + x2*size_x1 + x3*size_x1*size_x2); -// #else -// return this->data[x1 + x2*size_x1 + x3*size_x1*size_x2]; -// #endif -// } -// /*==========================================================*/ -// inline void resize(const int& size_x1, const int& size_x2, const int& size_x3) -// { -// if(size_x1>0 && size_x2>0 && size_x3>0) -// { -// this->size_x1 = size_x1; -// this->size_x2 = size_x2; -// this->size_x3 = size_x3; -// this->data.resize(size_x1*size_x2*size_x3); -// } -// } -// /*==========================================================*/ -// inline void resize(const int& size_x1, const int& size_x2, const int& size_x3, const T& initVal) -// { -// if(size_x1>0 && size_x2>0 && size_x3>0) -// { -// this->size_x1 = size_x1; -// this->size_x2 = size_x2; -// this->size_x3 = size_x3; -// this->data.resize(size_x1*size_x2*size_x3,initVal); -// } -// } -// /*==========================================================*/ -// int getNX1() const { return size_x1; } -// int getNX2() const { return size_x2; } -// int getNX3() const { return size_x3; } -// -//protected: -// std::vector<T> data; -// int size_x1, size_x2, size_x3; -//}; -// -////////////////////////////////////////////////////////////////////////// -//Matrix4DWrapper-Wrapper -//example: -// int indexForDataValue = 1; -// CbUniformMatrix4D<double> data(10,8,5,2); -// for(int x3=0; x3<data.getNX3(); x3++) -// for(int x2=0; x2<data.getNX2(); x2++) -// for(int x1=0; x1<data.getNX1(); x1++) -// data(x1,x2,x3,indexForDataValue) = x1; -// -// Matrix4DWrapper< CbUniformMatrix4D<double> > wrapper(&data,indexForDataValue); -// MarchingCubes< Matrix4DWrapper< CbUniformMatrix4D<double> > > mc( wrapper ); -// -// mc.init_all(); -// mc.run(3.5); -// mc.writeUCD("c:/temp/triangles.inp"); -// mc.clean_all(); -//template< typename Matrix4D > -//class Matrix4DWrapper -//{ -//public: -// typedef typename Matrix4D::value_type value_type; -// -//public: -// Matrix4DWrapper() : valIndex(-1), matrix(NULL), minX1(-1), minX2(-1), minX3(-1), maxX1(-1), maxX2(-1), maxX3(-1) -// { -// //wird benoetigt, damit MarchingCubes generell eine membervariabel erstellen kann -// } -// /*==========================================================*/ -// //fuer beliebige matrizen -// Matrix4DWrapper( Matrix4D* matrix, const int& valIndex) -// : valIndex(valIndex), matrix(matrix) -// { -// -// } -// /*==========================================================*/ -// Matrix4DWrapper( Matrix4D* matrix, const int& valIndex,const int& n1, const int& nx2, const int& nx3) -// : valIndex(valIndex), matrix(matrix), nx1(nx1), nx2(nx2), nx3(nx3) -// { -// minX1 = minX2 = minX3 = 0; -// maxX1 = nx1-1; -// maxX2 = nx2-1; -// maxX3 = nx3-1; -// } -// /*==========================================================*/ -// //wenn man z.B. matrixX1 von[0..10] geht und man nur den bereich 1..9 fuer MC -// //verwenden moechte -> minX1=1 und maxX2=2 -// Matrix4DWrapper( Matrix4D* matrix, const int& valIndex, const int& minX1, const int& minX2, const int& minX3, -// const int& maxX1, const int& maxX2, const int& maxX3) -// : valIndex(valIndex), matrix(matrix), minX1(minX1), minX2(minX2), minX3(minX3), maxX1(maxX1), maxX2(maxX2), maxX3(maxX3) -// { -// nx1 = matrix->getNX1()-1; -// nx2 = matrix->getNX2()-1; -// nx3 = matrix->getNX3()-1; -// -// if(minX1<0 || minX2<0 || minX3<0 || maxX1>=nx1 || maxX2>=nx2 || maxX3>=nx3) -// throw UbException(UB_EXARGS,"range error"); -// } -// /*==========================================================*/ -// inline void setData( const real& val, const int& x1, const int& x2, const int& x3 ) -// { -// (*matrix)(minX1+x1, minX2+x2, minX3+x3, valIndex) = static_cast<value_type>(val); -// } -// /*==========================================================*/ -// inline value_type getData(const int& x1, const int& x2, const int& x3 ) const -// { -// return (*matrix)(minX1+x1, minX2+x2, minX3+x3, valIndex); -// } -// /*==========================================================*/ -// inline void resize(const int& size_x1, const int& size_x2, const int& size_x3) -// { -// throw UbException("Matrix4DWrapper::resize(int,int,int) - mit diesem wrapper nicht erlaubt"); -// } -// /*==========================================================*/ -// inline int getMinX1() const { return minX1; } -// inline int getMinX2() const { return minX2; } -// inline int getMinX3() const { return minX3; } -// -// inline int getMaxX1() const { return maxX1; } -// inline int getMaxX2() const { return maxX2; } -// inline int getMaxX3() const { return maxX3; } -// -// inline int getNX1() const { nx1; } -// inline int getNX2() const { nx2; } -// inline int getNX3() const { nx3; } -// -//protected: -// int valIndex; -// Matrix4D* matrix; -// int minX1, minX2, minX3, maxX1, maxX2, maxX3, nx1, nx2, nx3; -//}; -// -////////////////////////////////////////////////////////////////////////// -//Matrix3DWrapper-Wrapper -// CbUniformMatrix3D<double> data(10,8,5); -// for(int x3=0; x3<data.getNX3(); x3++) -// for(int x2=0; x2<data.getNX2(); x2++) -// for(int x1=0; x1<data.getNX1(); x1++) -// data(x1,x2,x3) = x1; -// -// Matrix3DWrapper< CbUniformMatrix3D<double> > wrapper(&data); -// MarchingCubes< Matrix3DWrapper< CbUniformMatrix3D<double> > > mc( wrapper ); -// -// mc.init_all(); -// mc.run(3.5); -// mc.writeUCD("c:/temp/triangles.inp"); -// mc.clean_all(); -//template< typename Matrix3D > -//class Matrix3DWrapper -//{ -//public: -// typedef typename Matrix3D::value_type value_type; -// -//public: -// Matrix3DWrapper() : matrix(NULL), minX1(-1), minX2(-1), minX3(-1), maxX1(-1), maxX2(-1), maxX3(-1) -// { -// //wird benoetigt, damit MarchingCubes generell eine membervariabel erstellen kann -// } -// /*==========================================================*/ -// Matrix3DWrapper( Matrix3D* matrix) -// : matrix(matrix) -// { -// minX1 = minX2 = minX3 = 0; -// maxX1 = matrix->getNX1(); -// maxX2 = matrix->getNX2(); -// maxX3 = matrix->getNX3(); -// -// minX1 = minX2 = minX3 = 0; -// maxX1 = nx1-1; -// maxX2 = nx2-1; -// maxX3 = nx3-1; -// -// } -// /*==========================================================*/ -// Matrix3DWrapper( Matrix3D* matrix, const int& minX1, const int& minX2, const int& minX3 -// , const int& maxX1, const int& maxX2, const int& maxX3 ) -// : matrix(matrix), minX1(minX1), minX2(minX2), minX3(minX3), maxX1(maxX1), maxX2(maxX2), maxX3(maxX3) -// { -// -// } -// /*==========================================================*/ -// Matrix3DWrapper(const int& size_x1, const int& size_x2, const int& size_x3) -// { -// throw UbException("Matrix3DWrapper(int,int,int) - mit diesem wrapper nicht erlaubt"); -// } -// /*==========================================================*/ -// inline void setData( const real& val, const int& x1, const int& x2, const int& x3 ) -// { -// (*matrix)(minX1+x1, minX2+x2, minX3+x3) = static_cast<value_type>(val); -// } -// /*==========================================================*/ -// inline value_type getData(const int& x1, const int& x2, const int& x3 ) const -// { -// return (*matrix)(minX1+x1, minX2+x2, minX3+x3); -// } -// /*==========================================================*/ -// inline void resize(const int& size_x1, const int& size_x2, const int& size_x3) -// { -// throw UbException("Matrix3DWrapper::resize(int,int,int) - mit diesem wrapper nicht erlaubt"); -// } -// /*==========================================================*/ -// inline int getMinX1() const { return minX1; } -// inline int getMinX2() const { return minX2; } -// inline int getMinX3() const { return minX3; } -// -// inline int getMaxX1() const { return maxX1; } -// inline int getMaxX2() const { return maxX2; } -// inline int getMaxX3() const { return maxX3; } -// -// inline int getNX1() const { nx1; } -// inline int getNX2() const { nx2; } -// inline int getNX3() const { nx3; } -// -//protected: -// Matrix3D* matrix; -// int minX1, minX2, minX3, maxX1, maxX2, maxX3, nx1, nx2, nx3; -//}; -// -//} //namespace McCubes -// -//#endif //MCWRAPPER_H diff --git a/CMakeLists.txt b/CMakeLists.txt index ec5f5dbedbdb2f6b7d38fc39b6b864f3e33559e2..7effd22cff1b1569dfd05d25794680490f86b82a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,9 @@ option(BUILD_VF_GPU "Build VirtualFluids gpu variant" OFF) option(BUILD_USE_OPENMP "Build VirtualFluids with openmp" ON) option(BUILD_USE_BOOST "Build VirtualFluids with boost" OFF) -option(BUILD_USE_MPI "include MPI library support" ON) + +# TODO: https://git.rz.tu-bs.de/irmb/VirtualFluids_dev/-/issues/139 +# option(BUILD_USE_MPI "include MPI library support" ON) # vf gpu option(BUILD_NUMERIC_TESTS "Build numeric tests" OFF) @@ -190,10 +192,11 @@ if(BUILD_USE_OPENMP) find_package(OpenMP REQUIRED) endif() -if(BUILD_USE_MPI) +# TODO: https://git.rz.tu-bs.de/irmb/VirtualFluids_dev/-/issues/139 +# if(BUILD_USE_MPI) find_package(MPI REQUIRED) list(APPEND VF_COMPILER_DEFINITION VF_MPI) -endif() +# endif() # boost IF(BUILD_USE_BOOST) diff --git a/Python/actuator_line/actuator_line.py b/Python/actuator_line/actuator_line.py index 00fa21baeae9d075f4ebeb49baa9d13394ae4b94..f3780154dabf5e8a00632ef09a5f4c2db849a1e8 100644 --- a/Python/actuator_line/actuator_line.py +++ b/Python/actuator_line/actuator_line.py @@ -36,7 +36,7 @@ r""" import numpy as np from pathlib import Path from mpi4py import MPI -from pyfluids import basics, gpu, logger, communicator +from pyfluids import basics, gpu, logger, parallel #%% sim_name = "ABL" config_file = Path(__file__).parent/"configActuatorLine.txt" @@ -44,19 +44,24 @@ output_path = Path(__file__).parent/Path("output") output_path.mkdir(exist_ok=True) +def get_velocity(z, u_star, kappa, z0): + return u_star/kappa*np.log(z/z0+1) #%% logger.Logger.initialize_logger() grid_builder = gpu.grid_generator.MultipleGridBuilder() -communicator = communicator.Communicator.get_instance() +communicator = parallel.MPICommunicator.get_instance() config = basics.ConfigurationFile() config.load(str(config_file)) -para = gpu.Parameter(communicator.get_number_of_processes(), communicator.get_number_of_processes(), config) +para = gpu.Parameter(communicator.get_number_of_processes(), communicator.get_process_id(), config) bc_factory = gpu.BoundaryConditionFactory() #%% +use_refinement = config.get_bool_value("useRefinement", False) +turbine_height = config.get_float_value("turbineHeight", 120) +tip_speed_ratio = config.get_float_value("tipSpeedRatio", 7.55) turbine_diameter = config.get_float_value("turbineDiameter", 126) boundary_layer_height = config.get_float_value("boundaryLayerHeight", 1000) z0 = config.get_float_value("z0", 0.1) @@ -66,17 +71,18 @@ kappa = config.get_float_value("vonKarmanConstant", 0.4) # von Karman constant viscosity = config.get_float_value("viscosity", 1.56e-5) -velocity = 0.5*u_star/kappa*np.log(boundary_layer_height/z0+1) #0.5 times max mean velocity at the top in m/s +velocity = 0.5*get_velocity(boundary_layer_height, u_star, kappa, z0) #0.5 times max mean velocity at the top in m/s mach = config.get_float_value("Ma", 0.1) nodes_per_height = config.get_uint_value("nz", 64) +length = np.array([6,4,1])*boundary_layer_height +turbine_positions_x = np.ones(1)*boundary_layer_height +turbine_positions_y = np.ones(1)*length[1]/2 +turbine_positions_z = np.ones(1)*turbine_height +level = 0 -turb_pos = np.array([3,3,3])*turbine_diameter -epsilon = config.get_float_value("SmearingWidth", 5) density = config.get_float_value("Density", 1.225) -level = 0 -n_blades = 3 n_blade_nodes = config.get_int_value("NumberOfNodesPerAL", 32) read_precursor = config.get_bool_value("readPrecursor", False) @@ -98,7 +104,6 @@ t_start_out_probe = config.get_float_value("tStartOutProbe") t_out_probe = config.get_float_value("tOutProbe") #%% -length = np.array([6,4,1])*boundary_layer_height dx = boundary_layer_height/nodes_per_height dt = dx * mach / (np.sqrt(3) * velocity) velocity_ratio = dx/dt @@ -127,7 +132,7 @@ para.set_velocity_ratio(dx/dt) para.set_viscosity_ratio(dx*dx/dt) para.set_density_ratio(1.0) -para.set_main_kernel("CumulantK17") +para.configure_main_kernel(gpu.kernel.compressible.K17CompressibleNavierStokes) para.set_timestep_start_out(int(t_start_out/dt)) para.set_timestep_out(int(t_out/dt)) @@ -141,6 +146,11 @@ grid_scaling_factory = gpu.GridScalingFactory() grid_scaling_factory.set_scaling_factory(gpu.GridScaling.ScaleCompressible) grid_builder.add_coarse_grid(0.0, 0.0, 0.0, length[0], length[1], length[2], dx) + +if use_refinement: + level = 1 + grid_builder.add_grid(gpu.grid_generator.Cuboid(turbine_positions_x[0]- 3*turbine_diameter, turbine_positions_y[0]-3*turbine_diameter, 0, + turbine_positions_x[0]+10*turbine_diameter, turbine_positions_y[0]+3*turbine_diameter, turbine_positions_z[0]+3*turbine_diameter), level) grid_builder.set_periodic_boundary_condition(not read_precursor, True, False) grid_builder.build_grids(False) @@ -156,7 +166,7 @@ grid_builder.set_slip_boundary_condition(gpu.SideType.PZ, 0, 0, -1) if read_precursor: grid_builder.set_pressure_boundary_condition(gpu.SideType.PX, 0) bc_factory.set_stress_boundary_condition(gpu.StressBC.StressPressureBounceBack) -bc_factory.set_slip_boundary_condition(gpu.SlipBC.SlipBounceBack) +bc_factory.set_slip_boundary_condition(gpu.SlipBC.SlipCompressibleTurbulentViscosity) bc_factory.set_pressure_boundary_condition(gpu.PressureBC.OutflowNonReflective) if read_precursor: bc_factory.set_precursor_boundary_condition(gpu.PrecursorBC.DistributionsPrecursor if use_distributions else gpu.PrecursorBC.VelocityPrecursor) @@ -174,16 +184,13 @@ para.set_outflow_pressure_correction_factor(0.0) para.set_initial_condition_perturbed_log_law(u_star, z0, length[0], length[2], boundary_layer_height, velocity_ratio) #%% -turb_pos = np.array([3, 3, 3])*turbine_diameter -epsilon = 1.5*dx -density = 1.225 -level = 0 -n_blades = 3 -n_blade_nodes = 32 -omega = 1 -blade_radii = np.arange(n_blade_nodes, dtype=np.float32)/(0.5*turbine_diameter) -alm = gpu.ActuatorFarm(n_blades, density, n_blade_nodes, epsilon, level, dt, dx, True) -alm.add_turbine(turb_pos[0], turb_pos[1], turb_pos[2], turbine_diameter, omega, 0, 0, blade_radii) + +smearing_width = 1.5*dx +blade_radius = 0.5*turbine_diameter +hub_height_velocity = get_velocity(turbine_height, u_star, kappa, z0) +rotor_speeds = np.ones(1)*tip_speed_ratio*hub_height_velocity/blade_radius +alm = gpu.ActuatorFarmStandalone(turbine_diameter, n_blade_nodes, turbine_positions_x, turbine_positions_y, turbine_positions_z, rotor_speeds, density, smearing_width, level, dt, dx) +alm.enable_output("ALM", int(t_start_out_probe/dt), int(t_out_probe/dt) ) para.add_actuator(alm) #%% planar_average_probe = gpu.probes.PlanarAverageProbe("horizontalPlanes", para.get_output_path(), 0, int(t_start_tmp_averaging/dt), int(t_averaging/dt) , int(t_start_out_probe/dt), int(t_out_probe/dt), 'z') @@ -211,7 +218,6 @@ for n_probe, probe_pos in enumerate(plane_locs): cuda_memory_manager = gpu.CudaMemoryManager(para) grid_generator = gpu.GridProvider.make_grid_generator(grid_builder, para, cuda_memory_manager, communicator) #%% -#%% sim = gpu.Simulation(para, cuda_memory_manager, communicator, grid_generator, bc_factory, tm_factory, grid_scaling_factory) #%% sim.run() diff --git a/Python/actuator_line_with_wifi/NREL5MW.cd b/Python/actuator_line_with_wifi/NREL5MW.cd new file mode 100644 index 0000000000000000000000000000000000000000..36cdd133ea270a08196db65daa9a8a4c1e326747 --- /dev/null +++ b/Python/actuator_line_with_wifi/NREL5MW.cd @@ -0,0 +1,75 @@ +0 1 0.4 0.35 0.3 0.25 0.21 0.18 +-180 0.5 0.0602 0.0407 0.0267 0.0202 0.0185 0.0198 +-170 0.5 0.1107 0.1055 0.0968 0.0943 0.0945 0.0955 +-160 0.5 0.3045 0.2982 0.2876 0.2848 0.2809 0.2807 +-150 0.5 0.5355 0.5308 0.5232 0.5215 0.5112 0.5086 +-140 0.5 0.7685 0.7672 0.7656 0.766 0.7485 0.7427 +-130 0.5 0.9788 0.9819 0.9882 0.9911 0.9665 0.9574 +-120 0.5 1.1499 1.158 1.173 1.1787 1.1476 1.1355 +-110 0.5 1.2716 1.2847 1.3084 1.3168 1.2805 1.2656 +-100 0.5 1.3378 1.3557 1.3875 1.3984 1.3582 1.341 +-90 0.5 1.346 1.368 1.407 1.4201 1.3774 1.3587 +-80 0.5 1.2964 1.3218 1.3664 1.3811 1.3376 1.3181 +-70 0.5 1.1918 1.2193 1.2676 1.2833 1.2409 1.2212 +-60 0.5 1.0376 1.066 1.1156 1.1315 1.0919 1.0731 +-50 0.5 0.8429 0.8705 0.9187 0.9341 0.899 0.882 +-40 0.5 0.6215 0.6466 0.6904 0.7042 0.6754 0.661 +-35 0.5 0.5067 0.5299 0.5703 0.5829 0.5579 0.5451 +-30 0.5 0.3932 0.4141 0.4503 0.4616 0.4405 0.4295 +-25 0.5 0.2849 0.303 0.3357 0.3441 0.3256 0.3071 +-22 0.5 0.2242 0.2404 0.2752 0.273 0.2506 0.2297 +-20 0.5 0.1861 0.2011 0.2388 0.2237 0.1983 0.1785 +-18 0.5 0.1533 0.164 0.2056 0.1743 0.1457 0.1288 +-16 0.5 0.1281 0.13 0.1754 0.1256 0.094 0.0786 +-14 0.5 0.1101 0.1 0.1413 0.0789 0.0508 0.0283 +-12 0.5 0.0986 0.0744 0.1015 0.0271 0.0271 0.0134 +-10 0.5 0.0931 0.0534 0.0718 0.0287 0.0287 0.0111 +-9 0.5 0.0931 0.0469 0.0545 0.0271 0.0201 0.0099 +-8 0.5 0.093 0.0404 0.0254 0.0195 0.012 0.0091 +-7 0.5 0.0809 0.034 0.0175 0.0105 0.009 0.0086 +-6 0.5 0.0689 0.0275 0.0117 0.0091 0.0082 0.0082 +-5 0.5 0.0547 0.0223 0.0097 0.0073 0.0069 0.0079 +-4 0.5 0.0411 0.0173 0.0091 0.007 0.0063 0.0072 +-3 0.5 0.0299 0.024 0.0089 0.0068 0.0058 0.0064 +-2 0.5 0.0198 0.016 0.0088 0.0068 0.0057 0.0054 +-1 0.5 0.0147 0.0118 0.0088 0.0067 0.0057 0.0052 +0 0.5 0.0113 0.0094 0.0087 0.0065 0.0057 0.0052 +1 0.5 0.0118 0.0098 0.0088 0.0066 0.0058 0.0052 +2 0.5 0.0124 0.01 0.009 0.0068 0.0059 0.0053 +3 0.5 0.0123 0.0103 0.0092 0.007 0.0063 0.0053 +4 0.5 0.0119 0.0105 0.0095 0.0073 0.0071 0.0054 +5 0.5 0.0125 0.0108 0.0097 0.0079 0.009 0.0058 +6 0.5 0.0135 0.011 0.0101 0.0099 0.0113 0.0091 +7 0.5 0.0158 0.0115 0.0107 0.0132 0.0131 0.0113 +8 0.5 0.0198 0.012 0.0125 0.0153 0.0147 0.0124 +9 0.5 0.0275 0.0133 0.0155 0.0181 0.0181 0.0136 +10 0.5 0.0393 0.0156 0.0192 0.0262 0.0255 0.015 +11 0.5 0.058 0.0194 0.0255 0.042 0.0347 0.0383 +12 0.5 0.0816 0.0269 0.037 0.0601 0.0468 0.0613 +13 0.5 0.1129 0.0398 0.063 0.0785 0.0633 0.0841 +14 0.5 0.1469 0.0614 0.0931 0.1 0.0806 0.1065 +15 0.5 0.1845 0.0979 0.1239 0.1219 0.0987 0.1287 +16 0.5 0.225 0.1377 0.1592 0.1433 0.117 0.1509 +17 0.5 0.2684 0.1814 0.1903 0.1649 0.1368 0.1728 +18 0.5 0.3121 0.2316 0.2186 0.1845 0.1562 0.1947 +19 0.5 0.3554 0.2719 0.2455 0.2061 0.177 0.2165 +20 0.5 0.3997 0.3085 0.2689 0.228 0.1987 0.2379 +22 0.5 0.483 0.382 0.3246 0.2814 0.2499 0.2799 +25 0.5 0.6141 0.4988 0.4198 0.3678 0.3371 0.3377 +30 0.5 0.8441 0.6978 0.5843 0.5149 0.4813 0.4294 +35 0.5 1.0722 0.8869 0.7438 0.6548 0.6127 0.5324 +40 0.5 1.2873 1.0671 0.897 0.7901 0.7396 0.6452 +50 0.5 1.6401 1.3747 1.1686 1.0378 0.9781 0.8664 +60 0.5 1.836 1.5728 1.3647 1.2333 1.1796 1.0693 +70 0.5 1.8347 1.6302 1.4621 1.3587 1.3297 1.2438 +80 0.5 1.6334 1.5423 1.4544 1.4063 1.4202 1.3809 +90 0.5 1.3879 1.4041 1.3938 1.3985 1.4512 1.4565 +100 0.5 1.3795 1.3914 1.3798 1.381 1.4294 1.4345 +110 0.5 1.3114 1.3188 1.3063 1.3041 1.3464 1.3512 +120 0.5 1.1864 1.1891 1.1763 1.1709 1.2057 1.2099 +130 0.5 1.0102 1.0086 0.9962 0.9883 1.0144 1.0179 +140 0.5 0.7935 0.7883 0.7771 0.7676 0.7845 0.7871 +150 0.5 0.5532 0.5457 0.5364 0.5264 0.5346 0.5363 +160 0.5 0.3147 0.3066 0.3 0.2912 0.2922 0.2931 +170 0.5 0.1144 0.1085 0.1051 0.0995 0.0969 0.0971 +180 0.5 0.0602 0.0407 0.0267 0.0202 0.0185 0.0198 diff --git a/Python/actuator_line_with_wifi/NREL5MW.cl b/Python/actuator_line_with_wifi/NREL5MW.cl new file mode 100644 index 0000000000000000000000000000000000000000..f4634706d806f9eb6c705952083d85fe179b5fe5 --- /dev/null +++ b/Python/actuator_line_with_wifi/NREL5MW.cl @@ -0,0 +1,75 @@ +0 1 0.4 0.35 0.3 0.25 0.21 0.18 +-180 0 0 0 0 0 0 0 +-170 0 0.397 0.405 0.547 0.735 0.788 0.749 +-160 0 0.642 0.658 0.685 0.695 0.67 0.659 +-150 0 0.757 0.778 0.816 0.828 0.797 0.783 +-140 0 0.762 0.787 0.832 0.846 0.813 0.798 +-130 0 0.68 0.708 0.756 0.771 0.739 0.724 +-120 0 0.532 0.56 0.609 0.624 0.596 0.581 +-110 0 0.337 0.365 0.411 0.426 0.403 0.39 +-100 0 0.114 0.139 0.182 0.195 0.179 0.169 +-90 0 -0.12 -0.098 -0.061 -0.05 -0.06 -0.067 +-80 0 -0.349 -0.331 -0.302 -0.294 -0.295 -0.299 +-70 0 -0.557 -0.544 -0.523 -0.518 -0.512 -0.512 +-60 0 -0.727 -0.72 -0.708 -0.706 -0.693 -0.689 +-50 0 -0.842 -0.84 -0.838 -0.839 -0.82 -0.814 +-40 0 -0.886 -0.889 -0.895 -0.898 -0.875 -0.866 +-35 0 -0.875 -0.88 -0.889 -0.893 -0.869 -0.86 +-30 0 -0.839 -0.846 -0.858 -0.862 -0.838 -0.829 +-25 0 -0.777 -0.784 -0.832 -0.803 -0.791 -0.853 +-22 0 -0.725 -0.733 -0.919 -0.792 -0.821 -0.911 +-20 0 -0.685 -0.693 -1.013 -0.815 -0.869 -0.958 +-18 0 -0.635 -0.648 -1.125 -0.854 -0.931 -1.005 +-16 0 -0.571 -0.601 -1.245 -0.905 -0.999 -1.113 +-14 0 -0.494 -0.559 -1.21 -0.959 -1.031 -1.078 +-12 0 -0.407 -0.519 -1.033 -0.952 -0.952 -0.904 +-10 0 -0.311 -0.48 -0.85 -0.828 -0.828 -0.711 +-9 0 -0.259 -0.459 -0.767 -0.754 -0.674 -0.595 +-8 0 -0.208 -0.437 -0.744 -0.628 -0.519 -0.478 +-7 0 -0.16 -0.416 -0.664 -0.493 -0.378 -0.375 +-6 0 -0.111 -0.395 -0.525 -0.355 -0.245 -0.264 +-5 0 -0.072 -0.359 -0.382 -0.22 -0.113 -0.151 +-4 0 -0.054 -0.351 -0.251 -0.084 0.016 -0.017 +-3 0 0.003 -0.24 -0.12 0.049 0.145 0.088 +-2 0 0.009 -0.091 0.017 0.181 0.27 0.213 +-1 0 0.036 0.052 0.152 0.312 0.396 0.328 +0 0 0.137 0.196 0.288 0.444 0.521 0.442 +1 0 0.292 0.335 0.421 0.573 0.645 0.556 +2 0 0.444 0.472 0.554 0.701 0.768 0.67 +3 0 0.58 0.608 0.685 0.827 0.888 0.784 +4 0 0.71 0.742 0.815 0.952 0.996 0.898 +5 0 0.841 0.875 0.944 1.062 1.095 1.011 +6 0 0.967 1.007 1.072 1.161 1.192 1.103 +7 0 1.084 1.134 1.197 1.254 1.283 1.181 +8 0 1.193 1.26 1.305 1.336 1.358 1.257 +9 0 1.287 1.368 1.39 1.4 1.403 1.326 +10 0 1.368 1.475 1.458 1.442 1.358 1.382 +11 0 1.425 1.57 1.512 1.374 1.287 1.415 +12 0 1.473 1.642 1.549 1.277 1.272 1.434 +13 0 1.513 1.7 1.47 1.246 1.273 1.451 +14 0 1.563 1.712 1.354 1.256 1.272 1.448 +15 0 1.614 1.687 1.333 1.271 1.275 1.445 +16 0 1.649 1.649 1.329 1.289 1.284 1.448 +17 0 1.681 1.598 1.321 1.304 1.306 1.438 +18 0 1.719 1.549 1.333 1.315 1.308 1.448 +19 0 1.751 1.544 1.362 1.33 1.308 1.448 +20 0 1.783 1.565 1.398 1.354 1.311 1.428 +22 0 1.83 1.563 1.418 1.325 1.277 1.359 +25 0 1.872 1.546 1.354 1.215 1.136 1.168 +30 0 1.904 1.522 1.265 1.076 0.962 0.926 +35 0 1.929 1.544 1.264 1.066 0.947 0.8 +40 0 1.903 1.529 1.258 1.064 0.95 0.804 +50 0 1.69 1.376 1.146 0.98 0.884 0.763 +60 0 1.323 1.097 0.932 0.81 0.74 0.656 +70 0 0.88 0.75 0.657 0.582 0.54 0.495 +80 0 0.449 0.396 0.362 0.326 0.304 0.291 +90 0 0.124 0.101 0.092 0.072 0.053 0.053 +100 0 -0.118 -0.143 -0.15 -0.17 -0.198 -0.199 +110 0 -0.348 -0.374 -0.379 -0.399 -0.434 -0.436 +120 0 -0.549 -0.575 -0.578 -0.596 -0.637 -0.64 +130 0 -0.702 -0.727 -0.727 -0.743 -0.787 -0.79 +140 0 -0.787 -0.809 -0.807 -0.821 -0.864 -0.868 +150 0 -0.782 -0.8 -0.797 -0.806 -0.847 -0.85 +160 0 -0.664 -0.677 -0.673 -0.679 -0.711 -0.714 +170 0 -0.41 -0.417 -0.547 -0.735 -0.788 -0.749 +180 0 0 0 0 0 0 0 diff --git a/Python/actuator_line_with_wifi/NREL5MW.geo b/Python/actuator_line_with_wifi/NREL5MW.geo new file mode 100644 index 0000000000000000000000000000000000000000..e01eae6e09f4ad8d9f9dbc97eb2bad8c6ee5cca1 --- /dev/null +++ b/Python/actuator_line_with_wifi/NREL5MW.geo @@ -0,0 +1,18 @@ +2.8667 13.308 3.542 1 +5.6 13.308 3.854 1 +8.3333 13.308 4.167 1 +11.75 13.308 4.557 0.4 +15.85 11.48 4.652 0.35 +19.95 10.162 4.458 0.35 +24.05 9.011 4.249 0.3 +28.15 7.795 4.007 0.25 +32.25 6.544 3.748 0.25 +36.35 5.361 3.502 0.21 +40.45 4.188 3.256 0.21 +44.55 3.125 3.01 0.18 +48.65 2.319 2.764 0.18 +52.75 1.526 2.518 0.18 +56.1667 0.863 2.313 0.18 +58.9 0.37 2.086 0.18 +61.6333 0.106 1.419 0.18 +63.00 0.000 0.878 0.18 diff --git a/Python/actuator_line_with_wifi/NREL5MW.json b/Python/actuator_line_with_wifi/NREL5MW.json new file mode 100644 index 0000000000000000000000000000000000000000..24cc926908931dea8a7f3c5f18dec956f1f9619a --- /dev/null +++ b/Python/actuator_line_with_wifi/NREL5MW.json @@ -0,0 +1,33 @@ +{ + "generator": + { + "rated_speed": 122.9, + "rated_torque": 43093.55, + "max_torque": 44748, + "max_torque_rate": 15000, + "efficiency": 0.944, + "slip": 0.1 + }, + "gearbox": + { + "ratio": 97 + }, + "blade": + { + "tip_radius": 63, + "inertia": 11776047, + "mass": 17740, + "file_format": "standard", + "standard_dict": { + "geometry_file": "NREL5MW.geo", + "cl_file": "NREL5MW.cl", + "cd_file": "NREL5MW.cd" + }, + "openfast_dict": { + "input_file": "OpenFASTCoupled/NREL5MW.fst" + }, + "max_pitch_rate": 8, + "root_radius": 1.5 + }, + "number_of_blades_per_turbine": 3 +} \ No newline at end of file diff --git a/Python/actuator_line_with_wifi/SingleTurbine.json b/Python/actuator_line_with_wifi/SingleTurbine.json new file mode 100644 index 0000000000000000000000000000000000000000..5fb3b4fc5fc8b8a5533d75b05e2dc6204813313c --- /dev/null +++ b/Python/actuator_line_with_wifi/SingleTurbine.json @@ -0,0 +1,14 @@ +{ + "turbine_model": { + "name": "NREL5MW", + "file": "NREL5MW.json", + "file_type": "json" + }, + "controller": { + "name": "NREL5MWController", + "type": "Greedy", + "file": "GreedyController.json", + "file_type": "json" + }, + "hub_positions": [[0,0,0]] +} \ No newline at end of file diff --git a/Python/actuator_line_with_wifi/configActuatorLine.txt b/Python/actuator_line_with_wifi/configActuatorLine.txt new file mode 100644 index 0000000000000000000000000000000000000000..8f1fbd929e6b542ceef943593eb7e7057c971f67 --- /dev/null +++ b/Python/actuator_line_with_wifi/configActuatorLine.txt @@ -0,0 +1,40 @@ +################################################## +#information for Writing +################################################## +Path = ./output/ +################################################## +#informationsfor reading +################################################## +GridPath = . +################################################## +Devices = 0 +################################################## +tStartOut = 0 +tOut = 300 +tEnd = 600 +################################################## +tStartAveraging = 0 +tStartTmpAveraging = 300 +tAveraging = 200 +tStartOutProbe = 0 +tOutProbe = 100 +################################################## +Ma = 0.1 +nodesPerDiameter = 32 +velocity = 9 + +bodyForce = true +SGSconstant = 0.333333 +TurbulenceModel = QR + +QuadricLimiterP = 10000.0 +QuadricLimiterD = 10000.0 +QuadricLimiterM = 10000.0 + +################################################## +readPrecursor = false +nTimestepsReadPrecursor = 1 +precursorFile = precursor/Precursor + +################################################## +NumberOfNodesPerAL = 32 diff --git a/Python/actuator_line_with_wifi/controller.json b/Python/actuator_line_with_wifi/controller.json new file mode 100644 index 0000000000000000000000000000000000000000..1283360cc806c44f9dea47fb50088c466675da63 --- /dev/null +++ b/Python/actuator_line_with_wifi/controller.json @@ -0,0 +1,76 @@ +{ + "filter_frequency": 0.25, + "regions": + [ + { + "name": 1, + "min_speed": "-Inf", + "max_speed": 70, + + "torque": + { + "mode": "zero" + } + + }, + { + "name": 1.5, + "min_speed": 70, + "max_speed": 91.3, + + "torque": + { + "mode": "linear", + "kappa": 912.7, + "x_0": 70 + } + }, + { + "name": 2, + "min_speed": 91.3, + "max_speed": 120, + + "torque": + { + "mode": "quadratic", + "kappa": 2.332287 + } + }, + { + "name": 2.5, + "min_speed": 120, + "max_speed": 122.9, + "min_pitch": "-Inf", + "max_pitch": 1, + + "torque": + { + "mode": "linear", + "kappa": 4333, + "x_0": 111.3 + } + + }, + { + "name": 3, + "min_speed": 0, + "max_speed": "Inf", + "min_pitch": 0, + "max_pitch": 90, + + "pitch": + { + "mode": "PI", + "kappa_p": 0.01882681, + "kappa_i": 0.008068634, + "theta_k": 6.302336 + }, + "torque": + { + "mode": "inverse", + "kappa": 5296610 + } + + } + ] +} \ No newline at end of file diff --git a/Python/actuator_line_with_wifi/read_output.py b/Python/actuator_line_with_wifi/read_output.py new file mode 100644 index 0000000000000000000000000000000000000000..4b90e477d47a0228c2b6e607c5f40f21d798d78f --- /dev/null +++ b/Python/actuator_line_with_wifi/read_output.py @@ -0,0 +1,39 @@ +#%% +from pandas import HDFStore +from matplotlib import pyplot as plt +import numpy as np +from pathlib import Path + +from wiFI.turbine import create_turbine_from_farm_json + +def get_blade_array(hdf5: HDFStore, key: str): + blade_df = hdf5.get(key) + _, n_turbines, n_blades, n_nodes = blade_df.columns[-1] + return blade_df.to_numpy().reshape(-1, 3, n_turbines+1, n_blades+1, n_nodes+1) + +#%% +turbine_file = Path(__file__).parent/"SingleTurbine.json" +output_dir = Path(__file__).parents[2]/"output" +wifi_output = HDFStore(output_dir/"wifi.h5", mode="r") +turbine_model = create_turbine_from_farm_json(turbine_file, number_of_blade_nodes=32) +# %% +print(wifi_output.keys()) +#%% + +plt.plot(wifi_output["/Rotor_speed"]) +# %% +blade_forces = get_blade_array(wifi_output, "Blade_forces") + +plt.plot(blade_forces[-1, 0, 0, :, :].T) + +# %% +blade_coordinates = get_blade_array(wifi_output, "Blade_coordinates") +plt.scatter(blade_coordinates[-1,1,0,:,:], blade_coordinates[-1,2,0,:,:]) + +# %% +blade_velocities = get_blade_array(wifi_output, "Blade_velocities") +plt.plot(blade_velocities[-1, 0, 0, :, :].T) +# %% +plt.plot(blade_velocities[-1, 1, 0,:,:].T) + +# %% diff --git a/Python/actuator_line_with_wifi/runscript.py b/Python/actuator_line_with_wifi/runscript.py new file mode 100644 index 0000000000000000000000000000000000000000..88e32edcbf5a12beb6f226e30f30d9db93c0da0e --- /dev/null +++ b/Python/actuator_line_with_wifi/runscript.py @@ -0,0 +1,169 @@ +from pathlib import Path +from wiFI.turbine import create_turbine_from_farm_json +from wiFI.logging import LoggerConfig, LogEntry +from wiFI.interfaces.implementations.velocity_provider.VirtualFluids.VirtualFluids import create_standard_actuator_farm +from wiFI.controller.controller import ControllerTypes +from pyfluids import basics, gpu, logger, parallel +import numpy as np + + +#%% +sim_name = "ABL" +config_file = Path(__file__).parent/"configActuatorLine.txt" +turbine_file = Path(__file__).parent/"SingleTurbine.json" +controller_file = Path(__file__).parent/"controller.json" + +def load_config_file(config_file: Path): + config = basics.ConfigurationFile() + config.load(str(config_file)) + return config + +def add_plane_probes(plane_locs: np.ndarray, para: gpu.Parameter, t_start_averaging: float, t_start_out_probe: float, t_out_probe: float, dt: float, dx: float, length: np.ndarray): + for n_probe, probe_pos in enumerate(plane_locs): + plane_probe = gpu.probes.PlaneProbe(f"planeProbe_{n_probe+1}", para.get_output_path(), int(t_start_averaging/dt), 10, int(t_start_out_probe/dt), int(t_out_probe/dt)) + plane_probe.set_probe_plane(probe_pos, -length[1]/2, -length[2]/2, dx, length[1], length[2]) + plane_probe.add_all_available_statistics() + para.add_probe(plane_probe) + + +def main(sim_name: str, config_file: Path, turbine_file: Path, controller_file: Path): + logger.Logger.initialize_logger() + + config = load_config_file(config_file) + grid_builder = gpu.grid_generator.MultipleGridBuilder() + communicator = parallel.MPICommunicator.get_instance() + + para = gpu.Parameter(communicator.get_number_of_processes(), communicator.get_process_id(), config) + bc_factory = gpu.BoundaryConditionFactory() + + + viscosity = config.get_float_value("viscosity", 1.56e-5) + velocity = config.get_float_value("velocity", 9.0) + + mach = config.get_float_value("Ma", 0.1) + nodes_per_diameter = config.get_uint_value("nodesPerDiameter", 32) + + + density = config.get_float_value("Density", 1.225) + level = 0 + n_blade_nodes = config.get_int_value("NumberOfNodesPerAL", 32) + + read_precursor = config.get_bool_value("readPrecursor", False) + + if read_precursor: + nTReadPrecursor = config.get_int_value("nTimestepsReadPrecursor") + use_distributions = config.get_bool_value("useDistributions", False) + precursor_directory = config.get_string_value("precursorDirectory") + + # all in s + t_start_out = config.get_float_value("tStartOut") + t_out = config.get_float_value("tOut") + t_end = config.get_float_value("tEnd") # total time of simulation + + t_start_averaging = config.get_float_value("tStartAveraging") + t_start_tmp_averaging = config.get_float_value("tStartTmpAveraging") + t_averaging = config.get_float_value("tAveraging") + t_start_out_probe = config.get_float_value("tStartOutProbe") + t_out_probe = config.get_float_value("tOutProbe") + + + turbine_model = create_turbine_from_farm_json(turbine_file, + n_blade_nodes, + load_data = True, + use_gpu = True) + + diameter = turbine_model.blade_tip_radius*2 + + length = np.array([24,8,8])*diameter + dx = diameter/nodes_per_diameter + dt = dx * mach / (np.sqrt(3) * velocity) + velocity_ratio = dx/dt + velocity_LB = velocity / velocity_ratio # LB units + viscosity_LB = viscosity / (velocity_ratio * dx) # LB units + + logger.vf_log_info(f"velocity [dx/dt] = {velocity_LB}") + logger.vf_log_info(f"dt = {dt}") + logger.vf_log_info(f"dx = {dx}") + logger.vf_log_info(f"viscosity [10^8 dx^2/dt] = {viscosity_LB*1e8}") + + para.set_output_prefix(sim_name) + para.set_print_files(True) + output_path = Path(para.get_output_path()) + output_path.mkdir(exist_ok=True) + + para.set_forcing(0, 0, 0) + para.set_velocity_LB(velocity_LB) + para.set_viscosity_LB(viscosity_LB) + para.set_velocity_ratio(dx/dt) + para.set_viscosity_ratio(dx*dx/dt) + para.set_density_ratio(1.0) + + para.configure_main_kernel(gpu.kernel.compressible.K17CompressibleNavierStokes) + + para.set_timestep_start_out(int(t_start_out/dt)) + para.set_timestep_out(int(t_out/dt)) + para.set_timestep_end(int(t_end/dt)) + para.set_is_body_force(True) + + tm_factory = gpu.TurbulenceModelFactory(para) + tm_factory.read_config_file(config) + #%% + grid_scaling_factory = gpu.GridScalingFactory() + grid_scaling_factory.set_scaling_factory(gpu.GridScaling.ScaleCompressible) + + grid_builder.add_coarse_grid(-3*diameter, -length[1]/2, -length[2]/2, length[0]-3*diameter, length[1]/2, length[2]/2, dx) + grid_builder.set_periodic_boundary_condition(False, True, True) + grid_builder.build_grids(False) + + if read_precursor: + precursor = gpu.create_file_collection(precursor_directory + "/precursor", gpu.FileType.VTK) + grid_builder.set_precursor_boundary_condition(gpu.SideType.MX, precursor, nTReadPrecursor, 0, 0, 0) + else: + grid_builder.set_velocity_boundary_condition(gpu.SideType.MX, velocity_LB, 0, 0) + + grid_builder.set_pressure_boundary_condition(gpu.SideType.PX, 0) + + bc_factory.set_stress_boundary_condition(gpu.StressBC.StressPressureBounceBack) + bc_factory.set_slip_boundary_condition(gpu.SlipBC.SlipBounceBack) + bc_factory.set_pressure_boundary_condition(gpu.PressureBC.OutflowNonReflective) + if read_precursor: + bc_factory.set_precursor_boundary_condition(gpu.PrecursorBC.DistributionsPrecursor if use_distributions else gpu.PrecursorBC.VelocityPrecursor) + else: + bc_factory.set_velocity_boundary_condition(gpu.VelocityBC.VelocityAndPressureCompressible) + + para.set_outflow_pressure_correction_factor(0.0) + + para.set_initial_condition_uniform(velocity_LB, 0, 0) + + + logging_config = LoggerConfig("wifi", output_path, start_time=1000, log_period=100) + logging_dict = {"wind_farm": [LogEntry("rotor_speed", True, True), + LogEntry("azimuth", True, True)]} + + + tip_speed_ratio = 7.55*np.ones(turbine_model.n_turbines) + rotor_speeds = tip_speed_ratio * velocity / turbine_model.blade_tip_radius + smearing_width = 2*dx + farm = create_standard_actuator_farm(logging_config, logging_dict, turbine_model, density, smearing_width, + level, dt, dx, communicator.get_process_id(), + ControllerTypes.Greedy, controller_file, rotor_speeds) + + # farm = gpu.ActuatorFarmStandalone(turbine_model.blade_tip_radius*2, turbine_model.n_nodes_per_blade, turbine_model.hub_positions.x, turbine_model.hub_positions.y, turbine_model.hub_positions.z, rotor_speeds, density, smearing_width, level, dt, dx) + farm.enable_output("ALM", 0, int(t_out_probe/dt)) + para.add_actuator(farm) + + plane_locs = np.array([-1,1,2,3,4])*diameter + add_plane_probes(plane_locs, para, t_start_averaging, t_start_out_probe, t_out_probe, dt, dx, length) + plane_probe = gpu.probes.PlaneProbe(f"streamwiseProbe", para.get_output_path(), int(t_start_averaging/dt), 10, int(t_start_out_probe/dt), int(t_out_probe/dt)) + plane_probe.set_probe_plane(-diameter*3, 0, -length[2]/2, length[0], dx, length[2]) + plane_probe.add_all_available_statistics() + para.add_probe(plane_probe) + + cuda_memory_manager = gpu.CudaMemoryManager(para) + grid_generator = gpu.GridProvider.make_grid_generator(grid_builder, para, cuda_memory_manager, communicator) + sim = gpu.Simulation(para, cuda_memory_manager, communicator, grid_generator, bc_factory, tm_factory, grid_scaling_factory) + sim.run() + + +if __name__ == '__main__': + main(sim_name, config_file, turbine_file, controller_file) diff --git a/Python/boundary_layer/boundary_layer.py b/Python/boundary_layer/boundary_layer.py index 46c1014eb65ab6a393a532ab9ccf6b4ccdb424e4..34608e192a8cca19d6021c00d354272461f648bf 100644 --- a/Python/boundary_layer/boundary_layer.py +++ b/Python/boundary_layer/boundary_layer.py @@ -36,7 +36,7 @@ r""" import numpy as np from pathlib import Path from mpi4py import MPI -from pyfluids import basics, gpu, logger, communicator +from pyfluids import basics, gpu, logger, parallel #%% sim_name = "ABL" config_file = Path(__file__).parent/"configBoundaryLayer.txt" @@ -49,7 +49,7 @@ logger.Logger.initialize_logger() #%% grid_builder = gpu.grid_generator.MultipleGridBuilder() -communicator = communicator.Communicator.get_instance() +communicator = parallel.MPICommunicator.get_instance() config = basics.ConfigurationFile() config.load(str(config_file)) @@ -57,6 +57,9 @@ config.load(str(config_file)) para = gpu.Parameter(communicator.get_number_of_processes(), communicator.get_process_id(), config) bc_factory = gpu.BoundaryConditionFactory() +grid_scaling_factory = gpu.GridScalingFactory() +grid_scaling_factory.set_scaling_factory(gpu.GridScaling.ScaleCompressible) + #%% boundary_layer_height = config.get_float_value("boundaryLayerHeight", 1000) z0 = config.get_float_value("z0", 0.1) @@ -129,14 +132,14 @@ para.set_velocity_ratio(dx/dt) para.set_viscosity_ratio(dx*dx/dt) para.set_density_ratio(1.0) -para.set_main_kernel("CumulantK17") +para.configure_main_kernel(gpu.kernel.compressible.K17CompressibleNavierStokes) para.set_timestep_start_out(int(t_start_out/dt)) para.set_timestep_out(int(t_out/dt)) para.set_timestep_end(int(t_end/dt)) para.set_is_body_force(config.get_bool_value("bodyForce")) para.set_devices(np.arange(10)) -para.set_max_dev(communicator.get_number_of_process()) +para.set_max_dev(communicator.get_number_of_processes()) #%% tm_factory = gpu.TurbulenceModelFactory(para) tm_factory.read_config_file(config) @@ -158,7 +161,7 @@ if read_precursor: grid_builder.set_pressure_boundary_condition(gpu.SideType.PX, 0) bc_factory.set_pressure_boundary_condition(gpu.PressureBC.OutflowNonReflective) bc_factory.set_precursor_boundary_condition(gpu.PrecursorBC.DistributionsPrecursor if use_distributions else gpu.PrecursorBC.VelocityPrecursor) - + bc_factory.set_stress_boundary_condition(gpu.StressBC.StressPressureBounceBack) bc_factory.set_slip_boundary_condition(gpu.SlipBC.SlipBounceBack) para.set_outflow_pressure_correction_factor(0.0); @@ -197,7 +200,7 @@ cuda_memory_manager = gpu.CudaMemoryManager(para) grid_generator = gpu.GridProvider.make_grid_generator(grid_builder, para, cuda_memory_manager, communicator) #%% #%% -sim = gpu.Simulation(para, cuda_memory_manager, communicator, grid_generator, bc_factory, tm_factory) +sim = gpu.Simulation(para, cuda_memory_manager, communicator, grid_generator, bc_factory, tm_factory, grid_scaling_factory) #%% sim.run() MPI.Finalize() \ No newline at end of file diff --git a/apps/gpu/ActuatorLine/ActuatorLine.cpp b/apps/gpu/ActuatorLine/ActuatorLine.cpp index 2bfe99546e23b46901a9ac9d341243e6f36256e1..ed8d2477139313d2cbe167492b6f5a247d6e5dc8 100644 --- a/apps/gpu/ActuatorLine/ActuatorLine.cpp +++ b/apps/gpu/ActuatorLine/ActuatorLine.cpp @@ -65,21 +65,20 @@ ////////////////////////////////////////////////////////////////////////// -#include "gpu/core/LBM/Simulation.h" -#include "gpu/core/DataStructureInitializer/GridReaderGenerator/GridGenerator.h" #include "gpu/core/DataStructureInitializer/GridProvider.h" +#include "gpu/core/DataStructureInitializer/GridReaderGenerator/GridGenerator.h" #include "gpu/core/DataStructureInitializer/GridReaderFiles/GridReader.h" +#include "gpu/core/Factories/BoundaryConditionFactory.h" +#include "gpu/core/GPU/CudaMemoryManager.h" +#include "gpu/core/GridScaling/GridScalingFactory.h" +#include "gpu/core/LBM/Simulation.h" +#include "gpu/core/Kernel/KernelTypes.h" #include "gpu/core/Parameter/Parameter.h" #include "gpu/core/Output/FileWriter.h" -#include "gpu/core/PreCollisionInteractor/ActuatorFarm.h" +#include "gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmStandalone.h" #include "gpu/core/PreCollisionInteractor/Probes/PointProbe.h" #include "gpu/core/PreCollisionInteractor/Probes/PlaneProbe.h" -#include "gpu/core/Factories/BoundaryConditionFactory.h" #include "gpu/core/TurbulenceModels/TurbulenceModelFactory.h" -#include "gpu/core/GridScaling/GridScalingFactory.h" -#include "gpu/core/Kernel/KernelTypes.h" - -#include "gpu/core/GPU/CudaMemoryManager.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -106,14 +105,14 @@ void multipleLevel(const std::string& configPath) vf::basics::ConfigurationFile config; config.load(configPath); - const real reference_diameter = config.getValue<real>("ReferenceDiameter"); - const uint nodes_per_diameter = config.getValue<uint>("NodesPerDiameter"); + const real referenceDiameter = config.getValue<real>("ReferenceDiameter"); + const uint nodesPerDiameter = config.getValue<uint>("NodesPerDiameter"); const real velocity = config.getValue<real>("Velocity"); - const real L_x = 24*reference_diameter; - const real L_y = 6*reference_diameter; - const real L_z = 6*reference_diameter; + const real lengthX = 24*referenceDiameter; + const real lengthY = 6*referenceDiameter; + const real lengthZ = 6*referenceDiameter; const real viscosity = 1.56e-5; @@ -136,26 +135,28 @@ void multipleLevel(const std::string& configPath) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - const real dx = reference_diameter/real(nodes_per_diameter); + const real dx = referenceDiameter/real(nodesPerDiameter); - real turbPos[3] = {3*reference_diameter, 3*reference_diameter, 3*reference_diameter}; + std::vector<real>turbinePositionsX{3.f*referenceDiameter}; + std::vector<real>turbinePositionsY{0.5f*lengthY}; + std::vector<real>turbinePositionsZ{0.5f*lengthY}; auto gridBuilder = std::make_shared<MultipleGridBuilder>(); - gridBuilder->addCoarseGrid(0.0, 0.0, 0.0, - L_x, L_y, L_z, dx); + gridBuilder->addCoarseGrid(0.0, 0.0, 0.0, + lengthX, lengthY, lengthZ, dx); gridBuilder->setNumberOfLayers(4,0); - gridBuilder->addGrid( std::make_shared<Cuboid>( turbPos[0]-1.5*reference_diameter, turbPos[1]-1.5*reference_diameter, turbPos[2]-1.5*reference_diameter, - turbPos[0]+10.0*reference_diameter, turbPos[1]+1.5*reference_diameter, turbPos[2]+1.5*reference_diameter) , 1 ); + gridBuilder->addGrid( std::make_shared<Cuboid>( turbinePositionsX[0]-1.5*referenceDiameter, turbinePositionsY[0]-1.5*referenceDiameter, turbinePositionsZ[0]-1.5*referenceDiameter, + turbinePositionsX[0]+10.0*referenceDiameter, turbinePositionsY[0]+1.5*referenceDiameter, turbinePositionsZ[0]+1.5*referenceDiameter) , 1 ); para->setMaxLevel(2); scalingFactory.setScalingFactory(GridScalingFactory::GridScaling::ScaleCompressible); - gridBuilder->setPeriodicBoundaryCondition(false, false, false); + gridBuilder->setPeriodicBoundaryCondition(false, false, false); - gridBuilder->buildGrids(false); // buildGrids() has to be called before setting the BCs!!!! + gridBuilder->buildGrids(false); // buildGrids() has to be called before setting the BCs!!!! - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const real dt = dx * mach / (sqrt(3) * velocity); @@ -213,28 +214,24 @@ void multipleLevel(const std::string& configPath) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int level = 1; // grid level at which the turbine samples velocities and distributes forces - const real epsilon = dx*exp2(-level)*1.5; // width of gaussian smearing + const real smearingWidth = dx*exp2(-level)*1.5; // width of gaussian smearing const real density = 1.225f; - const uint nBlades = 3; const uint nBladeNodes = 32; - const real tipspeed_ratio = 7.5f; // tipspeed ratio = angular vel * radius / inflow vel - const real omega = 2*tipspeed_ratio*velocity/reference_diameter; - + const real tipspeedRatio = 7.5f; // tipspeed ratio = angular vel * radius / inflow vel + const std::vector<real> rotorSpeeds = {2*tipspeedRatio*velocity/referenceDiameter}; - SPtr<ActuatorFarm> actuator_farm = std::make_shared<ActuatorFarm>(nBlades, density, nBladeNodes, epsilon, level, dt, dx, true); - std::vector<real> bladeRadii; - real dr = reference_diameter/(nBladeNodes*2); - for(uint node=0; node<nBladeNodes; node++){ bladeRadii.emplace_back(dr*(node+1)); } - actuator_farm->addTurbine(turbPos[0], turbPos[1], turbPos[2], reference_diameter, omega, 0, 0, bladeRadii); - para->addActuator( actuator_farm ); + SPtr<ActuatorFarmStandalone> actuatorFarm = std::make_shared<ActuatorFarmStandalone>(referenceDiameter, nBladeNodes, turbinePositionsX, turbinePositionsZ, turbinePositionsZ, rotorSpeeds, density, smearingWidth, level, dt, dx); + actuatorFarm->enableOutput("ALM", uint(tStartOutProbe/dt), uint(tOutProbe/dt)); + para->addActuator( actuatorFarm ); SPtr<PointProbe> pointProbe = std::make_shared<PointProbe>("pointProbe", para->getOutputPath(), 100, 1, 500, 100, false); - std::vector<real> probeCoordsX = {reference_diameter,2*reference_diameter,5*reference_diameter}; - std::vector<real> probeCoordsY = {3*reference_diameter,3*reference_diameter,3*reference_diameter}; - std::vector<real> probeCoordsZ = {3*reference_diameter,3*reference_diameter,3*reference_diameter}; + std::vector<real> probeCoordsX = {referenceDiameter,2*referenceDiameter,5*referenceDiameter}; + std::vector<real> probeCoordsY = {3*referenceDiameter,3*referenceDiameter,3*referenceDiameter}; + std::vector<real> probeCoordsZ = {3*referenceDiameter,3*referenceDiameter,3*referenceDiameter}; pointProbe->addProbePointsFromList(probeCoordsX, probeCoordsY, probeCoordsZ); + // pointProbe->addProbePointsFromXNormalPlane(2*D, 0.0, 0.0, lengthY, lengthZ, (uint)lengthY/dx, (uint)lengthZ/dx); pointProbe->addStatistic(Statistic::Means); pointProbe->addStatistic(Statistic::Variances); @@ -247,7 +244,7 @@ void multipleLevel(const std::string& configPath) para->addProbe( timeseriesProbe ); SPtr<PlaneProbe> planeProbe = std::make_shared<PlaneProbe>("planeProbe", para->getOutputPath(), 100, 500, 100, 100); - planeProbe->setProbePlane(5*reference_diameter, 0, 0, dx, L_y, L_z); + planeProbe->setProbePlane(5*referenceDiameter, 0, 0, dx, lengthY, lengthZ); planeProbe->addStatistic(Statistic::Means); para->addProbe( planeProbe ); diff --git a/apps/gpu/ActuatorLineRegression/ActuatorLineRegression.cpp b/apps/gpu/ActuatorLineRegression/ActuatorLineRegression.cpp index 7ce24bf52373bc742c02de774ad16f7492c5a74a..222b5e3c53f1cd7ea98def212f21c8715e73cbdc 100644 --- a/apps/gpu/ActuatorLineRegression/ActuatorLineRegression.cpp +++ b/apps/gpu/ActuatorLineRegression/ActuatorLineRegression.cpp @@ -71,7 +71,7 @@ #include "gpu/core/DataStructureInitializer/GridReaderFiles/GridReader.h" #include "gpu/core/Parameter/Parameter.h" #include "gpu/core/Output/FileWriter.h" -#include "gpu/core/PreCollisionInteractor/ActuatorFarm.h" +#include "gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmStandalone.h" #include "gpu/core/PreCollisionInteractor/Probes/PointProbe.h" #include "gpu/core/PreCollisionInteractor/Probes/PlaneProbe.h" #include "gpu/core/PreCollisionInteractor/Probes/Probe.h" @@ -107,13 +107,13 @@ void multipleLevel(const std::string& configPath) vf::basics::ConfigurationFile config; config.load(configPath); - const real reference_diameter = config.getValue<real>("ReferenceDiameter"); - const uint nodes_per_diameter = config.getValue<uint>("NodesPerDiameter"); + const real referenceDiameter = config.getValue<real>("ReferenceDiameter"); + const uint nodesPerDiameter = config.getValue<uint>("NodesPerDiameter"); const real velocity = config.getValue<real>("Velocity"); - const real L_x = 10 * reference_diameter; - const real L_y = 4 * reference_diameter; - const real L_z = 4 * reference_diameter; + const real L_x = 10 * referenceDiameter; + const real L_y = 4 * referenceDiameter; + const real L_z = 4 * referenceDiameter; const real viscosity = 1.56e-5; @@ -136,9 +136,11 @@ void multipleLevel(const std::string& configPath) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - const real dx = reference_diameter/real(nodes_per_diameter); + const real dx = referenceDiameter/real(nodesPerDiameter); - real turbPos[3] = {3.0f * reference_diameter, 0.0, 0.0}; + std::vector<real>turbinePositionsX{3.f*referenceDiameter}; + std::vector<real>turbinePositionsY{0.0}; + std::vector<real>turbinePositionsZ{0.0}; auto gridBuilder = std::make_shared<MultipleGridBuilder>(); @@ -207,42 +209,37 @@ void multipleLevel(const std::string& configPath) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int level = 0; // grid level at which the turbine samples velocities and distributes forces - const real smearing_width = dx*exp2(-level)*2; // width of gaussian smearing - VF_LOG_INFO("smearing_width = {}m", smearing_width); + const real smearingWidth = dx*exp2(-level)*2; // width of gaussian smearing + VF_LOG_INFO("smearingWidth = {}m", smearingWidth); const real density = 1.225f; - const uint nBlades = 3; const uint nBladeNodes = 32; - const real tipspeed_ratio = 7.5f; // tipspeed ratio = angular vel * radius / inflow vel - const real rotor_speed = 2*tipspeed_ratio*velocity/reference_diameter; + const real tipspeedRatio = 7.5f; // tipspeed ratio = angular vel * radius / inflow vel + const std::vector<real> rotorSpeeds{2*tipspeedRatio*velocity/referenceDiameter}; - SPtr<ActuatorFarm> actuator_farm = std::make_shared<ActuatorFarm>(nBlades, density, nBladeNodes, smearing_width, level, dt, dx, true); - std::vector<real> bladeRadii; - real dr = reference_diameter/(nBladeNodes*2); - for(uint node=0; node<nBladeNodes; node++){ bladeRadii.emplace_back(dr*(node+1)); } - actuator_farm->addTurbine(turbPos[0], turbPos[1], turbPos[2], reference_diameter, rotor_speed, 0, 0, bladeRadii); - para->addActuator( actuator_farm ); + SPtr<ActuatorFarmStandalone> actuatorFarm = std::make_shared<ActuatorFarmStandalone>(referenceDiameter, nBladeNodes, turbinePositionsX, turbinePositionsY, turbinePositionsZ, rotorSpeeds, density, smearingWidth, level, dt, dx); + para->addActuator( actuatorFarm ); - std::vector<real> planePositions = {-1*reference_diameter, 1*reference_diameter, 3*reference_diameter}; + std::vector<real> planePositions = {-1*referenceDiameter, 1*referenceDiameter, 3*referenceDiameter}; for(int i=0; i < planePositions.size(); i++) { SPtr<PlaneProbe> planeProbe = std::make_shared<PlaneProbe>("planeProbe_" + std::to_string(i), para->getOutputPath(), tStartTmpAveraging/dt, tAveraging/dt, tStartOutProbe/dt, tOutProbe/dt); - planeProbe->setProbePlane(turbPos[0]+planePositions[i], -0.5 * L_y, -0.5 * L_z, dx, L_y, L_z); + planeProbe->setProbePlane(turbinePositionsX[0]+planePositions[i], -0.5 * L_y, -0.5 * L_z, dx, L_y, L_z); planeProbe->addStatistic(Statistic::Means); planeProbe->addStatistic(Statistic::Variances); planeProbe->addStatistic(Statistic::Instantaneous); para->addProbe( planeProbe ); } SPtr<PlaneProbe> planeProbeVert = std::make_shared<PlaneProbe>("planeProbeVertical", para->getOutputPath(), tStartTmpAveraging/dt, tAveraging/dt, tStartOutProbe/dt, tOutProbe/dt); - planeProbeVert->setProbePlane(0, turbPos[1], -0.5 * L_z, L_x, dx, L_z); + planeProbeVert->setProbePlane(0, turbinePositionsY[0], -0.5 * L_z, L_x, dx, L_z); planeProbeVert->addStatistic(Statistic::Means); planeProbeVert->addStatistic(Statistic::Variances); planeProbeVert->addStatistic(Statistic::Instantaneous); para->addProbe( planeProbeVert ); SPtr<PlaneProbe> planeProbeHorz = std::make_shared<PlaneProbe>("planeProbeHorizontal", para->getOutputPath(), tStartTmpAveraging/dt, tAveraging/dt, tStartOutProbe/dt, tOutProbe/dt); - planeProbeHorz->setProbePlane(0, -0.5 * L_y, turbPos[2], L_x, L_y, dx); + planeProbeHorz->setProbePlane(0, -0.5 * L_y, turbinePositionsZ[0], L_x, L_y, dx); planeProbeHorz->addStatistic(Statistic::Means); planeProbeHorz->addStatistic(Statistic::Variances); planeProbeHorz->addStatistic(Statistic::Instantaneous); diff --git a/pythonbindings/CMakeLists.txt b/pythonbindings/CMakeLists.txt index 53700cc8d2769581bcbfbe6e984fb3c90bbd2996..c3cf182cb8fc7ed2859b55ccab0e1c4642ffce9a 100644 --- a/pythonbindings/CMakeLists.txt +++ b/pythonbindings/CMakeLists.txt @@ -41,15 +41,15 @@ target_include_directories(lbm_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/) target_include_directories(lbm_bindings PRIVATE ${CMAKE_BINARY_DIR}) add_dependencies(python_bindings lbm_bindings) -pybind11_add_module(communicator_bindings MODULE src/communicator.cpp) -set_target_properties( communicator_bindings PROPERTIES +pybind11_add_module(parallel_bindings MODULE src/parallel.cpp) +set_target_properties( parallel_bindings PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PYFLUIDS_DIR} - OUTPUT_NAME "communicator") -target_link_libraries(communicator_bindings PRIVATE parallel) -target_include_directories(communicator_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/) -target_include_directories(communicator_bindings PRIVATE ${CMAKE_BINARY_DIR}) -target_compile_definitions(communicator_bindings PRIVATE VF_MPI) -add_dependencies(python_bindings communicator_bindings) + OUTPUT_NAME "parallel") +target_link_libraries(parallel_bindings PRIVATE parallel) +target_include_directories(parallel_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/) +target_include_directories(parallel_bindings PRIVATE ${CMAKE_BINARY_DIR}) +target_compile_definitions(parallel_bindings PRIVATE VF_MPI) +add_dependencies(python_bindings parallel_bindings) IF(BUILD_VF_GPU) @@ -105,5 +105,5 @@ endif() IF(BUILD_VF_GPU) target_compile_definitions(gpu_bindings PRIVATE VF_DOUBLE_ACCURACY) endif() - target_compile_definitions(communicator_bindings PRIVATE VF_DOUBLE_ACCURACY) + target_compile_definitions(parallel_bindings PRIVATE VF_DOUBLE_ACCURACY) endif() \ No newline at end of file diff --git a/pythonbindings/pyfluids-stubs/gpu/__init__.pyi b/pythonbindings/pyfluids-stubs/gpu/__init__.pyi index 8f78fd3387dc59c94ddf2315635e674a7330dae9..31fe74fb1a9d607960d21e7bf5448d95d99d1211 100644 --- a/pythonbindings/pyfluids-stubs/gpu/__init__.pyi +++ b/pythonbindings/pyfluids-stubs/gpu/__init__.pyi @@ -38,10 +38,11 @@ from typing import Callable, ClassVar, List, Optional from typing import overload, Union import numpy as np import numpy.typing as npt -import basics +import basics, parallel from . import grid_generator as grid_generator from . import probes as probes +from . import kernel as kernel class PreCollisionInteractor: def __init__(self, *args, **kwargs) -> None: ... @@ -51,10 +52,8 @@ class FileCollection: def __init__(self, *args, **kwargs) -> None: ... class ActuatorFarm(PreCollisionInteractor): - def __init__(self, number_of_blades_per_turbine: int, density: float, number_of_nodes_per_blade: int, epsilon: float, level: int, delta_t: float, delta_x: float, use_host_arrays: bool) -> None: ... - def add_turbine(self, posX: float, posY: float, posZ: float, diameter: float, omega: float, azimuth: float, yaw: float, bladeRadii: List[float]) -> None: ... - def calc_blade_forces(self) -> None: ... - def get_all_azimuths(self) -> npt.NDArray[np.float32]: ... + def __init__(self, diameter: float, blade_radii: npt.NDArray[np.float32],turbine_positions_x: npt.NDArray[np.float32], turbine_positions_y: npt.NDArray[np.float32], turbine_positions_z: npt.NDArray[np.float32], density: float, smearing_width: float, level: int, delta_t: float, delta_x: float, use_host_arrays: bool) -> None: ... + def update_forces_and_coordinates(self) -> None: ... def get_all_blade_coords_x(self) -> npt.NDArray[np.float32]: ... def get_all_blade_coords_x_device(self) -> int: ... def get_all_blade_coords_y(self) -> npt.NDArray[np.float32]: ... @@ -67,20 +66,15 @@ class ActuatorFarm(PreCollisionInteractor): def get_all_blade_forces_y_device(self) -> int: ... def get_all_blade_forces_z(self) -> npt.NDArray[np.float32]: ... def get_all_blade_forces_z_device(self) -> int: ... - def get_all_blade_radii(self) -> npt.NDArray[np.float32]: ... - def get_all_blade_radii_device(self) -> int: ... def get_all_blade_velocities_x(self) -> npt.NDArray[np.float32]: ... def get_all_blade_velocities_x_device(self) -> int: ... def get_all_blade_velocities_y(self) -> npt.NDArray[np.float32]: ... def get_all_blade_velocities_y_device(self) -> int: ... def get_all_blade_velocities_z(self) -> npt.NDArray[np.float32]: ... def get_all_blade_velocities_z_device(self) -> int: ... - def get_all_omegas(self) -> npt.NDArray[np.float32]: ... def get_all_turbine_pos_x(self) -> npt.NDArray[np.float32]: ... def get_all_turbine_pos_y(self) -> npt.NDArray[np.float32]: ... def get_all_turbine_pos_z(self) -> npt.NDArray[np.float32]: ... - def get_all_yaws(self) -> npt.NDArray[np.float32]: ... - def get_turbine_azimuth(self, turbine: int) -> float: ... def get_turbine_blade_coords_x(self, turbine: int) -> npt.NDArray[np.float32]: ... def get_turbine_blade_coords_x_device(self, turbine: int) -> int: ... def get_turbine_blade_coords_y(self, turbine: int) -> npt.NDArray[np.float32]: ... @@ -93,29 +87,20 @@ class ActuatorFarm(PreCollisionInteractor): def get_turbine_blade_forces_y_device(self, turbine: int) -> int: ... def get_turbine_blade_forces_z(self, turbine: int) -> npt.NDArray[np.float32]: ... def get_turbine_blade_forces_z_device(self, turbine: int) -> int: ... - def get_turbine_blade_radii(self, turbine: int) -> npt.NDArray[np.float32]: ... - def get_turbine_blade_radii_device(self, turbine: int) -> int: ... def get_turbine_blade_velocities_x(self, turbine: int) -> npt.NDArray[np.float32]: ... def get_turbine_blade_velocities_x_device(self, turbine: int) -> int: ... def get_turbine_blade_velocities_y(self, turbine: int) -> npt.NDArray[np.float32]: ... def get_turbine_blade_velocities_y_device(self, turbine: int) -> int: ... def get_turbine_blade_velocities_z(self, turbine: int) -> npt.NDArray[np.float32]: ... def get_turbine_blade_velocities_z_device(self, turbine: int) -> int: ... - def get_turbine_omega(self, turbine: int) -> float: ... - def get_turbine_pos(self, turbine: int) -> npt.NDArray[np.float32]: ... - def get_turbine_yaw(self, turbine: int) -> float: ... - def set_all_azimuths(self, azimuths: npt.NDArray[np.float32]) -> None: ... def set_all_blade_coords(self, blade_coords_x: npt.NDArray[np.float32], blade_coords_y: npt.NDArray[np.float32], blade_coords_z: npt.NDArray[np.float32]) -> None: ... def set_all_blade_forces(self, blade_forces_x: npt.NDArray[np.float32], blade_forces_y: npt.NDArray[np.float32], blade_forces_z: npt.NDArray[np.float32]) -> None: ... def set_all_blade_velocities(self, blade_velocities_x: npt.NDArray[np.float32], blade_velocities_y: npt.NDArray[np.float32], blade_velocities_z: npt.NDArray[np.float32]) -> None: ... - def set_all_omegas(self, omegas: npt.NDArray[np.float32]) -> None: ... - def set_all_yaws(self, yaws: npt.NDArray[np.float32]) -> None: ... - def set_turbine_azimuth(self, turbine: int, azimuth: float) -> None: ... def set_turbine_blade_coords(self, turbine: int, blade_coords_x: npt.NDArray[np.float32], blade_coords_y: npt.NDArray[np.float32], blade_coords_z: npt.NDArray[np.float32]) -> None: ... def set_turbine_blade_forces(self, turbine: int, blade_forces_x: npt.NDArray[np.float32], blade_forces_y: npt.NDArray[np.float32], blade_forces_z: npt.NDArray[np.float32]) -> None: ... def set_turbine_blade_velocities(self, turbine: int, blade_velocities_x: npt.NDArray[np.float32], blade_velocities_y: npt.NDArray[np.float32], blade_velocities_z: npt.NDArray[np.float32]) -> None: ... - def set_turbine_omega(self, turbine: int, omega: float) -> None: ... - def set_turbine_yaw(self, turbine: int, yaw: float) -> None: ... + def set_turbine_azimuth(self, turbine: int, azimuth: float) -> None: ... + def enable_output(self, output_name: str, t_start_out: int, t_out: int) -> None: ... @property def delta_t(self) -> float: ... @property @@ -133,6 +118,8 @@ class ActuatorFarm(PreCollisionInteractor): @property def number_of_turbines(self) -> int: ... +class ActuatorFarmStandalone(ActuatorFarm): + def __init__(self, diameter: float, number_of_nodes_per_blade: int, turbine_positions_x: npt.NDArray[np.float32], turbine_positions_y: npt.NDArray[np.float32], turbine_positions_z: npt.NDArray[np.float32], rotor_speeds: npt.NDArray[np.float32], density: float, smearing_width: float, level: int, delta_t: float, delta_x: float) -> None: ... class BoundaryConditionFactory: def __init__(self) -> None: ... @@ -145,14 +132,6 @@ class BoundaryConditionFactory: def set_velocity_boundary_condition(self, boundary_condition_type: VelocityBC) -> None: ... -class MpiCommunicator: - def __init__(self, *args, **kwargs) -> None: ... - @staticmethod - def get_instance() -> MpiCommunicator: ... - def get_number_of_process(self) -> int: ... - def get_pid(self) -> int: ... - - class CudaMemoryManager: def __init__(self, parameter: Parameter) -> None: ... @@ -176,7 +155,7 @@ class FileType: class GridProvider: def __init__(self, *args, **kwargs) -> None: ... @staticmethod - def make_grid_generator(builder: grid_generator.GridBuilder, para: Parameter, cuda_memory_manager: CudaMemoryManager, communicator: MpiCommunicator) -> GridProvider: ... + def make_grid_generator(builder: grid_generator.GridBuilder, para: Parameter, cuda_memory_manager: CudaMemoryManager, communicator: parallel.Communicator) -> GridProvider: ... class MultipleGridBuilder: def __init__(self) -> None: ... @@ -273,7 +252,7 @@ class Parameter: def set_initial_condition_perturbed_log_law(self, u_star: float, z0: float, length_x: float, length_z: float, height: float, velocity_ratio: float) -> None: ... def set_initial_condition_uniform(self, velocity_x: float, velocity_y: float, velocity_z: float) -> None: ... def set_is_body_force(self, is_body_force: bool) -> None: ... - def set_main_kernel(self, kernel: str) -> None: ... + def configure_main_kernel(self, kernel: str) -> None: ... def set_max_dev(self, max_dev: int) -> None: ... def set_max_level(self, number_of_levels: int) -> None: ... def set_outflow_pressure_correction_factor(self, correction_factor: float) -> None: ... diff --git a/pythonbindings/pyfluids-stubs/gpu/kernel/__init__.pyi b/pythonbindings/pyfluids-stubs/gpu/kernel/__init__.pyi new file mode 100644 index 0000000000000000000000000000000000000000..720d94386904022b45611372179ab4d772ca2ff6 --- /dev/null +++ b/pythonbindings/pyfluids-stubs/gpu/kernel/__init__.pyi @@ -0,0 +1,2 @@ +from . import compressible as compressible +from . import incompressible as incompressible \ No newline at end of file diff --git a/pythonbindings/pyfluids-stubs/gpu/kernel/compressible.pyi b/pythonbindings/pyfluids-stubs/gpu/kernel/compressible.pyi new file mode 100644 index 0000000000000000000000000000000000000000..7462ea0789da29711693df06117f6730586a0f2f --- /dev/null +++ b/pythonbindings/pyfluids-stubs/gpu/kernel/compressible.pyi @@ -0,0 +1,4 @@ +BGK: str +BGKPlus: str +K17CompressibleNavierStokes: str +K15CompressibleNavierStokes: str diff --git a/pythonbindings/pyfluids-stubs/gpu/kernel/incompressible.pyi b/pythonbindings/pyfluids-stubs/gpu/kernel/incompressible.pyi new file mode 100644 index 0000000000000000000000000000000000000000..9ee58b85a548f63c19e87eabb11c98e3e07eb8a4 --- /dev/null +++ b/pythonbindings/pyfluids-stubs/gpu/kernel/incompressible.pyi @@ -0,0 +1,3 @@ +BGK: str +BGKPlus: str +CumulantK15: str \ No newline at end of file diff --git a/pythonbindings/pyfluids-stubs/parallel.pyi b/pythonbindings/pyfluids-stubs/parallel.pyi new file mode 100644 index 0000000000000000000000000000000000000000..a1f420de3d00b0314f22c65e78eb81bc1aed4d54 --- /dev/null +++ b/pythonbindings/pyfluids-stubs/parallel.pyi @@ -0,0 +1,46 @@ +r""" +======================================================================================= + ____ ____ __ ______ __________ __ __ __ __ + \ \ | | | | | _ \ |___ ___| | | | | / \ | | + \ \ | | | | | |_) | | | | | | | / \ | | + \ \ | | | | | _ / | | | | | | / /\ \ | | + \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____ + \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______| + \ \ | | ________________________________________________________________ + \ \ | | | ______________________________________________________________| + \ \| | | | __ __ __ __ ______ _______ + \ | | |_____ | | | | | | | | | _ \ / _____) + \ | | _____| | | | | | | | | | | \ \ \_______ + \ | | | | |_____ | \_/ | | | | |_/ / _____ | + \ _____| |__| |________| \_______/ |__| |______/ (_______/ + + This file is part of VirtualFluids. VirtualFluids 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, either version 3 of + the License, or (at your option) any later version. + + VirtualFluids 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 VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. + +! \file parallel.pyi +! \ingroup bindings +! \author Henry Korb +======================================================================================= +""" + +from __future__ import annotations + +class Communicator: + @staticmethod + def get_instance() -> Communicator: ... + def get_number_of_processes(self) -> int: ... + def get_process_id(self) -> int: ... + +class MPICommunicator(Communicator): + @staticmethod + def get_instance() -> MPICommunicator: ... \ No newline at end of file diff --git a/pythonbindings/pyfluids/__init__.py b/pythonbindings/pyfluids/__init__.py index 5b4197972c0a8738c551e57e635415e3858f53e6..acd2f2605bbba23b64ecb7882c25e369963c7dc1 100644 --- a/pythonbindings/pyfluids/__init__.py +++ b/pythonbindings/pyfluids/__init__.py @@ -31,28 +31,4 @@ r""" ! \ingroup pyfluids ! \author Henry Korb ======================================================================================= -""" -try: - from . import basics -except ImportError: - print("Basics bindings not included") -try: - from . import logger -except ImportError: - print("Logger bindings not included") -try: - from . import lbm -except ImportError: - print("LBM bindings not included") -try: - from . import communicator -except ImportError: - print("communicator bindings not included") -try: - from . import gpu -except ImportError: - print("GPU bindings not included") -try: - from . import cpu -except ImportError: - print("CPU bindings not included") \ No newline at end of file +""" \ No newline at end of file diff --git a/pythonbindings/src/gpu/gpu.cpp b/pythonbindings/src/gpu/gpu.cpp index dcb4ded4b1f0f92748323081b7de9504c2995542..71852487ea3445ee694295dd90c12e3dd2908f3d 100644 --- a/pythonbindings/src/gpu/gpu.cpp +++ b/pythonbindings/src/gpu/gpu.cpp @@ -44,6 +44,7 @@ #include "submodules/transient_bc_setter.cpp" #include "submodules/actuator_farm.cpp" #include "submodules/grid_scaling_factory.cpp" +#include "submodules/kernel.cpp" namespace gpu_bindings { @@ -62,5 +63,6 @@ PYBIND11_MODULE(gpu, m) grid_provider::makeModule(m); turbulence_model::makeModule(m); grid_scaling_factory::makeModule(m); + kernel::makeModule(m); } } // namespace gpu_bindings diff --git a/pythonbindings/src/gpu/submodules/actuator_farm.cpp b/pythonbindings/src/gpu/submodules/actuator_farm.cpp index ee5275483f85559a15aefa769ba30a87af993355..69f44e55e7837e28a100a9e4ccfa6752d72d9a24 100644 --- a/pythonbindings/src/gpu/submodules/actuator_farm.cpp +++ b/pythonbindings/src/gpu/submodules/actuator_farm.cpp @@ -33,7 +33,8 @@ #include <pybind11/pybind11.h> #include <pybind11/numpy.h> -#include <gpu/core/PreCollisionInteractor/ActuatorFarm.h> +#include <gpu/core/PreCollisionInteractor/Actuator/ActuatorFarm.h> +#include <gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmStandalone.h> #include <gpu/core/PreCollisionInteractor/PreCollisionInteractor.h> @@ -41,9 +42,9 @@ class PyActuatorFarm : public ActuatorFarm { public: using ActuatorFarm::ActuatorFarm; // Inherit constructors - void calcBladeForces() override + void updateForcesAndCoordinates() override { - PYBIND11_OVERRIDE_NAME(void, ActuatorFarm, "calc_blade_forces", calcBladeForces); + PYBIND11_OVERRIDE_PURE_NAME(void, ActuatorFarm, "update_forces_and_coordinates", updateForcesAndCoordinates); } }; @@ -62,24 +63,31 @@ namespace actuator_farm using arr = py::array_t<real, py::array::c_style>; py::class_<ActuatorFarm, PreCollisionInteractor, PyActuatorFarm, std::shared_ptr<ActuatorFarm>>(parentModule, "ActuatorFarm", py::dynamic_attr()) - .def(py::init< const uint, + .def(py::init< const real, + const std::vector<real>, + const std::vector<real>, + const std::vector<real>, + const std::vector<real>, const real, - const uint, const real, - int, + const int, const real, const real, const bool>(), - py::arg("number_of_blades_per_turbine"), + py::arg("diameter"), + py::arg("blade_radii"), + py::arg("turbine_positions_x"), + py::arg("turbine_positions_y"), + py::arg("turbine_positions_z"), py::arg("density"), - py::arg("number_of_nodes_per_blade"), - py::arg("epsilon"), + py::arg("smearing_width"), py::arg("level"), py::arg("delta_t"), py::arg("delta_x"), py::arg("use_host_arrays")) - .def_property_readonly("number_of_turbines", &ActuatorFarm::getNumberOfTurbines) .def_property_readonly("number_of_nodes_per_blade", &ActuatorFarm::getNumberOfNodesPerBlade) + .def_property_readonly("number_of_turbines", &ActuatorFarm::getNumberOfTurbines) + .def_property_readonly("number_of_nodes_per_turbine", &ActuatorFarm::getNumberOfNodesPerTurbine) .def_property_readonly("number_of_blades_per_turbine", &ActuatorFarm::getNumberOfBladesPerTurbine) .def_property_readonly("number_of_grid_nodes", &ActuatorFarm::getNumberOfGridNodes) .def_property_readonly("number_of_indices", &ActuatorFarm::getNumberOfIndices) @@ -87,22 +95,13 @@ namespace actuator_farm .def_property_readonly("delta_t", &ActuatorFarm::getDeltaT) .def_property_readonly("delta_x", &ActuatorFarm::getDeltaX) - .def("add_turbine", &ActuatorFarm::addTurbine, py::arg("posX"), py::arg("posY"), py::arg("posZ"), py::arg("diameter"), py::arg("omega"), py::arg("azimuth"), py::arg("yaw"), py::arg("bladeRadii")) - .def("get_turbine_pos", [](ActuatorFarm& al, uint turbine){ real position[3] = {al.getTurbinePosX(turbine), al.getTurbinePosY(turbine), al.getTurbinePosZ(turbine)}; return arr(3, position); }, py::arg("turbine")) - .def("get_turbine_azimuth", &ActuatorFarm::getTurbineAzimuth, py::arg("turbine")) - .def("get_turbine_yaw", &ActuatorFarm::getTurbineYaw, py::arg("turbine")) - .def("get_turbine_omega", &ActuatorFarm::getTurbineOmega, py::arg("turbine")) - .def("get_all_azimuths", [](ActuatorFarm& al){ return arr(al.getNumberOfTurbines(), al.getAllAzimuths()); } ) - .def("get_all_yaws", [](ActuatorFarm& al){ return arr(al.getNumberOfTurbines(), al.getAllYaws()); } ) - .def("get_all_omegas", [](ActuatorFarm& al){ return arr(al.getNumberOfTurbines(), al.getAllOmegas()); } ) .def("get_all_turbine_pos_x", [](ActuatorFarm& al){ return arr(al.getNumberOfTurbines(), al.getAllTurbinePosX()); } ) .def("get_all_turbine_pos_y", [](ActuatorFarm& al){ return arr(al.getNumberOfTurbines(), al.getAllTurbinePosY()); } ) .def("get_all_turbine_pos_z", [](ActuatorFarm& al){ return arr(al.getNumberOfTurbines(), al.getAllTurbinePosZ()); } ) - .def("get_all_blade_radii", [](ActuatorFarm& al){ return arr({al.getNumberOfTurbines(), al.getNumberOfNodesPerBlade()}, al.getAllBladeRadii()); } ) .def("get_all_blade_coords_x", [](ActuatorFarm& al){ return arr({al.getNumberOfTurbines(), al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getAllBladeCoordsX()); } ) .def("get_all_blade_coords_y", [](ActuatorFarm& al){ return arr({al.getNumberOfTurbines(), al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getAllBladeCoordsY()); } ) .def("get_all_blade_coords_z", [](ActuatorFarm& al){ return arr({al.getNumberOfTurbines(), al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getAllBladeCoordsZ()); } ) @@ -113,7 +112,6 @@ namespace actuator_farm .def("get_all_blade_forces_y", [](ActuatorFarm& al){ return arr({al.getNumberOfTurbines(), al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getAllBladeForcesY()); } ) .def("get_all_blade_forces_z", [](ActuatorFarm& al){ return arr({al.getNumberOfTurbines(), al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getAllBladeForcesZ()); } ) - .def("get_turbine_blade_radii", [](ActuatorFarm& al, uint turbine){ return arr(al.getNumberOfNodesPerBlade(), al.getTurbineBladeRadiiDevice(turbine)); } , py::arg("turbine")) .def("get_turbine_blade_coords_x", [](ActuatorFarm& al, uint turbine){ return arr({al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getTurbineBladeCoordsXDevice(turbine)); }, py::arg("turbine") ) .def("get_turbine_blade_coords_y", [](ActuatorFarm& al, uint turbine){ return arr({al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getTurbineBladeCoordsYDevice(turbine)); }, py::arg("turbine") ) .def("get_turbine_blade_coords_z", [](ActuatorFarm& al, uint turbine){ return arr({al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getTurbineBladeCoordsZDevice(turbine)); }, py::arg("turbine") ) @@ -124,7 +122,6 @@ namespace actuator_farm .def("get_turbine_blade_forces_y", [](ActuatorFarm& al, uint turbine){ return arr({al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getTurbineBladeForcesYDevice(turbine)); }, py::arg("turbine") ) .def("get_turbine_blade_forces_z", [](ActuatorFarm& al, uint turbine){ return arr({al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getTurbineBladeForcesZDevice(turbine)); }, py::arg("turbine") ) - .def("get_all_blade_radii_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeRadiiDevice()); } ) .def("get_all_blade_coords_x_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeCoordsXDevice()); } ) .def("get_all_blade_coords_y_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeCoordsYDevice()); } ) .def("get_all_blade_coords_z_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeCoordsZDevice()); } ) @@ -135,7 +132,6 @@ namespace actuator_farm .def("get_all_blade_forces_y_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeForcesYDevice()); } ) .def("get_all_blade_forces_z_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeForcesZDevice()); } ) - .def("get_turbine_blade_radii_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeRadiiDevice(turbine)); }, py::arg("turbine") ) .def("get_turbine_blade_coords_x_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeCoordsXDevice(turbine)); }, py::arg("turbine") ) .def("get_turbine_blade_coords_y_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeCoordsYDevice(turbine)); }, py::arg("turbine") ) .def("get_turbine_blade_coords_z_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeCoordsZDevice(turbine)); }, py::arg("turbine") ) @@ -146,14 +142,6 @@ namespace actuator_farm .def("get_turbine_blade_forces_y_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeForcesYDevice(turbine)); }, py::arg("turbine") ) .def("get_turbine_blade_forces_z_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeForcesZDevice(turbine)); }, py::arg("turbine") ) - .def("set_all_azimuths", [](ActuatorFarm& al, arr azimuths){ al.setAllAzimuths(np_to_arr(azimuths)); }, py::arg("azimuths")) - .def("set_all_yaws", [](ActuatorFarm& al, arr yaws){ al.setAllYaws(np_to_arr(yaws)); }, py::arg("yaws")) - .def("set_all_omegas", [](ActuatorFarm& al, arr omegas){ al.setAllOmegas(np_to_arr(omegas)); }, py::arg("omegas")) - - .def("set_turbine_azimuth", &ActuatorFarm::setTurbineAzimuth, py::arg("turbine"), py::arg("azimuth")) - .def("set_turbine_yaw", &ActuatorFarm::setTurbineYaw, py::arg("turbine"), py::arg("yaw")) - .def("set_turbine_omega", &ActuatorFarm::setTurbineOmega, py::arg("turbine"), py::arg("omega")) - .def("set_all_blade_coords", [](ActuatorFarm& al, arr coordsX, arr coordsY, arr coordsZ){ al.setAllBladeCoords(np_to_arr(coordsX), np_to_arr(coordsY), np_to_arr(coordsZ)); }, py::arg("blade_coords_x"), py::arg("blade_coords_y"), py::arg("blade_coords_z") ) @@ -172,6 +160,34 @@ namespace actuator_farm .def("set_turbine_blade_forces", [](ActuatorFarm& al, uint turbine, arr forcesX, arr forcesY, arr forcesZ){ al.setTurbineBladeForces(turbine, np_to_arr(forcesX), np_to_arr(forcesY), np_to_arr(forcesZ)); }, py::arg("turbine"), py::arg("blade_forces_x"), py::arg("blade_forces_y"), py::arg("blade_forces_z") ) - .def("calc_blade_forces", &ActuatorFarm::calcBladeForces); + .def("update_forces_and_coordinates", &ActuatorFarm::updateForcesAndCoordinates) + .def("enable_output", &ActuatorFarm::enableOutput, py::arg("output_name"), py::arg("t_start_out"), py::arg("t_out")) + .def("set_turbine_azimuth", &ActuatorFarm::setTurbineAzimuth, py::arg("turbine"), py::arg("azimuth")); + + py::class_<ActuatorFarmStandalone, ActuatorFarm, std::shared_ptr<ActuatorFarmStandalone>>(parentModule, "ActuatorFarmStandalone") + .def(py::init< const real, + const uint, + const std::vector<real>, + const std::vector<real>, + const std::vector<real>, + const std::vector<real>, + const real, + const real, + const int, + const real, + const real>(), + py::arg("diameter"), + py::arg("number_of_nodes_per_blade"), + py::arg("turbine_positions_x"), + py::arg("turbine_positions_y"), + py::arg("turbine_positions_z"), + py::arg("rotor_speeds"), + py::arg("density"), + py::arg("smearing_width"), + py::arg("level"), + py::arg("delta_t"), + py::arg("delta_x")); } + + } \ No newline at end of file diff --git a/pythonbindings/src/gpu/submodules/kernel.cpp b/pythonbindings/src/gpu/submodules/kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0cbee2d05616280fea8d3445095f206b6d40752 --- /dev/null +++ b/pythonbindings/src/gpu/submodules/kernel.cpp @@ -0,0 +1,56 @@ +//======================================================================================= +// ____ ____ __ ______ __________ __ __ __ __ +// \ \ | | | | | _ \ |___ ___| | | | | / \ | | +// \ \ | | | | | |_) | | | | | | | / \ | | +// \ \ | | | | | _ / | | | | | | / /\ \ | | +// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____ +// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______| +// \ \ | | ________________________________________________________________ +// \ \ | | | ______________________________________________________________| +// \ \| | | | __ __ __ __ ______ _______ +// \ | | |_____ | | | | | | | | | _ \ / _____) +// \ | | _____| | | | | | | | | | | \ \ \_______ +// \ | | | | |_____ | \_/ | | | | |_/ / _____ | +// \ _____| |__| |________| \_______/ |__| |______/ (_______/ +// +// This file is part of VirtualFluids. VirtualFluids 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, either version 3 of +// the License, or (at your option) any later version. +// +// VirtualFluids 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 VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file kernel.cpp +//! \ingroup submodules +//! \author Henry Korb +//======================================================================================= +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> +#include <gpu/core/Kernel/KernelTypes.h> + +namespace kernel +{ + namespace py = pybind11; + + void makeModule(py::module_ &parentModule) + { + auto kernel_module = parentModule.def_submodule("Kernel", "Kernel types"); + auto compressible = kernel_module.def_submodule("compressible", "Compressible Kernel types"); + auto incompressible = kernel_module.def_submodule("incompressible", "Incompressible Kernel types"); + + compressible.attr("BGK") = vf::collisionKernel::compressible::BGK; + compressible.attr("BGKPlus") = vf::collisionKernel::compressible::BGKPlus; + compressible.attr("K17CompressibleNavierStokes") = vf::collisionKernel::compressible::K17CompressibleNavierStokes; + compressible.attr("K15CompressibleNavierStokes") = vf::collisionKernel::compressible::K15CompressibleNavierStokes; + + incompressible.attr("BGK") = vf::collisionKernel::incompressible::BGK; + incompressible.attr("BGKPlus") = vf::collisionKernel::incompressible::BGKPlus; + incompressible.attr("CumulantK15") = vf::collisionKernel::incompressible::CumulantK15; + } +} diff --git a/pythonbindings/src/gpu/submodules/parameter.cpp b/pythonbindings/src/gpu/submodules/parameter.cpp index 6b9d57a715eb309295f6537daaccf56ff5397384..167ae0a3f2f2e061847d546e506fb3502c44e63e 100644 --- a/pythonbindings/src/gpu/submodules/parameter.cpp +++ b/pythonbindings/src/gpu/submodules/parameter.cpp @@ -83,7 +83,7 @@ namespace parameter .def("set_max_dev", &Parameter::setMaxDev, py::arg("max_dev")) .def("set_is_body_force", &Parameter::setIsBodyForce, py::arg("is_body_force")) .def("set_use_streams", &Parameter::setUseStreams, py::arg("use_streams")) - .def("set_main_kernel", &Parameter::configureMainKernel, py::arg("kernel")) + .def("configure_main_kernel", &Parameter::configureMainKernel, py::arg("kernel")) .def("set_AD_kernel", &Parameter::setADKernel, py::arg("ad_kernel")) .def("set_has_wall_model_monitor", &Parameter::setHasWallModelMonitor, py::arg("has_wall_monitor")) .def("set_outflow_pressure_correction_factor", &Parameter::setOutflowPressureCorrectionFactor, py::arg("correction_factor")) diff --git a/pythonbindings/src/communicator.cpp b/pythonbindings/src/parallel.cpp similarity index 75% rename from pythonbindings/src/communicator.cpp rename to pythonbindings/src/parallel.cpp index cf5157fe497ac9c08183f4c5092a150f517670b4..9eac1b60b21a8b89522e404858e18379b6045b58 100644 --- a/pythonbindings/src/communicator.cpp +++ b/pythonbindings/src/parallel.cpp @@ -33,17 +33,21 @@ #include <pybind11/cast.h> #include <pybind11/pybind11.h> +#include <parallel/Communicator.h> #include <parallel/MPICommunicator.h> -namespace communicator_bindings +namespace parallel { - namespace py = pybind11; +namespace py = pybind11; - PYBIND11_MODULE(communicator, m) - { - py::class_<vf::parallel::MPICommunicator, std::shared_ptr<vf::parallel::MPICommunicator>>(m, "Communicator") - .def_static("get_instance", &vf::parallel::MPICommunicator::getInstance) - .def("get_number_of_processes", &vf::parallel::MPICommunicator::getNumberOfProcesses) - .def("get_process_id", py::overload_cast<>(&vf::parallel::MPICommunicator::getProcessID, py::const_)); - } -} // namespace communicator_bindings +PYBIND11_MODULE(parallel, m) +{ +py::class_<vf::parallel::Communicator, std::shared_ptr<vf::parallel::Communicator>>(m, "Communicator") + .def_static("get_instance", &vf::parallel::Communicator::getInstance) + .def("get_process_id", py::overload_cast<>(&vf::parallel::Communicator::getProcessID, py::const_)) + .def("get_number_of_processes", &vf::parallel::Communicator::getNumberOfProcesses); + + py::class_<vf::parallel::MPICommunicator, vf::parallel::Communicator, std::shared_ptr<vf::parallel::MPICommunicator>>(m, "MPICommunicator") + .def_static("get_instance", &vf::parallel::MPICommunicator::getInstance); +} +} // namespace parallel diff --git a/src/basics/CMakeLists.txt b/src/basics/CMakeLists.txt index 8ef4841bf640f156f8f2573f286e7613ea3c0941..760d0f8260e1126b4cbe8933eda2780d43f36665 100644 --- a/src/basics/CMakeLists.txt +++ b/src/basics/CMakeLists.txt @@ -1,7 +1,7 @@ include(buildInfo.cmake) -vf_add_library(PUBLIC_LINK logger MPI::MPI_CXX EXCLUDE buildInfo.in.cpp) +vf_add_library(PUBLIC_LINK logger PRIVATE_LINK parallel EXCLUDE buildInfo.in.cpp) vf_get_library_name (library_name) target_include_directories(${library_name} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/geometry3d) @@ -26,3 +26,8 @@ if(BUILD_USE_BOOST) endif() vf_add_tests() + +# TODO: https://git.rz.tu-bs.de/irmb/VirtualFluids_dev/-/issues/139 +# if(BUILD_USE_MPI) + target_link_libraries(${library_name} PRIVATE MPI::MPI_CXX) +# endif() \ No newline at end of file diff --git a/src/basics/geometry3d/GbVoxelMatrix3D.cpp b/src/basics/geometry3d/GbVoxelMatrix3D.cpp index 130eaf655c3fb42544d71508a16b6b9212039df7..7ddba99294f68aa5594ca4dfe035815d947c2eb4 100644 --- a/src/basics/geometry3d/GbVoxelMatrix3D.cpp +++ b/src/basics/geometry3d/GbVoxelMatrix3D.cpp @@ -41,10 +41,6 @@ #include <basics/utilities/UbSystem.h> #include "basics/constants/NumericConstants.h" -#ifdef MC_CUBES -#include <MarchingCubes/MarchingCubes.h> -#endif // MC_CUBES - using namespace std; const float GbVoxelMatrix3D::SOLID = 1.0f; @@ -323,45 +319,9 @@ bool GbVoxelMatrix3D::isCellInsideOrCuttingGbObject3D(const double &x1a, const d vector<GbTriangle3D *> GbVoxelMatrix3D::getSurfaceTriangleSet() { vector<GbTriangle3D *> triangles; - -#ifdef MC_CUBES - // MC - typedef McCubes::Matrix3DWrapper<Matrix3D> McMatrixWrapper; - typedef McCubes::MarchingCubes<McMatrixWrapper> McMarchingCubesGenerator; - typedef McMarchingCubesGenerator::Vertex McVertex; - typedef McMarchingCubesGenerator::Triangle McTriangle; - - McMatrixWrapper wrapper( - &voxelMatrix); //,0,0,0,voxelMatrix.getNX1()-1,voxelMatrix.getNX2()-1,voxelMatrix.getNX3()-1); - McMarchingCubesGenerator mc(wrapper); - - mc.init_all(); - mc.run(0.5); - - // const int nofVertices = mc.nverts(); - const int nofTriangles = mc.ntrigs(); - - McVertex *mcvertices = mc.vertices(); - McTriangle *mctriangles = mc.triangles(); - - for (int t = 0; t < nofTriangles; t++) { - triangles.push_back( - new GbTriangle3D(new GbPoint3D(minX1 + deltaX1 * (mcvertices[mctriangles[t].v1].x /*-1*/), - minX2 + deltaX2 * (mcvertices[mctriangles[t].v1].y /*-1*/), - minX3 + deltaX3 * (mcvertices[mctriangles[t].v1].z /*-1*/)), - new GbPoint3D(minX1 + deltaX1 * (mcvertices[mctriangles[t].v2].x /*-1*/), - minX2 + deltaX2 * (mcvertices[mctriangles[t].v2].y /*-1*/), - minX3 + deltaX3 * (mcvertices[mctriangles[t].v2].z /*-1*/)), - new GbPoint3D(minX1 + deltaX1 * (mcvertices[mctriangles[t].v3].x /*-1*/), - minX2 + deltaX2 * (mcvertices[mctriangles[t].v3].y /*-1*/), - minX3 + deltaX3 * (mcvertices[mctriangles[t].v3].z /*-1*/)))); - } -#else cerr << "vector<GbTriangle3D*> GbVoxelMatrix3D::getSurfaceTriangleSet() - benoetigt MARCHING_CUBE paket aus 3rdParty" << endl; -#endif // MC_CUBES - return triangles; } /*=======================================================*/ @@ -372,111 +332,8 @@ void GbVoxelMatrix3D::addSurfaceTriangleSet(vector<UbTupleFloat3> & /*nodes*/, v UBLOG(logINFO, " GbVoxelMatrix3D addSurfaceTriangleSet end without TriangleSetCreation") return; } -#ifdef MC_CUBES - UBLOG(logDEBUG1, " GbVoxelMatrix3D addSurfaceTriangleSet MC defined") - - typedef McCubes::Matrix3DWrapper<Matrix3D> McMatrixWrapper; - typedef McCubes::MarchingCubes<McMatrixWrapper> McMarchingCubesGenerator; - typedef McMarchingCubesGenerator::Vertex McVertex; - typedef McMarchingCubesGenerator::Triangle McTriangle; - - // MC - { // standard( fuer voxelmatrix) - McMatrixWrapper wrapper(&voxelMatrix); - McMarchingCubesGenerator mc(wrapper); - - UBLOG(logDEBUG1, " GbVoxelMatrix3D addSurfaceTriangleSet McMarchingCubesGenerator") - - UBLOG(logDEBUG1, " GbVoxelMatrix3D addSurfaceTriangleSet mc.init") - mc.init_all(); - UBLOG(logDEBUG1, " GbVoxelMatrix3D addSurfaceTriangleSet mc.run") - mc.run(0.5); - UBLOG(logDEBUG1, " GbVoxelMatrix3D addSurfaceTriangleSet mc.run done") - - const int nofVertices = mc.nverts(); - const int nofTriangles = mc.ntrigs(); - - McVertex *mcvertices = mc.vertices(); - McTriangle *mctriangles = mc.triangles(); - - UBLOG(logDEBUG1, " GbVoxelMatrix3D node tuple") - for (int n = 0; n < nofVertices; n++) - nodes.push_back(makeUbTuple( - (float)(minX1 + deltaX1 * (mcvertices[n].x /*-1*/)), // Anm: kein -1, da man durch manipulation der - // indices die dreiecke um eins versetzt bekommt - (float)(minX2 + deltaX2 * (mcvertices[n].y /*-1*/)), - (float)(minX3 + deltaX3 * (mcvertices[n].z /*-1*/)))); - UBLOG(logDEBUG1, " GbVoxelMatrix3D triangles tuple") - for (int t = 0; t < nofTriangles; t++) - triangles.push_back(makeUbTuple(mctriangles[t].v1, mctriangles[t].v2, mctriangles[t].v3)); - UBLOG(logDEBUG1, " GbVoxelMatrix3D triangles tuple done") - } - // false - das scheint probleme bei der asphaltprobe zu machen 1500x600x100 - // da lief es bis C - evtl. memory voll - if (false) // extension... um die raender koerrekt abzubilden muesste man eine dummy FLUID reihe um - { // die matrix legen( lsg1: temp matrix mit 2 reihen pro richtung mehr -> zuviel speicher, 500^3 = 500MB - // lsg2: fuer jede flaeche eine dummy matrix -> wie folgt: - int nx1 = (int)voxelMatrix.getNX1(); - int nx2 = (int)voxelMatrix.getNX2(); - int nx3 = (int)voxelMatrix.getNX3(); - UBLOG(logINFO, " A ") - Matrix3D tmpX1Min(2, nx2 + 2, nx3 + 2, FLUID); - Matrix3D tmpX1Max(2, nx2 + 2, nx3 + 2, FLUID); - for (int x3 = 0; x3 < nx3; x3++) - for (int x2 = 0; x2 < nx2; x2++) { - tmpX1Min(1, x2 + 1, x3 + 1) = voxelMatrix(0, x2, x3); - tmpX1Max(0, x2 + 1, x3 + 1) = voxelMatrix(nx1 - 1, x2, x3); - } - UBLOG(logINFO, " B") - Matrix3D tmpX2Min(nx1 + 2, 2, nx3 + 2, FLUID); - Matrix3D tmpX2Max(nx1 + 2, 2, nx3 + 2, FLUID); - for (int x3 = 0; x3 < nx3; x3++) - for (int x1 = 0; x1 < nx1; x1++) { - tmpX2Min(x1 + 1, 1, x3 + 1) = voxelMatrix(x1, 0, x3); - tmpX2Max(x1 + 1, 0, x3 + 1) = voxelMatrix(x1, nx2 - 1, x3); - } - UBLOG(logINFO, " C ") - Matrix3D tmpX3Min(nx1 + 2, nx3 + 2, 2, FLUID); - Matrix3D tmpX3Max(nx1 + 2, nx3 + 2, 2, FLUID); - for (int x2 = 0; x2 < nx2; x2++) - for (int x1 = 0; x1 < nx1; x1++) { - tmpX3Min(x1 + 1, x2 + 1, 1) = voxelMatrix(x1, x2, 0); - tmpX3Max(x1 + 1, x2 + 1, 0) = voxelMatrix(x1, x2, nx3 - 1); - } - UBLOG(logINFO, " D") - Matrix3D *matrices[] = { &tmpX1Min, &tmpX1Max, &tmpX2Min, &tmpX2Max, &tmpX3Min, &tmpX3Max }; - int dx1[] = { -1, nx1 - 1, -1, -1, -1, -1 }; - int dx2[] = { -1, -1, -1, nx2 - 1, -1, -1 }; - int dx3[] = { -1, -1, -1, -1, -1, nx3 - 1 }; - UBLOG(logINFO, " E") - for (int i = 0; i < 6; i++) { - McMatrixWrapper wrapper(matrices[i]); - McMarchingCubesGenerator mc(wrapper); - - mc.init_all(); - mc.run(0.5); - - McVertex *mcvertices = mc.vertices(); - McTriangle *mctriangles = mc.triangles(); - - int deltaNodeNr = (int)nodes.size(); - UBLOG(logINFO, " GbVoxelMatrix3D node tuple") - for (int n = 0; n < mc.nverts(); n++) - nodes.push_back( - makeUbTuple((float)(minX1 + deltaX1 * (mcvertices[n].x + - dx1[i])), // Anm: kein -1, da man durch manipulation der - // indices die dreiecke um eins versetzt bekommt - (float)(minX2 + deltaX2 * (mcvertices[n].y + dx2[i])), - (float)(minX3 + deltaX3 * (mcvertices[n].z + dx3[i])))); - for (int t = 0; t < mc.ntrigs(); t++) - triangles.push_back(makeUbTuple(deltaNodeNr + mctriangles[t].v1, deltaNodeNr + mctriangles[t].v2, - deltaNodeNr + mctriangles[t].v3)); - } - } -#else cerr << "void GbVoxelMatrix3D.addSurfaceTriangleSet - benoetigt MARCHING_CUBE paket aus 3rdParty" << endl; -#endif // MC_CUBES UBLOG(logINFO, " GbVoxelMatrix3D addSurfaceTriangleSet end") } diff --git a/src/basics/parallel/PbMpi.h b/src/basics/parallel/PbMpi.h deleted file mode 100644 index 7f73da85b4ee333a3f266ea8fc082fc5d88f1b40..0000000000000000000000000000000000000000 --- a/src/basics/parallel/PbMpi.h +++ /dev/null @@ -1,503 +0,0 @@ -//======================================================================================= -// ____ ____ __ ______ __________ __ __ __ __ -// \ \ | | | | | _ \ |___ ___| | | | | / \ | | -// \ \ | | | | | |_) | | | | | | | / \ | | -// \ \ | | | | | _ / | | | | | | / /\ \ | | -// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____ -// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______| -// \ \ | | ________________________________________________________________ -// \ \ | | | ______________________________________________________________| -// \ \| | | | __ __ __ __ ______ _______ -// \ | | |_____ | | | | | | | | | _ \ / _____) -// \ | | _____| | | | | | | | | | | \ \ \_______ -// \ | | | | |_____ | \_/ | | | | |_/ / _____ | -// \ _____| |__| |________| \_______/ |__| |______/ (_______/ -// -// This file is part of VirtualFluids. VirtualFluids 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, either version 3 of -// the License, or (at your option) any later version. -// -// VirtualFluids 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 VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file PbMpi.h -//! \ingroup parallel -//! \author Soeren Freudiger, Sebastian Geller -//======================================================================================= -#ifndef PbMpi_H -#define PbMpi_H - -#include <sstream> -#include <vector> - -#ifndef VF_MPI -#error VF_MPI has to be defined -#endif - -// As we doing a lot of const-cast here we define PbMpi.h to system_header to mute clang-tidy -#ifdef __clang__ -#pragma clang system_header -#endif - -//#undef SEEK_SET -//#undef SEEK_CUR -//#undef SEEK_END -#include <mpi.h> - -#include <basics/utilities/UbException.h> - -#ifdef USE_MPI_CXX_SYNTAX -#define PbMpi_COMM_WORLD MPI::COMM_WORLD -#define PbMpi_INT MPI::INT -#define PbMpi_CHAR MPI::CHAR -#define PbMpi_SHORT MPI::SHORT -#define PbMpi_FLOAT MPI::FLOAT -#define PbMpi_DOUBLE MPI::DOUBLE -#define PbMpi_COMM_NULL MPI::COMM_NULL - -namespace PbMpi -{ -typedef MPI::Intracomm Comm; -typedef MPI::Group Group; -typedef MPI::Request Request; -typedef MPI::Status Status; - -inline void Init() -{ - MPI::Init(); - MPI::COMM_WORLD.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS); -} -inline void Init(int &argc, char **argv) -{ - MPI::Init(argc, argv); - MPI::COMM_WORLD.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS); -} -inline void Finalize() { MPI::Finalize(); } - -inline int GetCommSize(const Comm &comm) { return comm.Get_size(); } -inline int GetCommRank(const Comm &comm) { return comm.Get_rank(); } -inline void Barrier(const Comm &comm) { comm.Barrier(); } - -inline double Wtime() { return MPI::Wtime(); } -inline double Wtick() { return MPI::Wtick(); } - -inline void Wait(Request &request, Status *outStatus = NULL) -{ - if (outStatus) - request.Wait(*outStatus); - else - request.Wait(); -} - -inline Group GetCommGroup(Comm &comm) { return comm.Get_group(); } -inline Group GetGroupIncl(Group &group, const int &n, int *ranks) { return group.Incl(n, ranks); } -inline Comm CommCreateComm(Comm &comm, Group &group) { return comm.Create(group); } - -inline void Alltoall(Comm &comm, void *sendBuffer, const int &sn, const MPI_Datatype &sdatatype, void *recvBuffer, - const int &rn, const MPI_Datatype &rdatatype) -{ - comm.Alltoall(sendBuffer, sn, sdatatype, recvBuffer, rn, rdatatype); -} -inline void Bcast(Comm &comm, void *data, const int &n, const MPI_Datatype &datatype, const int &srcRank) -{ - comm.Bcast(data, n, datatype, srcRank); -} -inline void Send(Comm &comm, const void *data, const int &length, const MPI_Datatype &dataType, const int &destRank, - const int &tag) -{ - try { - comm.Send(data, length, dataType, destRank, tag); - } catch (MPI::Exception &e) { - std::stringstream ss; - ss << "MPI::Exception error_string=" << e.Get_error_string() << std::endl; - throw UbException(UB_EXARGS, "MPI:Exception catched\n" + ss.str()); - } catch (...) { - throw UbException(UB_EXARGS, "unknown exception"); - } -} -inline void Recv(Comm &comm, const void *data, const int &length, const MPI_Datatype &dataType, const int &srcRank, - const int &tag) -{ - try { - comm.Recv(const_cast<void *>(data), length, dataType, srcRank, tag); - } catch (MPI::Exception &e) { - std::stringstream ss; - ss << "MPI::Exception error_string=" << e.Get_error_string() << std::endl; - throw UbException(UB_EXARGS, "MPI:Exception catched \n" + ss.str()); - } catch (...) { - throw UbException(UB_EXARGS, "unknown exception"); - } -} - -inline void Irecv(Comm comm, const void *data, const int &length, const MPI_Datatype &dataType, const int &srcRank, - const int &tag, Request &outRequest) -{ - outRequest = comm.Irecv(const_cast<void *>(data), length, dataType, srcRank, tag); -} -inline void Ssend(Comm &comm, const void *data, const int &length, const MPI_Datatype &dataType, const int &destRank, - const int &tag) -{ - try { - comm.Ssend(data, length, dataType, destRank, tag); - } catch (MPI::Exception &e) { - std::stringstream ss; - ss << "MPI::Exception error_string=" << e.Get_error_string() << std::endl; - throw UbException(UB_EXARGS, "MPI:Exception catched\n" + ss.str()); - } catch (...) { - throw UbException(UB_EXARGS, "unknown exception"); - } -} - -} // namespace PbMpi -#else ////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -// C-Syntax -////////////////////////////////////////////////////////////////////////// -namespace PbMpi -{ -using Comm = MPI_Comm; -using Group = MPI_Group; -using Request = MPI_Request; -using Status = MPI_Status; -} // namespace PbMpi - -#define PbMpi_COMM_WORLD ((PbMpi::Comm)MPI_COMM_WORLD) -#define PbMpi_INT MPI_INT -#define PbMpi_CHAR MPI_CHAR -#define PbMpi_SHORT MPI_SHORT -#define PbMpi_FLOAT MPI_FLOAT -#define PbMpi_DOUBLE MPI_DOUBLE -#define PbMpi_COMM_NULL MPI_COMM_NULL - -namespace PbMpi -{ -inline void Init() -{ - int argc = 1; - char **argv = new char *[1]; - argv[0] = new char[1]; - argv[0][0] = 'n'; - MPI_Init(&argc, &argv); -} -inline void Init(int &argc, char **argv) { MPI_Init(&argc, &argv); } -inline void Finalize() { MPI_Finalize(); } -inline int GetCommSize(Comm comm) -{ - int tmp; - MPI_Comm_size(comm, &tmp); - return tmp; -} -inline int GetCommRank(Comm comm) -{ - int tmp; - MPI_Comm_rank(comm, &tmp); - return tmp; -} -inline void Barrier(Comm comm) { MPI_Barrier(comm); } -inline double Wtime() { return MPI_Wtime(); } -inline double Wtick() { return MPI_Wtick(); } -inline void Wait(Request &request, Status *outStatus = NULL) { MPI_Wait(&request, outStatus); } - -inline Group GetCommGroup(Comm comm) -{ - Group out; - MPI_Comm_group(comm, &out); - return out; -} -inline Group GetGroupIncl(Group group, const int &n, int *ranks) -{ - Group out; - MPI_Group_incl(group, n, ranks, &out); - return out; -} -inline Comm CommCreateComm(Comm comm, Group &group) -{ - Comm out; - MPI_Comm_create(comm, group, &out); - return out; -} - -inline void Alltoall(Comm comm, void *sendBuffer, const int &sn, const MPI_Datatype &sdatatype, void *recvBuffer, - const int &rn, const MPI_Datatype &rdatatype) -{ - MPI_Alltoall(sendBuffer, sn, sdatatype, recvBuffer, rn, rdatatype, comm); -} -inline void Bcast(Comm comm, void *data, const int &n, const MPI_Datatype &datatype, const int &srcRank) -{ - MPI_Bcast(data, n, datatype, srcRank, comm); -} -inline void Send(Comm comm, const void *data, const int &length, const MPI_Datatype &dataType, const int &destRank, - const int &tag) -{ - MPI_Send(const_cast<void *>(data), length, dataType, destRank, tag, comm); -} -inline void Recv(Comm comm, const void *data, const int &length, const MPI_Datatype &dataType, const int &srcRank, - const int &tag) -{ - MPI_Recv(const_cast<void *>(data), length, dataType, srcRank, tag, comm, MPI_STATUS_IGNORE); -} -inline void Ssend(Comm comm, const void *data, const int &length, const MPI_Datatype &dataType, const int &destRank, - const int &tag) -{ - MPI_Ssend(const_cast<void *>(data), length, dataType, destRank, tag, comm); -} -inline void Irecv(Comm comm, const void *data, const int &length, const MPI_Datatype &dataType, const int &srcRank, - const int &tag, Request &outRequest) -{ - MPI_Irecv(const_cast<void *>(data), length, dataType, srcRank, tag, comm, &outRequest); -} - -} // namespace PbMpi -#endif - -namespace PbMpi -{ -/*======================================================================*/ -// send a single value "value" of MPI_Datatype -template <class T> -inline void sendSingleValue(const T &value, MPI_Datatype datatype, int dest, int tag, PbMpi::Comm comm); - -/*======================================================================*/ -// receives a single value "value" of MPI_Datatype -template <class T> -inline void receiveSingleValue(T &value, MPI_Datatype datatype, int source, int tag, PbMpi::Comm comm); - -/*======================================================================*/ -// receives and returns a single value of MPI_Datatype -// expample: int value = PbMpi::receiveSingleValue<int>(MPI::INT,0,10,comm); -template <class T> -inline T receiveSingleValue(MPI_Datatype datatype, int source, int tag, PbMpi::Comm comm); - -/*======================================================================*/ -// sends bool value (doesn't work with template, why ever... stupid MPI) -inline void sendBoolValue(const bool &value, int dest, int tag, PbMpi::Comm comm); - -/*======================================================================*/ -// receives bool value (doesn't work with template, why ever... stupid MPI) -inline bool receiveBoolValue(int source, int tag, PbMpi::Comm comm); - -/*======================================================================*/ -// sends bool value (doesn't work with template, why ever... stupid MPI) -inline void sendStringValue(const std::string &value, int dest, int tag, PbMpi::Comm comm); - -/*======================================================================*/ -// receives bool value (doesn't work with template, why ever... stupid MPI) -inline std::string receiveStringValue(int source, int tag, PbMpi::Comm comm); - -/*======================================================================*/ -// send a vector of MPI_Datatype -template <class T> -inline void sendVector(const std::vector<T> &v, MPI_Datatype datatype, int dest, int tag, PbMpi::Comm comm); - -/*======================================================================*/ -// receive a std::vector of MPI_Datatype -template <class T> -inline void receiveVector(std::vector<T> &v, MPI_Datatype datatype, int source, int tag, PbMpi::Comm comm); - -/*======================================================================*/ -// receive a vector of MPI_Datatype and adds this vector to existing vector -// ans returns number of received elements -template <class T> -inline int receiveVectorAndAddToVector(std::vector<T> &v, MPI_Datatype datatype, int source, int tag, PbMpi::Comm comm); - -/*======================================================================*/ -// send a std::vector of strings -inline void sendStringVector(const std::vector<std::string> &v, int dest, int tag, PbMpi::Comm comm); - -/*======================================================================*/ -// send a vector of strings -inline void receiveStringVector(std::vector<std::string> &v, int dest, int tag, PbMpi::Comm comm); -} // namespace PbMpi - -/*======================================================================*/ -// send a single value of MPI_Datatype -template <class T> -void PbMpi::sendSingleValue(const T &value, MPI_Datatype datatype, int dest, int tag, PbMpi::Comm comm) -{ - PbMpi::Send(comm, &value, 1, datatype, dest, tag); - // comm.Send(&value, 1, datatype, dest, tag); -} -/*======================================================================*/ -template <class T> -void PbMpi::receiveSingleValue(T &value, MPI_Datatype datatype, int source, int tag, PbMpi::Comm comm) -{ - PbMpi::Recv(comm, &value, 1, datatype, source, tag); - // comm.Recv(&value, 1, datatype, source, tag); -} -/*======================================================================*/ -template <class T> -T PbMpi::receiveSingleValue(MPI_Datatype datatype, int source, int tag, PbMpi::Comm comm) -{ - T value; - PbMpi::Recv(comm, &value, 1, datatype, source, tag); - // comm.Recv(&value, 1, datatype, source, tag); - - return value; -} -/*======================================================================*/ -// send a bool value (bool doesn't work with template, why ever) -void PbMpi::sendBoolValue(const bool &value, int dest, int tag, PbMpi::Comm comm) -{ - short dummy; - if (value) - dummy = 1; - else - dummy = 0; - - PbMpi::Send(comm, &dummy, 1, PbMpi_SHORT, dest, tag); - // comm.Send(&dummy, 1, MPI::SHORT, dest, tag); -} -/*======================================================================*/ -bool PbMpi::receiveBoolValue(int source, int tag, PbMpi::Comm comm) -{ - short dummy{ 0 }; - PbMpi::Recv(comm, &dummy, 1, PbMpi_SHORT, source, tag); - // comm.Recv(&dummy, 1, MPI::SHORT, source, tag); - - return (dummy == 1); -} -/*======================================================================*/ -// sends bool value (doesn't work with template, why ever... stupid MPI) -void PbMpi::sendStringValue(const std::string &value, int dest, int tag, PbMpi::Comm comm) -{ - std::vector<char> vec; - for (char i : value) - vec.push_back(i); - - PbMpi::sendVector(vec, PbMpi_CHAR, dest, tag, comm); -} - -/*======================================================================*/ -// receives bool value (doesn't work with template, why ever... stupid MPI) -std::string PbMpi::receiveStringValue(int source, int tag, PbMpi::Comm comm) -{ - std::vector<char> vec; - PbMpi::receiveVector(vec, PbMpi_CHAR, source, tag, comm); - - std::string str; - for (char i : vec) - str += i; - - return str; -} -/*======================================================================*/ -// send a vector of MPI_Datatype -template <class T> -void PbMpi::sendVector(const std::vector<T> &v, MPI_Datatype datatype, int dest, int tag, PbMpi::Comm comm) -{ - // send size - int size = (int)v.size(); - - PbMpi::Send(comm, &size, 1, PbMpi_INT, dest, tag); - // comm.Send(&size, 1, MPI::INT, dest, tag); - - if (size > 0) { - PbMpi::Send(comm, &v[0], size, datatype, dest, tag); - // comm.Send(&v[0], size, datatype, dest, tag); - } -} -/*======================================================================*/ -// receive a vector of MPI_Datatype -template <class T> -void PbMpi::receiveVector(std::vector<T> &v, MPI_Datatype datatype, int source, int tag, PbMpi::Comm comm) -{ - int size{ 0 }; - - PbMpi::Recv(comm, &size, 1, PbMpi_INT, source, tag); - // comm.Recv(&size, 1, MPI::INT, source, tag); - - v.resize(size); - - if (size > 0) { - PbMpi::Recv(comm, &v[0], size, datatype, source, tag); - // comm.Recv(&v[0], size, datatype, source, tag); - } -} -/*======================================================================*/ -// receive a vector of MPI_Datatype and adds this vector to existing vector -// return value is size of received elements -template <class T> -int PbMpi::receiveVectorAndAddToVector(std::vector<T> &v, MPI_Datatype datatype, int source, int tag, PbMpi::Comm comm) -{ - int incommingSize; - - PbMpi::Recv(comm, &incommingSize, 1, PbMpi_INT, source, tag); - // comm.Recv(&incommingSize, 1, MPI::INT, source, tag); - - int oldSize = (int)v.size(); - v.resize(oldSize + incommingSize); - - if (incommingSize > 0) { - PbMpi::Recv(comm, &v[oldSize], incommingSize, datatype, source, tag); - // comm.Recv(&v[oldSize], incommingSize, datatype, source, tag); - } - - return incommingSize; -} -/*======================================================================*/ -// send a vector of strings -void PbMpi::sendStringVector(const std::vector<std::string> &v, int dest, int tag, PbMpi::Comm comm) -{ - // send size - int stringVectorSize = (int)v.size(); - - PbMpi::Send(comm, &stringVectorSize, 1, PbMpi_INT, dest, tag); - // comm.Send(&stringVectorSize, 1, MPI::INT, dest, tag); - - if (stringVectorSize > 0) { - std::vector<int> singleStringSizes(stringVectorSize + 1); - int nofChars = 0; - for (int i = 0; i < stringVectorSize; i++) - nofChars += singleStringSizes[i] = (int)v[i].length(); - singleStringSizes[stringVectorSize] = nofChars; - - PbMpi::Send(comm, &singleStringSizes[0], stringVectorSize + 1, PbMpi_INT, dest, tag); - - std::vector<char> charVector(nofChars); - int pos = 0; - for (int i = 0; i < stringVectorSize; i++) - for (int j = 0; j < singleStringSizes[i]; j++) - charVector[pos++] = v[i][j]; - - PbMpi::Send(comm, &charVector[0], nofChars, PbMpi_CHAR, dest, tag); - // comm.Send(&charVector[0], nofChars, MPI::CHAR, dest, tag); - } -} -/*======================================================================*/ -// send a vector of strings -void PbMpi::receiveStringVector(std::vector<std::string> &v, int source, int tag, PbMpi::Comm comm) -{ - // send size - int stringVectorSize{ 0 }; - PbMpi::Recv(comm, &stringVectorSize, 1, PbMpi_INT, source, tag); - // comm.Recv(&stringVectorSize, 1, MPI::INT, source, tag); - - v.clear(); - v.resize(stringVectorSize); - - if (stringVectorSize > 0) { - std::vector<int> singleStringSizes(stringVectorSize + 1); - - PbMpi::Recv(comm, &singleStringSizes[0], stringVectorSize + 1, PbMpi_INT, source, tag); - // comm.Recv(&singleStringSizes[0], stringVectorSize+1, MPI::INT, source, tag); - - int nofChars = singleStringSizes[stringVectorSize]; - std::vector<char> charVector(nofChars); - - PbMpi::Recv(comm, &charVector[0], nofChars, PbMpi_CHAR, source, tag); - // comm.Recv(&charVector[0], nofChars, MPI::CHAR, source, tag); - - int pos = 0; - for (int i = 0; i < stringVectorSize; i++) - for (int j = 0; j < singleStringSizes[i]; j++) - v[i].push_back(charVector[pos++]); - } -} - -#endif // PbMpi_H diff --git a/src/basics/utilities/UbTiming.h b/src/basics/utilities/UbTiming.h index a99c4ec39acfa64c99bb2a61a8ceec4fc8ba604a..9ea6ed16fc3b547bb20e34cc0e5c1e080e09cc6f 100644 --- a/src/basics/utilities/UbTiming.h +++ b/src/basics/utilities/UbTiming.h @@ -40,10 +40,9 @@ #include <string> #include <vector> -#ifdef VF_MPI -#include <basics/parallel/PbMpi.h> -#include <mpi.h> -#endif // VF_MPI +#if defined(VF_MPI) +#include <parallel/Communicator.h> +#endif class UbTiming { @@ -70,8 +69,8 @@ public: /*==========================================================*/ virtual void startTiming() { -#if defined(VF_MPI) && !defined(CAB_RUBY) - this->startTime = PbMpi::Wtime(); +#if defined(VF_MPI) + this->startTime = vf::parallel::Communicator::getInstance()->Wtime(); #else this->startTime = (double)clock(); #endif // VF_MPI @@ -87,8 +86,8 @@ public: /*==========================================================*/ virtual void stopTiming() { -#if defined(VF_MPI) && !defined(CAB_RUBY) - this->deltaT = PbMpi::Wtime() - this->startTime; +#if defined(VF_MPI) + this->deltaT = vf::parallel::Communicator::getInstance()->Wtime() - this->startTime; #else this->deltaT = ((double)clock() - this->startTime) / (double)CLOCKS_PER_SEC; #endif // VF_MPI @@ -106,8 +105,8 @@ public: { this->duration = 0.0; -#if defined(VF_MPI) && !defined(CAB_RUBY) - this->startTime = PbMpi::Wtime(); +#if defined(VF_MPI) + this->startTime = vf::parallel::Communicator::getInstance()->Wtime(); #else this->startTime = (double)clock(); #endif // VF_MPI @@ -115,8 +114,8 @@ public: /*==========================================================*/ void pause() { -#if defined(VF_MPI) && !defined(CAB_RUBY) - this->duration += PbMpi::Wtime() - this->startTime; +#if defined(VF_MPI) + this->duration += vf::parallel::Communicator::getInstance()->Wtime() - this->startTime; #else this->duration += ((double)clock() - this->startTime) / (double)CLOCKS_PER_SEC; #endif // VF_MPI @@ -124,8 +123,8 @@ public: /*==========================================================*/ void unpause() { -#if defined(VF_MPI) && !defined(CAB_RUBY) - this->startTime = PbMpi::Wtime(); +#if defined(VF_MPI) + this->startTime = vf::parallel::Communicator::getInstance()->Wtime(); #else this->startTime = (double)clock(); #endif // VF_MPI @@ -133,19 +132,10 @@ public: /*==========================================================*/ void stop() { -#if defined(VF_MPI) && !defined(CAB_RUBY) - this->duration += PbMpi::Wtime() - this->startTime; +#if defined(VF_MPI) + this->duration += vf::parallel::Communicator::getInstance()->Wtime() - this->startTime; #else this->duration += ((double)clock() - this->startTime) / (double)CLOCKS_PER_SEC; -#endif // VF_MPI - } - /*==========================================================*/ - double getTicks() const - { -#if defined(VF_MPI) && !defined(CAB_RUBY) - return PbMpi::Wtick(); -#else - return double(1.0) / double(CLOCKS_PER_SEC); #endif // VF_MPI } @@ -226,8 +216,8 @@ public: { this->isMeasuring = true; -#if defined(VF_MPI) && !defined(CAB_RUBY) - this->startTime = PbMpi::Wtime(); +#if defined(VF_MPI) + this->startTime = vf::parallel::Communicator::getInstance()->Wtime(); #elif defined(UBSYSTEM_APPLE) this->startTime = mach_absolute_time(); #elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_AIX) @@ -253,8 +243,8 @@ public: if (!isMeasuring) return 0.0; -#if defined(VF_MPI) && !defined(CAB_RUBY) - double actTime = PbMpi::Wtime(); +#if defined(VF_MPI) + double actTime = vf::parallel::Communicator::getInstance()->Wtime(); this->lapTime = actTime - this->startTime; #elif defined(UBSYSTEM_APPLE) double actTime = mach_absolute_time(); @@ -296,8 +286,8 @@ public: if (!isMeasuring) return 0.0; -#if defined(VF_MPI) && !defined(CAB_RUBY) - return PbMpi::Wtime() - this->startTime; +#if defined(VF_MPI) + return vf::parallel::Communicator::getInstance()->Wtime() - this->startTime; #elif defined(UBSYSTEM_APPLE) timespec tp; mach_absolute_difference(mach_absolute_time(), this->startTime, &tp); diff --git a/src/cpu/core/CMakeLists.txt b/src/cpu/core/CMakeLists.txt index ee8f4ed209673acfc4bbfbd8bff39379e28d5255..4a596797e30f7bcad82f6054558f92e60857fe58 100644 --- a/src/cpu/core/CMakeLists.txt +++ b/src/cpu/core/CMakeLists.txt @@ -48,3 +48,9 @@ IF(${VFCPU_USE_VTK}) target_include_directories(${library_name} PRIVATE ${VTK_INCLUDE_DIRS}) ENDIF() +# TODO: https://git.rz.tu-bs.de/irmb/VirtualFluids_dev/-/issues/139 +# if(BUILD_USE_MPI) + target_link_libraries(${library_name} PRIVATE MPI::MPI_CXX) +# endif() + + diff --git a/src/gpu/core/CMakeLists.txt b/src/gpu/core/CMakeLists.txt index 52c0ba96d4ac37f0ae9f6af76537155d5b24a063..c3e38fd157a18ea889716ff66d469986f606dbd3 100644 --- a/src/gpu/core/CMakeLists.txt +++ b/src/gpu/core/CMakeLists.txt @@ -28,5 +28,5 @@ if(BUILD_VF_UNIT_TESTS) set_source_files_properties(LBM/GPUHelperFunctions/KernelUtilitiesTests.cpp PROPERTIES LANGUAGE CUDA) set_source_files_properties(Output/DistributionDebugWriterTest.cpp PROPERTIES LANGUAGE CUDA) set_source_files_properties(Parameter/ParameterTest.cpp PROPERTIES LANGUAGE CUDA) - set_source_files_properties(PreCollisionInteractor/ActuatorFarmInlinesTest.cpp PROPERTIES LANGUAGE CUDA) + set_source_files_properties(PreCollisionInteractor/Actuator/ActuatorFarmInlinesTest.cpp PROPERTIES LANGUAGE CUDA) endif() diff --git a/src/gpu/core/GPU/CudaMemoryManager.cpp b/src/gpu/core/GPU/CudaMemoryManager.cpp index a6adb34c165019372512873d153f45681c01ea11..450e1faaef6ff08b6fd07a1f58d4112e5ebff9cb 100644 --- a/src/gpu/core/GPU/CudaMemoryManager.cpp +++ b/src/gpu/core/GPU/CudaMemoryManager.cpp @@ -7,7 +7,7 @@ #include <Parameter/Parameter.h> #include "Parameter/CudaStreamManager.h" -#include "PreCollisionInteractor/ActuatorFarm.h" +#include "PreCollisionInteractor/Actuator/ActuatorFarm.h" #include "PreCollisionInteractor/Probes/Probe.h" #include <PreCollisionInteractor/PrecursorWriter.h> @@ -2911,26 +2911,20 @@ void CudaMemoryManager::cudaFreeTaggedFluidNodeIndices(CollisionTemplate tag, in /////////////////////////////////////////////////////////////////////////////// void CudaMemoryManager::cudaAllocBladeGeometries(ActuatorFarm* actuatorFarm) { - uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNumberOfTurbines(); - checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeRadiiH, sizeRealTurbine*actuatorFarm->getNumberOfNodesPerBlade()) ); - checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->diametersH, sizeRealTurbine) ); + const uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNumberOfTurbines(); checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->turbinePosXH, sizeRealTurbine) ); checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->turbinePosYH, sizeRealTurbine) ); checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->turbinePosZH, sizeRealTurbine) ); - checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeRadiiD, sizeRealTurbine*actuatorFarm->getNumberOfNodesPerBlade()) ); - checkCudaErrors( cudaMalloc((void**) &actuatorFarm->diametersD, sizeRealTurbine) ); checkCudaErrors( cudaMalloc((void**) &actuatorFarm->turbinePosXD, sizeRealTurbine) ); checkCudaErrors( cudaMalloc((void**) &actuatorFarm->turbinePosYD, sizeRealTurbine) ); checkCudaErrors( cudaMalloc((void**) &actuatorFarm->turbinePosZD, sizeRealTurbine) ); - setMemsizeGPU(sizeof(real)*(actuatorFarm->getNumberOfNodesPerBlade()+4)*actuatorFarm->getNumberOfTurbines(), false); + setMemsizeGPU(sizeof(real)*4.f*actuatorFarm->getNumberOfTurbines(), false); } void CudaMemoryManager::cudaCopyBladeGeometriesHtoD(ActuatorFarm* actuatorFarm) { - uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNumberOfTurbines(); - checkCudaErrors( cudaMemcpy(actuatorFarm->bladeRadiiD, actuatorFarm->bladeRadiiH, sizeRealTurbine*actuatorFarm->getNumberOfNodesPerBlade(), cudaMemcpyHostToDevice) ); - checkCudaErrors( cudaMemcpy(actuatorFarm->diametersD, actuatorFarm->diametersH, sizeRealTurbine, cudaMemcpyHostToDevice) ); + const uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNumberOfTurbines(); checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosXD, actuatorFarm->turbinePosXH, sizeRealTurbine, cudaMemcpyHostToDevice) ); checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosYD, actuatorFarm->turbinePosYH, sizeRealTurbine, cudaMemcpyHostToDevice) ); checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosZD, actuatorFarm->turbinePosZH, sizeRealTurbine, cudaMemcpyHostToDevice) ); @@ -2939,8 +2933,6 @@ void CudaMemoryManager::cudaCopyBladeGeometriesHtoD(ActuatorFarm* actuatorFarm) void CudaMemoryManager::cudaCopyBladeGeometriesDtoH(ActuatorFarm* actuatorFarm) { uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNumberOfTurbines(); - checkCudaErrors( cudaMemcpy(actuatorFarm->bladeRadiiH, actuatorFarm->bladeRadiiD, sizeRealTurbine*actuatorFarm->getNumberOfNodesPerBlade(), cudaMemcpyDeviceToHost) ); - checkCudaErrors( cudaMemcpy(actuatorFarm->diametersH, actuatorFarm->diametersD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosXH, actuatorFarm->turbinePosXD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosYH, actuatorFarm->turbinePosYD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosZH, actuatorFarm->turbinePosZD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); @@ -2948,59 +2940,15 @@ void CudaMemoryManager::cudaCopyBladeGeometriesDtoH(ActuatorFarm* actuatorFarm) } void CudaMemoryManager::cudaFreeBladeGeometries(ActuatorFarm* actuatorFarm) { - checkCudaErrors( cudaFree(actuatorFarm->bladeRadiiD) ); - checkCudaErrors( cudaFree(actuatorFarm->diametersD) ); checkCudaErrors( cudaFree(actuatorFarm->turbinePosXD) ); checkCudaErrors( cudaFree(actuatorFarm->turbinePosYD) ); checkCudaErrors( cudaFree(actuatorFarm->turbinePosZD) ); - checkCudaErrors( cudaFreeHost(actuatorFarm->bladeRadiiH) ); - checkCudaErrors( cudaFreeHost(actuatorFarm->diametersH) ); checkCudaErrors( cudaFreeHost(actuatorFarm->turbinePosXH) ); checkCudaErrors( cudaFreeHost(actuatorFarm->turbinePosYH) ); checkCudaErrors( cudaFreeHost(actuatorFarm->turbinePosZH) ); } -void CudaMemoryManager::cudaAllocBladeOrientations(ActuatorFarm* actuatorFarm) -{ - uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNumberOfTurbines(); - checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->omegasH, sizeRealTurbine) ); - checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->azimuthsH, sizeRealTurbine) ); - checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->yawsH, sizeRealTurbine) ); - - checkCudaErrors( cudaMalloc((void**) &actuatorFarm->omegasD, sizeRealTurbine) ); - checkCudaErrors( cudaMalloc((void**) &actuatorFarm->azimuthsD, sizeRealTurbine) ); - checkCudaErrors( cudaMalloc((void**) &actuatorFarm->yawsD, sizeRealTurbine) ); - - setMemsizeGPU(3*sizeRealTurbine, false); - -} -void CudaMemoryManager::cudaCopyBladeOrientationsHtoD(ActuatorFarm* actuatorFarm) -{ - uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNumberOfTurbines(); - checkCudaErrors( cudaMemcpy(actuatorFarm->omegasD, actuatorFarm->omegasH, sizeRealTurbine, cudaMemcpyHostToDevice) ); - checkCudaErrors( cudaMemcpy(actuatorFarm->azimuthsD, actuatorFarm->azimuthsH, sizeRealTurbine, cudaMemcpyHostToDevice) ); - checkCudaErrors( cudaMemcpy(actuatorFarm->yawsD, actuatorFarm->yawsH, sizeRealTurbine, cudaMemcpyHostToDevice) ); - -} -void CudaMemoryManager::cudaCopyBladeOrientationsDtoH(ActuatorFarm* actuatorFarm) -{ - uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNumberOfTurbines(); - checkCudaErrors( cudaMemcpy(actuatorFarm->omegasH, actuatorFarm->omegasD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); - checkCudaErrors( cudaMemcpy(actuatorFarm->azimuthsH, actuatorFarm->azimuthsD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); - checkCudaErrors( cudaMemcpy(actuatorFarm->yawsH, actuatorFarm->yawsD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); -} -void CudaMemoryManager::cudaFreeBladeOrientations(ActuatorFarm* actuatorFarm) -{ - checkCudaErrors( cudaFree((void**) &actuatorFarm->omegasD) ); - checkCudaErrors( cudaFree((void**) &actuatorFarm->azimuthsD) ); - checkCudaErrors( cudaFree((void**) &actuatorFarm->yawsD) ); - - checkCudaErrors( cudaFreeHost((void**) &actuatorFarm->omegasH) ); - checkCudaErrors( cudaFreeHost((void**) &actuatorFarm->azimuthsH) ); - checkCudaErrors( cudaFreeHost((void**) &actuatorFarm->yawsH) ); -} - void CudaMemoryManager::cudaAllocBladeCoords(ActuatorFarm* actuatorFarm) { checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeCoordsXH, sizeof(real)*actuatorFarm->getNumberOfGridNodes()) ); diff --git a/src/gpu/core/GPU/GeometryUtils.h b/src/gpu/core/GPU/GeometryUtils.h index 37fe00b6b67e1376e79500f4430db47736f18c46..688f11134108f5b00ff6287fddbbef1f49db20b3 100644 --- a/src/gpu/core/GPU/GeometryUtils.h +++ b/src/gpu/core/GPU/GeometryUtils.h @@ -5,7 +5,7 @@ __inline__ __host__ __device__ void getNeighborIndicesOfBSW( uint k, //index of dMMM node uint &ke, uint &kn, uint &kt, uint &kne, uint &kte,uint &ktn, uint &ktne, - uint* neighborX, uint* neighborY, uint* neighborZ) + const uint* neighborX, const uint* neighborY, const uint* neighborZ) { ke = neighborX[k]; kn = neighborY[k]; @@ -16,10 +16,10 @@ __inline__ __host__ __device__ void getNeighborIndicesOfBSW( uint k, //index of ktne = neighborX[ktn]; } -__inline__ __host__ __device__ uint findNearestCellBSW(uint index, - real* coordsX, real* coordsY, real* coordsZ, - real posX, real posY, real posZ, - uint* neighborsX, uint* neighborsY, uint* neighborsZ, uint* neighborsWSB) +__inline__ __host__ __device__ uint findNearestCellBSW(const uint index, + const real* coordsX, const real* coordsY, const real* coordsZ, + const real posX, const real posY, const real posZ, + const uint* neighborsX, const uint* neighborsY, const uint* neighborsZ, const uint* neighborsWSB) { uint new_index = index; @@ -53,7 +53,7 @@ __inline__ __host__ __device__ void getInterpolationWeights(real &dW, real &dE, __inline__ __host__ __device__ real trilinearInterpolation( real dW, real dE, real dN, real dS, real dT, real dB, uint k, uint ke, uint kn, uint kt, uint kne, uint kte, uint ktn, uint ktne, - real* quantity ) + const real* quantity ) { return ( dE*dN*dT*quantity[k] + dW*dN*dT*quantity[ke] + dE*dS*dT*quantity[kn] + dW*dS*dT*quantity[kne] diff --git a/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarm.cu b/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarm.cu new file mode 100644 index 0000000000000000000000000000000000000000..ee72fb189c6a7a41b3cdd991599e9485f60682cc --- /dev/null +++ b/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarm.cu @@ -0,0 +1,467 @@ +//======================================================================================= +// ____ ____ __ ______ __________ __ __ __ __ +// \ \ | | | | | _ \ |___ ___| | | | | / \ | | +// \ \ | | | | | |_) | | | | | | | / \ | | +// \ \ | | | | | _ / | | | | | | / /\ \ | | +// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____ +// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______| +// \ \ | | ________________________________________________________________ +// \ \ | | | ______________________________________________________________| +// \ \| | | | __ __ __ __ ______ _______ +// \ | | |_____ | | | | | | | | | _ \ / _____) +// \ | | _____| | | | | | | | | | | \ \ \_______ +// \ | | | | |_____ | \_/ | | | | |_/ / _____ | +// \ _____| |__| |________| \_______/ |__| |______/ (_______/ +// +// This file is part of VirtualFluids. VirtualFluids 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, either version 3 of +// the License, or (at your option) any later version. +// +// VirtualFluids 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 VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file ActuatorFarm.cu +//! \ingroup PreCollisionInteractor +//! \author Henrik Asmuth, Henry Korb +//====================================================================================== +#include "ActuatorFarm.h" +#include "ActuatorFarmInlines.h" + +#include <cuda.h> +#include <cuda_runtime.h> +#include <helper_cuda.h> + +#include <basics/constants/NumericConstants.h> +#include <basics/writer/WbWriterVtkXmlBinary.h> +#include <cuda_helper/CudaGrid.h> +#include <logger/Logger.h> + +#include "DataStructureInitializer/GridProvider.h" +#include "GPU/CudaMemoryManager.h" +#include "GPU/GeometryUtils.h" +#include "LBM/GPUHelperFunctions/KernelUtilities.h" +#include "Parameter/CudaStreamManager.h" +#include "Parameter/Parameter.h" + +using namespace vf::basics::constant; + +struct GridData +{ + const uint* indices; + const uint nIndices; + const real *coordsX, *coordsY, *coordsZ; + const uint *neighborsX, *neighborsY, *neighborsZ, *neighborsWSB; + const real *vx, *vy, *vz; + real *fx, *fy, *fz; + const real inverseDeltaX, velocityRatio; +}; + +struct TurbineData +{ + const real *posX, *posY, *posZ; + const uint numberOfTurbines; + const real smearingWidth, factorGaussian; +}; + +struct ComponentData +{ + const real referenceLength; + const uint numberOfNodesPerTurbine; + const real *coordsX, *coordsY, *coordsZ; + real *velocitiesX, *velocitiesY, *velocitiesZ; + const real *forcesX, *forcesY, *forcesZ; + uint* gridIndices; +}; + +__global__ void interpolateVelocities(const GridData gridData, const TurbineData turbineData, ComponentData componentData) +{ + const unsigned nodeIndex = vf::gpu::getNodeIndex(); + + if (nodeIndex >= componentData.numberOfNodesPerTurbine * turbineData.numberOfTurbines) + return; + + const real coordX = componentData.coordsX[nodeIndex]; + const real coordY = componentData.coordsY[nodeIndex]; + const real coordZ = componentData.coordsZ[nodeIndex]; + + uint k, ke, kn, kt; + uint kne, kte, ktn, ktne; + + k = findNearestCellBSW(componentData.gridIndices[nodeIndex], + gridData.coordsX, gridData.coordsY, gridData.coordsZ, + coordX, coordY, coordZ, + gridData.neighborsX, gridData.neighborsY, gridData.neighborsZ, gridData.neighborsWSB); + + componentData.gridIndices[nodeIndex] = k; + + getNeighborIndicesOfBSW(k, ke, kn, kt, kne, kte, ktn, ktne, gridData.neighborsX, gridData.neighborsY, + gridData.neighborsZ); + + real dW, dE, dN, dS, dT, dB; + + const real distX = gridData.inverseDeltaX * (coordX - gridData.coordsX[k]); + const real distY = gridData.inverseDeltaX * (coordY - gridData.coordsY[k]); + const real distZ = gridData.inverseDeltaX * (coordZ - gridData.coordsZ[k]); + + getInterpolationWeights(dW, dE, dN, dS, dT, dB, distX, distY, distZ); + + componentData.velocitiesX[nodeIndex] = + trilinearInterpolation(dW, dE, dN, dS, dT, dB, k, ke, kn, kt, kne, kte, ktn, ktne, gridData.vx) * + gridData.velocityRatio; + componentData.velocitiesY[nodeIndex] = + trilinearInterpolation(dW, dE, dN, dS, dT, dB, k, ke, kn, kt, kne, kte, ktn, ktne, gridData.vy) * + gridData.velocityRatio; + componentData.velocitiesZ[nodeIndex] = + trilinearInterpolation(dW, dE, dN, dS, dT, dB, k, ke, kn, kt, kne, kte, ktn, ktne, gridData.vz) * + gridData.velocityRatio; +} + +__global__ void applyBodyForces(GridData gridData, const TurbineData turbineData, const ComponentData componentData) +{ + + const uint index = vf::gpu::getNodeIndex(); + + if (index >= gridData.nIndices) + return; + + const uint gridIndex = gridData.indices[index]; + const real gridCoordX = gridData.coordsX[gridIndex]; + const real gridCoordY = gridData.coordsY[gridIndex]; + const real gridCoordZ = gridData.coordsZ[gridIndex]; + + real gridForceX = c0o1; + real gridForceY = c0o1; + real gridForceZ = c0o1; + + for (uint turbine = 0; turbine < turbineData.numberOfTurbines; turbine++) { + const real distToHubX = gridCoordX - turbineData.posX[turbine]; + const real distToHubY = gridCoordY - turbineData.posY[turbine]; + const real distToHubZ = gridCoordZ - turbineData.posZ[turbine]; + + if (!inBoundingSphere(distToHubX, distToHubY, distToHubZ, componentData.referenceLength, turbineData.smearingWidth)) + continue; + + for (uint turbineNode = 0; turbineNode < componentData.numberOfNodesPerTurbine; turbineNode++) { + const uint node = turbine * componentData.numberOfNodesPerTurbine + turbineNode; + + const real distX = componentData.coordsX[node] - gridCoordX; + const real distY = componentData.coordsY[node] - gridCoordY; + const real distZ = componentData.coordsZ[node] - gridCoordZ; + + const real eta = gaussianSmearing(distX, distY, distZ, turbineData.smearingWidth, turbineData.factorGaussian); + gridForceX += componentData.forcesX[node] * eta; + gridForceY += componentData.forcesY[node] * eta; + gridForceZ += componentData.forcesZ[node] * eta; + } + } + gridData.fx[gridIndex] += gridForceX; + gridData.fy[gridIndex] += gridForceY; + gridData.fz[gridIndex] += gridForceZ; +} + +void ActuatorFarm::init(Parameter* para, GridProvider* gridProvider, CudaMemoryManager* cudaManager) +{ + if (!para->getIsBodyForce()) + throw std::runtime_error("try to allocate ActuatorFarm but BodyForce is not set in Parameter."); + this->forceRatio = para->getForceRatio(); + this->initTurbineGeometries(cudaManager); + this->initBladeCoords(cudaManager); + this->initBladeIndices(cudaManager); + this->initBladeVelocities(cudaManager); + this->initBladeForces(cudaManager); + this->initBoundingSpheres(para, cudaManager); + this->streamIndex = para->getStreamManager()->registerAndLaunchStream(CudaStreamIndex::ActuatorFarm); +} + +void ActuatorFarm::interact(Parameter* para, CudaMemoryManager* cudaManager, int level, unsigned int t) +{ + if (level != this->level) + return; + + cudaStream_t stream = para->getStreamManager()->getStream(CudaStreamIndex::ActuatorFarm, this->streamIndex); + + if (useHostArrays) + cudaManager->cudaCopyBladeCoordsHtoD(this); + + if (this->writeOutput && ((t - this->tStartOut) % this->tOut == 0)) { + if (!useHostArrays) { + cudaManager->cudaCopyBladeCoordsDtoH(this); + cudaManager->cudaCopyBladeVelocitiesDtoH(this); + cudaManager->cudaCopyBladeForcesDtoH(this); + } + this->write(this->getFilename(para, t)); + } + + const GridData gridData { + this->boundingSphereIndicesD, this->numberOfIndices, + para->getParD(this->level)->coordinateX, para->getParD(this->level)->coordinateY, para->getParD(this->level)->coordinateZ, + para->getParD(this->level)->neighborX, para->getParD(this->level)->neighborY, para->getParD(this->level)->neighborZ, para->getParD(this->level)->neighborInverse, + para->getParD(this->level)->velocityX, para->getParD(this->level)->velocityY, para->getParD(this->level)->velocityZ, + para->getParD(this->level)->forceX_SP,para->getParD(this->level)->forceY_SP,para->getParD(this->level)->forceZ_SP, + this->invDeltaX, para->getVelocityRatio()}; + + const TurbineData turbineData { + this->turbinePosXD, this->turbinePosYD, this->turbinePosZD, + this->numberOfTurbines, + this->smearingWidth, this->factorGaussian}; + + const ComponentData bladeData { + this->diameter, this->numberOfNodesPerTurbine, + this->bladeCoordsXDCurrentTimestep, this->bladeCoordsYDCurrentTimestep, this->bladeCoordsZDCurrentTimestep, + this->bladeVelocitiesXDCurrentTimestep, this->bladeVelocitiesYDCurrentTimestep, this->bladeVelocitiesZDCurrentTimestep, + this->bladeForcesXDCurrentTimestep, this->bladeForcesYDCurrentTimestep, this->bladeForcesZDCurrentTimestep, + this->bladeIndicesD}; + + vf::cuda::CudaGrid bladeGrid = vf::cuda::CudaGrid(para->getParH(level)->numberofthreads, this->numberOfGridNodes); + interpolateVelocities<<<bladeGrid.grid, bladeGrid.threads, 0, stream>>>(gridData, turbineData, bladeData); + cudaStreamSynchronize(stream); + + if (useHostArrays) + cudaManager->cudaCopyBladeVelocitiesDtoH(this); + + this->updateForcesAndCoordinates(); + this->swapDeviceArrays(); + + if (useHostArrays) + cudaManager->cudaCopyBladeForcesHtoD(this); + + vf::cuda::CudaGrid sphereGrid = vf::cuda::CudaGrid(para->getParH(level)->numberofthreads, this->numberOfIndices); + + applyBodyForces<<<sphereGrid.grid, sphereGrid.threads, 0, stream>>>(gridData, turbineData, bladeData); + cudaStreamSynchronize(stream); +} + +void ActuatorFarm::free(Parameter* para, CudaMemoryManager* cudaManager) +{ + cudaManager->cudaFreeBladeGeometries(this); + cudaManager->cudaFreeBladeCoords(this); + cudaManager->cudaFreeBladeVelocities(this); + cudaManager->cudaFreeBladeForces(this); + cudaManager->cudaFreeBladeIndices(this); + cudaManager->cudaFreeSphereIndices(this); +} + +void ActuatorFarm::getTaggedFluidNodes(Parameter* para, GridProvider* gridProvider) +{ + std::vector<uint> indicesInSphere(this->boundingSphereIndicesH, this->boundingSphereIndicesH + this->numberOfIndices); + gridProvider->tagFluidNodeIndices(indicesInSphere, CollisionTemplate::AllFeatures, this->level); +} + +void ActuatorFarm::initTurbineGeometries(CudaMemoryManager* cudaManager) +{ + this->numberOfGridNodes = this->numberOfTurbines * this->numberOfNodesPerTurbine; + + cudaManager->cudaAllocBladeGeometries(this); + + std::copy(initialTurbinePositionsX.begin(), initialTurbinePositionsX.end(), turbinePosXH); + std::copy(initialTurbinePositionsY.begin(), initialTurbinePositionsY.end(), turbinePosYH); + std::copy(initialTurbinePositionsZ.begin(), initialTurbinePositionsZ.end(), turbinePosZH); + + cudaManager->cudaCopyBladeGeometriesHtoD(this); + + this->factorGaussian = pow(this->smearingWidth * sqrt(cPi), -c3o1) / this->forceRatio; +} + +void ActuatorFarm::initBladeCoords(CudaMemoryManager* cudaManager) +{ + cudaManager->cudaAllocBladeCoords(this); + + for (uint turbine = 0; turbine < this->numberOfTurbines; turbine++) { + for (uint blade = 0; blade < ActuatorFarm::numberOfBlades; blade++) { + const real local_azimuth = this->azimuths[turbine] + blade * c2Pi / ActuatorFarm::numberOfBlades; + + for (uint bladeNode = 0; bladeNode < this->numberOfNodesPerBlade; bladeNode++) { + const uint node = calcNodeIndexInBladeArrays({ turbine, blade, bladeNode }, this->numberOfNodesPerBlade, + ActuatorFarm::numberOfBlades); + + real x, y, z; + rotateFromBladeToGlobal(c0o1, c0o1, this->bladeRadii[bladeNode], x, y, z, local_azimuth); + bladeCoordsXH[node] = x + this->turbinePosXH[turbine]; + bladeCoordsYH[node] = y + this->turbinePosYH[turbine]; + bladeCoordsZH[node] = z + this->turbinePosZH[turbine]; + } + } + } + cudaManager->cudaCopyBladeCoordsHtoD(this); + swapArrays(this->bladeCoordsXDCurrentTimestep, this->bladeCoordsXDPreviousTimestep); + swapArrays(this->bladeCoordsYDCurrentTimestep, this->bladeCoordsYDPreviousTimestep); + swapArrays(this->bladeCoordsZDCurrentTimestep, this->bladeCoordsZDPreviousTimestep); + cudaManager->cudaCopyBladeCoordsHtoD(this); +} + +void ActuatorFarm::initBladeVelocities(CudaMemoryManager* cudaManager) +{ + cudaManager->cudaAllocBladeVelocities(this); + + std::fill_n(this->bladeVelocitiesXH, this->numberOfGridNodes, c0o1); + std::fill_n(this->bladeVelocitiesYH, this->numberOfGridNodes, c0o1); + std::fill_n(this->bladeVelocitiesZH, this->numberOfGridNodes, c0o1); + + cudaManager->cudaCopyBladeVelocitiesHtoD(this); + swapArrays(this->bladeVelocitiesXDCurrentTimestep, this->bladeVelocitiesXDPreviousTimestep); + swapArrays(this->bladeVelocitiesYDCurrentTimestep, this->bladeVelocitiesYDPreviousTimestep); + swapArrays(this->bladeVelocitiesZDCurrentTimestep, this->bladeVelocitiesZDPreviousTimestep); + cudaManager->cudaCopyBladeVelocitiesHtoD(this); +} + +void ActuatorFarm::initBladeForces(CudaMemoryManager* cudaManager) +{ + cudaManager->cudaAllocBladeForces(this); + + std::fill_n(this->bladeForcesXH, this->numberOfGridNodes, c0o1); + std::fill_n(this->bladeForcesYH, this->numberOfGridNodes, c0o1); + std::fill_n(this->bladeForcesZH, this->numberOfGridNodes, c0o1); + + cudaManager->cudaCopyBladeForcesHtoD(this); + swapArrays(this->bladeForcesXDCurrentTimestep, this->bladeForcesXDPreviousTimestep); + swapArrays(this->bladeForcesYDCurrentTimestep, this->bladeForcesYDPreviousTimestep); + swapArrays(this->bladeForcesZDCurrentTimestep, this->bladeForcesZDPreviousTimestep); + cudaManager->cudaCopyBladeForcesHtoD(this); +} + +void ActuatorFarm::initBladeIndices(CudaMemoryManager* cudaManager) +{ + cudaManager->cudaAllocBladeIndices(this); + + std::fill_n(this->bladeIndicesH, this->numberOfGridNodes, 1); + + cudaManager->cudaCopyBladeIndicesHtoD(this); +} + +void ActuatorFarm::initBoundingSpheres(Parameter* para, CudaMemoryManager* cudaManager) +{ + std::vector<int> nodesInSpheres; + const real sphereRadius = getBoundingSphereRadius(this->diameter, this->smearingWidth); + const real sphereRadiusSqrd = sphereRadius * sphereRadius; + const uint minimumNumberOfNodesPerSphere = + (uint)(c4o3 * cPi * pow(sphereRadius - this->deltaX, c3o1) / pow(this->deltaX, c3o1)); + + for (uint turbine = 0; turbine < this->numberOfTurbines; turbine++) { + + const real posX = this->turbinePosXH[turbine]; + const real posY = this->turbinePosYH[turbine]; + const real posZ = this->turbinePosZH[turbine]; + + uint nodesInThisSphere = 0; + + for (size_t pos = 1; pos <= para->getParH(this->level)->numberOfNodes; pos++) { + const real distX = para->getParH(this->level)->coordinateX[pos] - posX; + const real distY = para->getParH(this->level)->coordinateY[pos] - posY; + const real distZ = para->getParH(this->level)->coordinateZ[pos] - posZ; + if (distSqrd(distX, distY, distZ) < sphereRadiusSqrd) { + nodesInSpheres.push_back((int)pos); + nodesInThisSphere++; + } + } + + if (nodesInThisSphere < minimumNumberOfNodesPerSphere) { + VF_LOG_CRITICAL("Found only {} nodes in bounding sphere of turbine no. {}, expected at least {}!", + nodesInThisSphere, turbine, minimumNumberOfNodesPerSphere); + throw std::runtime_error("ActuatorFarm::initBoundingSpheres: Turbine bounding sphere partially out of domain."); + } + } + + this->numberOfIndices = uint(nodesInSpheres.size()); + + cudaManager->cudaAllocSphereIndices(this); + std::copy(nodesInSpheres.begin(), nodesInSpheres.end(), this->boundingSphereIndicesH); + cudaManager->cudaCopySphereIndicesHtoD(this); +} + +void ActuatorFarm::setAllBladeCoords(const real* _bladeCoordsX, const real* _bladeCoordsY, const real* _bladeCoordsZ) +{ + std::copy_n(_bladeCoordsX, this->numberOfGridNodes, this->bladeCoordsXH); + std::copy_n(_bladeCoordsY, this->numberOfGridNodes, this->bladeCoordsYH); + std::copy_n(_bladeCoordsZ, this->numberOfGridNodes, this->bladeCoordsZH); +} + +void ActuatorFarm::setAllBladeVelocities(const real* _bladeVelocitiesX, const real* _bladeVelocitiesY, + const real* _bladeVelocitiesZ) +{ + std::copy_n(_bladeVelocitiesX, this->numberOfGridNodes, this->bladeVelocitiesXH); + std::copy_n(_bladeVelocitiesY, this->numberOfGridNodes, this->bladeVelocitiesYH); + std::copy_n(_bladeVelocitiesZ, this->numberOfGridNodes, this->bladeVelocitiesZH); +} + +void ActuatorFarm::setAllBladeForces(const real* _bladeForcesX, const real* _bladeForcesY, const real* _bladeForcesZ) +{ + std::copy_n(_bladeForcesX, this->numberOfGridNodes, this->bladeForcesXH); + std::copy_n(_bladeForcesY, this->numberOfGridNodes, this->bladeForcesYH); + std::copy_n(_bladeForcesZ, this->numberOfGridNodes, this->bladeForcesZH); +} + +void ActuatorFarm::setTurbineBladeCoords(uint turbine, const real* _bladeCoordsX, const real* _bladeCoordsY, + const real* _bladeCoordsZ) +{ + std::copy_n(_bladeCoordsX, this->numberOfNodesPerTurbine, &this->bladeCoordsXH[turbine * this->numberOfNodesPerTurbine]); + std::copy_n(_bladeCoordsY, this->numberOfNodesPerTurbine, &this->bladeCoordsYH[turbine * this->numberOfNodesPerTurbine]); + std::copy_n(_bladeCoordsZ, this->numberOfNodesPerTurbine, &this->bladeCoordsZH[turbine * this->numberOfNodesPerTurbine]); +} + +void ActuatorFarm::setTurbineBladeVelocities(uint turbine, const real* _bladeVelocitiesX, const real* _bladeVelocitiesY, + const real* _bladeVelocitiesZ) +{ + std::copy_n(_bladeVelocitiesX, this->numberOfNodesPerTurbine, &this->bladeVelocitiesXH[turbine * this->numberOfNodesPerTurbine]); + std::copy_n(_bladeVelocitiesY, this->numberOfNodesPerTurbine, &this->bladeVelocitiesYH[turbine * this->numberOfNodesPerTurbine]); + std::copy_n(_bladeVelocitiesZ, this->numberOfNodesPerTurbine, &this->bladeVelocitiesZH[turbine * this->numberOfNodesPerTurbine]); +} + +void ActuatorFarm::setTurbineBladeForces(uint turbine, const real* _bladeForcesX, const real* _bladeForcesY, + const real* _bladeForcesZ) +{ + std::copy_n(_bladeForcesX, this->numberOfNodesPerTurbine, &this->bladeForcesXH[turbine * this->numberOfNodesPerTurbine]); + std::copy_n(_bladeForcesY, this->numberOfNodesPerTurbine, &this->bladeForcesYH[turbine * this->numberOfNodesPerTurbine]); + std::copy_n(_bladeForcesZ, this->numberOfNodesPerTurbine, &this->bladeForcesZH[turbine * this->numberOfNodesPerTurbine]); +} + +void ActuatorFarm::swapDeviceArrays() +{ + swapArrays(this->bladeCoordsXDPreviousTimestep, this->bladeCoordsXDCurrentTimestep); + swapArrays(this->bladeCoordsYDPreviousTimestep, this->bladeCoordsYDCurrentTimestep); + swapArrays(this->bladeCoordsZDPreviousTimestep, this->bladeCoordsZDCurrentTimestep); + + swapArrays(this->bladeVelocitiesXDPreviousTimestep, this->bladeVelocitiesXDCurrentTimestep); + swapArrays(this->bladeVelocitiesYDPreviousTimestep, this->bladeVelocitiesYDCurrentTimestep); + swapArrays(this->bladeVelocitiesZDPreviousTimestep, this->bladeVelocitiesZDCurrentTimestep); + + swapArrays(this->bladeForcesXDPreviousTimestep, this->bladeForcesXDCurrentTimestep); + swapArrays(this->bladeForcesYDPreviousTimestep, this->bladeForcesYDCurrentTimestep); + swapArrays(this->bladeForcesZDPreviousTimestep, this->bladeForcesZDCurrentTimestep); +} + +std::string ActuatorFarm::getFilename(Parameter* para, uint t) const +{ + return para->getOutputPath() + this->outputName + "_t_" + std::to_string(t); +} + +void ActuatorFarm::write(const std::string& filename) const +{ + std::vector<std::string> dataNames = { + "bladeVelocitiesX", + "bladeVelocitiesY", + "bladeVelocitiesZ", + "bladeForcesX", + "bladeForcesY", + "bladeForcesZ", + }; + std::vector<UbTupleFloat3> nodes(numberOfGridNodes); + std::vector<std::vector<double>> nodeData(6); + for (auto& data : nodeData) + data.resize(numberOfGridNodes); + for (uint i = 0; i < numberOfGridNodes; i++) { + nodes[i] = UbTupleFloat3(this->bladeCoordsXH[i], this->bladeCoordsYH[i], this->bladeCoordsZH[i]); + nodeData[0][i] = this->bladeVelocitiesXH[i]; + nodeData[1][i] = this->bladeVelocitiesYH[i]; + nodeData[2][i] = this->bladeVelocitiesZH[i]; + nodeData[3][i] = this->bladeForcesXH[i]; + nodeData[4][i] = this->bladeForcesYH[i]; + nodeData[5][i] = this->bladeForcesZH[i]; + } + WbWriterVtkXmlBinary::getInstance()->writeNodesWithNodeData(filename, nodes, dataNames, nodeData); +} diff --git a/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarm.h b/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarm.h new file mode 100644 index 0000000000000000000000000000000000000000..d89be8fffaed41ff472550fe4fb83b4e23295c2e --- /dev/null +++ b/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarm.h @@ -0,0 +1,189 @@ +#ifndef ActuatorFarm_H +#define ActuatorFarm_H + +#include "PreCollisionInteractor/PreCollisionInteractor.h" +#include <basics/DataTypes.h> +#include <basics/constants/NumericConstants.h> +#include <stdexcept> + +class Parameter; +class GridProvider; +using namespace vf::basics::constant; + +class ActuatorFarm : public PreCollisionInteractor +{ +public: + ActuatorFarm( + const real diameter, + const std::vector<real> bladeRadii, + const std::vector<real> turbinePositionsX, + const std::vector<real> turbinePositionsY, + const std::vector<real> turbinePositionsZ, + const real density, + const real smearingWidth, + const int level, + const real deltaT, + const real deltaX, + const bool useHostArrays + ) : + diameter(diameter), + bladeRadii(bladeRadii), + numberOfNodesPerBlade(static_cast<uint>(bladeRadii.size())), + numberOfNodesPerTurbine(numberOfNodesPerBlade*numberOfBlades), + numberOfTurbines(static_cast<uint>(turbinePositionsX.size())), + initialTurbinePositionsX(turbinePositionsX), + initialTurbinePositionsY(turbinePositionsY), + initialTurbinePositionsZ(turbinePositionsZ), + density(density), + smearingWidth(smearingWidth), + level(level), + useHostArrays(useHostArrays), + deltaT(deltaT*exp2(-level)), + deltaX(deltaX*exp2(-level)), + invDeltaX(c1o1/deltaX) + { + if(this->smearingWidth < this->deltaX) + throw std::runtime_error("ActuatorFarm::ActuatorFarm: smearing width needs to be larger than dx!"); + if(numberOfTurbines != turbinePositionsY.size() || numberOfTurbines != turbinePositionsZ.size()) + throw std::runtime_error("ActuatorFarm::ActuatorFarm: turbine positions need to have the same length!"); + azimuths = std::vector<real>(numberOfTurbines, 0.0); + } + + ~ActuatorFarm() override = default; + void init(Parameter* para, GridProvider* gridProvider, CudaMemoryManager* cudaManager) override; + void interact(Parameter* para, CudaMemoryManager* cudaManager, int level, uint t) override; + void free(Parameter* para, CudaMemoryManager* cudaManager) override; + void getTaggedFluidNodes(Parameter *para, GridProvider* gridProvider) override; + + void enableOutput(const std::string outputName, uint tStart, uint tOut) { + this->outputName = outputName; + this->writeOutput = true; + this->tStartOut = tStart; + this->tOut = tOut; + } + + void write(const std::string& filename) const; + + real getDensity() const { return this->density; }; + real getDeltaT() const { return this->deltaT; }; + real getDeltaX() const { return this->deltaX; }; + + uint getNumberOfTurbines() const { return this->numberOfTurbines; }; + uint getNumberOfNodesPerTurbine() const { return this->numberOfNodesPerTurbine; }; + uint getNumberOfNodesPerBlade() const { return this->numberOfNodesPerBlade; }; + uint getNumberOfBladesPerTurbine() const { return ActuatorFarm::numberOfBlades; }; + + uint getNumberOfIndices() const { return this->numberOfIndices; }; + uint getNumberOfGridNodes() const { return this->numberOfGridNodes; }; + + real* getAllTurbinePosX() const { return turbinePosXH; }; + real* getAllTurbinePosY() const { return turbinePosYH; }; + real* getAllTurbinePosZ() const { return turbinePosZH; }; + + real getTurbinePosX(uint turbine) const { return turbinePosXH[turbine]; }; + real getTurbinePosY(uint turbine) const { return turbinePosYH[turbine]; }; + real getTurbinePosZ(uint turbine) const { return turbinePosZH[turbine]; }; + + real* getAllBladeCoordsX() const { return this->bladeCoordsXH; }; + real* getAllBladeCoordsY() const { return this->bladeCoordsYH; }; + real* getAllBladeCoordsZ() const { return this->bladeCoordsZH; }; + real* getAllBladeVelocitiesX() const { return this->bladeVelocitiesXH; }; + real* getAllBladeVelocitiesY() const { return this->bladeVelocitiesYH; }; + real* getAllBladeVelocitiesZ() const { return this->bladeVelocitiesZH; }; + real* getAllBladeForcesX() const { return this->bladeForcesXH; }; + real* getAllBladeForcesY() const { return this->bladeForcesYH; }; + real* getAllBladeForcesZ() const { return this->bladeForcesZH; }; + + real* getTurbineBladeCoordsX(uint turbine) const { return &this->bladeCoordsXH[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeCoordsY(uint turbine) const { return &this->bladeCoordsYH[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeCoordsZ(uint turbine) const { return &this->bladeCoordsZH[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeVelocitiesX(uint turbine) const { return &this->bladeVelocitiesXH[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeVelocitiesY(uint turbine) const { return &this->bladeVelocitiesYH[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeVelocitiesZ(uint turbine) const { return &this->bladeVelocitiesZH[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeForcesX(uint turbine) const { return &this->bladeForcesXH[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeForcesY(uint turbine) const { return &this->bladeForcesYH[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeForcesZ(uint turbine) const { return &this->bladeForcesZH[turbine*numberOfNodesPerTurbine]; }; + + real* getAllBladeCoordsXDevice() const { return this->bladeCoordsXDCurrentTimestep; }; + real* getAllBladeCoordsYDevice() const { return this->bladeCoordsYDCurrentTimestep; }; + real* getAllBladeCoordsZDevice() const { return this->bladeCoordsZDCurrentTimestep; }; + real* getAllBladeVelocitiesXDevice() const { return this->bladeVelocitiesXDCurrentTimestep; }; + real* getAllBladeVelocitiesYDevice() const { return this->bladeVelocitiesYDCurrentTimestep; }; + real* getAllBladeVelocitiesZDevice() const { return this->bladeVelocitiesZDCurrentTimestep; }; + real* getAllBladeForcesXDevice() const { return this->bladeForcesXDCurrentTimestep; }; + real* getAllBladeForcesYDevice() const { return this->bladeForcesYDCurrentTimestep; }; + real* getAllBladeForcesZDevice() const { return this->bladeForcesZDCurrentTimestep; }; + + real* getTurbineBladeCoordsXDevice(uint turbine) const { return &this->bladeCoordsXDCurrentTimestep[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeCoordsYDevice(uint turbine) const { return &this->bladeCoordsYDCurrentTimestep[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeCoordsZDevice(uint turbine) const { return &this->bladeCoordsZDCurrentTimestep[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeVelocitiesXDevice(uint turbine) const { return &this->bladeVelocitiesXDCurrentTimestep[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeVelocitiesYDevice(uint turbine) const { return &this->bladeVelocitiesYDCurrentTimestep[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeVelocitiesZDevice(uint turbine) const { return &this->bladeVelocitiesZDCurrentTimestep[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeForcesXDevice(uint turbine) const { return &this->bladeForcesXDCurrentTimestep[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeForcesYDevice(uint turbine) const { return &this->bladeForcesYDCurrentTimestep[turbine*numberOfNodesPerTurbine]; }; + real* getTurbineBladeForcesZDevice(uint turbine) const { return &this->bladeForcesZDCurrentTimestep[turbine*numberOfNodesPerTurbine]; }; + + void setAllBladeCoords(const real* _bladeCoordsX, const real* _bladeCoordsY, const real* _bladeCoordsZ); + void setAllBladeVelocities(const real* _bladeVelocitiesX, const real* _bladeVelocitiesY, const real* _bladeVelocitiesZ); + void setAllBladeForces(const real* _bladeForcesX, const real* _bladeForcesY, const real* _bladeForcesZ); + + void setTurbineBladeCoords(uint turbine, const real* _bladeCoordsX, const real* _bladeCoordsY, const real* _bladeCoordsZ); + void setTurbineBladeVelocities(uint turbine, const real* _bladeVelocitiesX, const real* _bladeVelocitiesY, const real* _bladeVelocitiesZ); + void setTurbineBladeForces(uint turbine, const real* _bladeForcesX, const real* _bladeForcesY, const real* _bladeForcesZ); + + void setTurbineAzimuth(uint turbine, real azimuth){azimuths[turbine] = azimuth;} + + virtual void updateForcesAndCoordinates()=0; + +private: + void initTurbineGeometries(CudaMemoryManager* cudaManager); + void initBoundingSpheres(Parameter* para, CudaMemoryManager* cudaManager); + void initBladeCoords(CudaMemoryManager* cudaManager); + void initBladeVelocities(CudaMemoryManager* cudaManager); + void initBladeForces(CudaMemoryManager* cudaManager); + void initBladeIndices(CudaMemoryManager* cudaManager); + std::string getFilename(Parameter* para, uint t) const; + void swapDeviceArrays(); + +public: + real* bladeCoordsXH, * bladeCoordsYH, * bladeCoordsZH; + real* bladeCoordsXDPreviousTimestep, * bladeCoordsYDPreviousTimestep, * bladeCoordsZDPreviousTimestep; + real* bladeCoordsXDCurrentTimestep, * bladeCoordsYDCurrentTimestep, * bladeCoordsZDCurrentTimestep; + real* bladeVelocitiesXH, * bladeVelocitiesYH, * bladeVelocitiesZH; + real* bladeVelocitiesXDPreviousTimestep, * bladeVelocitiesYDPreviousTimestep, * bladeVelocitiesZDPreviousTimestep; + real* bladeVelocitiesXDCurrentTimestep, * bladeVelocitiesYDCurrentTimestep, * bladeVelocitiesZDCurrentTimestep; + real* bladeForcesXH, * bladeForcesYH, * bladeForcesZH; + real* bladeForcesXDPreviousTimestep, * bladeForcesYDPreviousTimestep, * bladeForcesZDPreviousTimestep; + real* bladeForcesXDCurrentTimestep, * bladeForcesYDCurrentTimestep, * bladeForcesZDCurrentTimestep; + uint* bladeIndicesH; + uint* bladeIndicesD; + uint* boundingSphereIndicesH; + uint* boundingSphereIndicesD; + real* turbinePosXH, *turbinePosYH, *turbinePosZH; + real* turbinePosXD, *turbinePosYD, *turbinePosZD; + +protected: + static constexpr uint numberOfBlades{3}; + std::vector<real> bladeRadii, initialTurbinePositionsX, initialTurbinePositionsY, initialTurbinePositionsZ; + std::vector<real> azimuths; + const real diameter; + const bool useHostArrays; + const real density; + const real deltaT, deltaX, invDeltaX; + const uint numberOfTurbines, numberOfNodesPerBlade, numberOfNodesPerTurbine; + const real smearingWidth; // in m + const int level; + uint numberOfIndices{0}; + uint numberOfGridNodes{0}; + + real forceRatio, factorGaussian; + int streamIndex; + + bool writeOutput{false}; + std::string outputName; + uint tOut{0}; + uint tStartOut{0}; +}; + +#endif diff --git a/src/gpu/core/PreCollisionInteractor/ActuatorFarmInlines.h b/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmInlines.h similarity index 64% rename from src/gpu/core/PreCollisionInteractor/ActuatorFarmInlines.h rename to src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmInlines.h index cc151088db963f00d3d39af705c80d22337701c9..943ab708b6158400f236f496b2b42d876adcbaec 100644 --- a/src/gpu/core/PreCollisionInteractor/ActuatorFarmInlines.h +++ b/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmInlines.h @@ -26,7 +26,7 @@ // You should have received a copy of the GNU General Public License along // with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. // -//! \file ActuatorFarm.cu +//! \file ActuatorFarmInlines.cu //! \ingroup PreCollisionInteractor //! \author Henrik Asmuth, Henry Korb, Anna Wellmann //====================================================================================== @@ -34,7 +34,11 @@ #ifndef ACTUATOR_FARM_INLINES #define ACTUATOR_FARM_INLINES -#include "basics/DataTypes.h" +#include <basics/DataTypes.h> +#include <basics/constants/NumericConstants.h> +#include "GPU/GeometryUtils.h" + +using namespace vf::basics::constant; struct TurbineNodeIndex { uint turbine; @@ -57,11 +61,12 @@ __host__ __device__ __inline__ void calcTurbineBladeAndBladeNode(uint node, uint { // see https://git.rz.tu-bs.de/irmb/VirtualFluids_dev/-/merge_requests/248 for visualization turbine = node / (numberOfNodesPerBlade * numberOfBlades); - uint x_off = turbine * numberOfNodesPerBlade * numberOfBlades; + const uint x_off = turbine * numberOfNodesPerBlade * numberOfBlades; blade = (node - x_off) / numberOfNodesPerBlade; - uint y_off = numberOfNodesPerBlade * blade + x_off; + const uint y_off = numberOfNodesPerBlade * blade + x_off; bladeNode = node - y_off; } + __host__ __device__ __inline__ TurbineNodeIndex calcTurbineBladeAndBladeNode(uint node, uint numberOfNodesPerBlade, uint numberOfBlades) { uint turbine; @@ -71,4 +76,47 @@ __host__ __device__ __inline__ TurbineNodeIndex calcTurbineBladeAndBladeNode(uin return { /*.turbine = */ turbine, /*.blade = */ blade, /*.bladeNode = */ bladeNode }; // Designated initializers are a C++ 20 feature } +__host__ __device__ __inline__ void rotateFromBladeToGlobal( + real bladeCoordX_BF, real bladeCoordY_BF, real bladeCoordZ_BF, + real& bladeCoordX_GF, real& bladeCoordY_GF, real& bladeCoordZ_GF, + real azimuth) +{ + rotateAboutX3D(azimuth, bladeCoordX_BF, bladeCoordY_BF, bladeCoordZ_BF, bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF); +} + +__host__ __device__ __inline__ void rotateFromGlobalToBlade( + real& bladeCoordX_BF, real& bladeCoordY_BF, real& bladeCoordZ_BF, + real bladeCoordX_GF, real bladeCoordY_GF, real bladeCoordZ_GF, + real azimuth) +{ + invRotateAboutX3D(azimuth, bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF, bladeCoordX_BF, bladeCoordY_BF, bladeCoordZ_BF); +} +__host__ __device__ __inline__ real distSqrd(real distX, real distY, real distZ) +{ + return distX * distX + distY * distY + distZ * distZ; +} + +__host__ __device__ __inline__ real getBoundingSphereRadius(real diameter, real smearingWidth) +{ + return c1o2 * diameter + c3o2 * smearingWidth; +} + +__host__ __device__ __inline__ bool inBoundingSphere(real distX, real distY, real distZ, real diameter, real smearingWidth) +{ + const real boundingSphereRadius = getBoundingSphereRadius(diameter, smearingWidth); + return distSqrd(distX, distY, distZ) < boundingSphereRadius * boundingSphereRadius; +} + +__host__ __device__ __inline__ real gaussianSmearing(real distX, real distY, real distZ, real epsilon, real factorGaussian) +{ + return factorGaussian * exp(-distSqrd(distX, distY, distZ) / (epsilon * epsilon)); +} + +__inline__ void swapArrays(real* &arr1, real* &arr2) +{ + real* tmp = arr1; + arr1 = arr2; + arr2 = tmp; +} + #endif diff --git a/src/gpu/core/PreCollisionInteractor/ActuatorFarmInlinesTest.cpp b/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmInlinesTest.cpp similarity index 100% rename from src/gpu/core/PreCollisionInteractor/ActuatorFarmInlinesTest.cpp rename to src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmInlinesTest.cpp diff --git a/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmStandalone.cu b/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmStandalone.cu new file mode 100644 index 0000000000000000000000000000000000000000..6e577d1f06967ccf0e80db9474b9b7c3b8861c50 --- /dev/null +++ b/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmStandalone.cu @@ -0,0 +1,124 @@ +//======================================================================================= +// ____ ____ __ ______ __________ __ __ __ __ +// \ \ | | | | | _ \ |___ ___| | | | | / \ | | +// \ \ | | | | | |_) | | | | | | | / \ | | +// \ \ | | | | | _ / | | | | | | / /\ \ | | +// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____ +// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______| +// \ \ | | ________________________________________________________________ +// \ \ | | | ______________________________________________________________| +// \ \| | | | __ __ __ __ ______ _______ +// \ | | |_____ | | | | | | | | | _ \ / _____) +// \ | | _____| | | | | | | | | | | \ \ \_______ +// \ | | | | |_____ | \_/ | | | | |_/ / _____ | +// \ _____| |__| |________| \_______/ |__| |______/ (_______/ +// +// This file is part of VirtualFluids. VirtualFluids 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, either version 3 of +// the License, or (at your option) any later version. +// +// VirtualFluids 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 VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file ActuatorFarm.cu +//! \ingroup PreCollisionInteractor +//! \author Henrik Asmuth, Henry Korb +//====================================================================================== +#include "ActuatorFarmInlines.h" +#include "ActuatorFarmStandalone.h" + +#include <cuda.h> +#include <cuda_runtime.h> +#include <helper_cuda.h> + +#include <logger/Logger.h> +#include <cuda_helper/CudaGrid.h> +#include <basics/constants/NumericConstants.h> +#include <basics/writer/WbWriterVtkXmlBinary.h> + +#include "GPU/GeometryUtils.h" +#include "LBM/GPUHelperFunctions/KernelUtilities.h" +#include "Parameter/Parameter.h" +#include "Parameter/CudaStreamManager.h" +#include "DataStructureInitializer/GridProvider.h" +#include "GPU/CudaMemoryManager.h" + +using namespace vf::basics::constant; + +std::vector<real> ActuatorFarmStandalone::computeBladeRadii(const real diameter, const uint numberOfNodesPerBlade) +{ + const real dr = c1o2 * diameter / numberOfNodesPerBlade; + std::vector<real> blade_radii(numberOfNodesPerBlade); + for (uint node = 0; node < numberOfNodesPerBlade; node++) + blade_radii[node] = dr * (node + 0.5); + return blade_radii; +} + +void ActuatorFarmStandalone::updateForcesAndCoordinates() +{ + const real lift_coefficient = c1o1; + const real drag_coefficient = c0o1; + const real c0 = 20 * c1o10; + const real delta_azimuth = c2Pi / this->numberOfBlades; + + for (uint turbine = 0; turbine < this->numberOfTurbines; turbine++) { + const real rotor_speed = this->rotorSpeeds[turbine]; + const real azimuth_old = this->azimuths[turbine]; + const real azimuth_new = azimuth_old + deltaT * rotor_speed; + this->azimuths[turbine] = azimuth_new > c2Pi ? azimuth_new - c2Pi : azimuth_new; + + for (uint blade = 0; blade < this->numberOfBlades; blade++) { + const real local_azimuth_new = azimuth_new + blade * delta_azimuth; + + real last_node_radius = c0o1; + real current_node_radius = c0o1; + real next_node_radius = this->bladeRadii[0]; + + for (uint bladeNode = 0; bladeNode < this->numberOfNodesPerBlade; bladeNode++) { + const uint node = calcNodeIndexInBladeArrays({ turbine, blade, bladeNode }, this->numberOfNodesPerBlade, + this->numberOfBlades); + + real u_rel, v_rel, w_rel; + rotateFromGlobalToBlade(u_rel, v_rel, w_rel, + this->bladeVelocitiesXH[node], + this->bladeVelocitiesYH[node], + this->bladeVelocitiesZH[node], + azimuth_old + delta_azimuth); + + last_node_radius = current_node_radius; + current_node_radius = next_node_radius; + next_node_radius = + bladeNode < this->numberOfNodesPerBlade - 1 ? this->bladeRadii[bladeNode + 1] : this->diameter * c1o2; + + const real dr = c1o2 * (next_node_radius - last_node_radius); + + v_rel += current_node_radius * rotor_speed; + const real u_rel_sq = u_rel * u_rel + v_rel * v_rel; + const real phi = atan2(u_rel, v_rel); + + const real tmp = c4o1 * current_node_radius / this->diameter - c1o1; + const real chord = c0 * sqrt(c1o1 - tmp * tmp); + const real normal_coefficient = lift_coefficient * cos(phi) + drag_coefficient * sin(phi); + const real tangential_coefficient = lift_coefficient * sin(phi) - drag_coefficient * cos(phi); + const real fx = -c1o2 * u_rel_sq * chord * this->density * normal_coefficient * dr; + const real fy = -c1o2 * u_rel_sq * chord * this->density * tangential_coefficient * dr; + + rotateFromBladeToGlobal(fx, fy, c0o1, + this->bladeForcesXH[node], this->bladeForcesYH[node], this->bladeForcesZH[node], + local_azimuth_new); + rotateFromBladeToGlobal(c0o1, c0o1, current_node_radius, + this->bladeCoordsXH[node], this->bladeCoordsYH[node], this->bladeCoordsZH[node], + local_azimuth_new); + bladeCoordsXH[node] += this->turbinePosXH[turbine]; + bladeCoordsYH[node] += this->turbinePosYH[turbine]; + bladeCoordsZH[node] += this->turbinePosZH[turbine]; + } + } + } +} diff --git a/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmStandalone.h b/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmStandalone.h new file mode 100644 index 0000000000000000000000000000000000000000..78f0ebf67e0cfd60683be7f36f25bf97eb839035 --- /dev/null +++ b/src/gpu/core/PreCollisionInteractor/Actuator/ActuatorFarmStandalone.h @@ -0,0 +1,34 @@ +#ifndef ActuatorFarmStandalone_H +#define ActuatorFarmStandalone_H + +#include "ActuatorFarm.h" +#include "basics/DataTypes.h" + +class ActuatorFarmStandalone : public ActuatorFarm +{ +public: + ActuatorFarmStandalone( + const real diameter, + const uint numberOfNodesPerBlade, + const std::vector<real> turbinePositionsX, + const std::vector<real> turbinePositionsY, + const std::vector<real> turbinePositionsZ, + const std::vector<real> rotorSpeeds, + const real density, + const real smearingWidth, + const int level, + const real deltaT, + const real deltaX + ) : rotorSpeeds(rotorSpeeds), + ActuatorFarm(diameter, computeBladeRadii(diameter, numberOfNodesPerBlade), turbinePositionsX, turbinePositionsY, turbinePositionsZ, density, smearingWidth, level, deltaT, deltaX, true) + {} + + void updateForcesAndCoordinates() override; + static std::vector<real> computeBladeRadii(const real diameter, const uint numberOfNodesPerBlade); + +private: + std::vector<real> rotorSpeeds; + +}; + +#endif diff --git a/src/gpu/core/PreCollisionInteractor/ActuatorFarm.cu b/src/gpu/core/PreCollisionInteractor/ActuatorFarm.cu deleted file mode 100644 index fac6b3cb70c8bb2694f89e886b9192dfeed86782..0000000000000000000000000000000000000000 --- a/src/gpu/core/PreCollisionInteractor/ActuatorFarm.cu +++ /dev/null @@ -1,629 +0,0 @@ -//======================================================================================= -// ____ ____ __ ______ __________ __ __ __ __ -// \ \ | | | | | _ \ |___ ___| | | | | / \ | | -// \ \ | | | | | |_) | | | | | | | / \ | | -// \ \ | | | | | _ / | | | | | | / /\ \ | | -// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____ -// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______| -// \ \ | | ________________________________________________________________ -// \ \ | | | ______________________________________________________________| -// \ \| | | | __ __ __ __ ______ _______ -// \ | | |_____ | | | | | | | | | _ \ / _____) -// \ | | _____| | | | | | | | | | | \ \ \_______ -// \ | | | | |_____ | \_/ | | | | |_/ / _____ | -// \ _____| |__| |________| \_______/ |__| |______/ (_______/ -// -// This file is part of VirtualFluids. VirtualFluids 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, either version 3 of -// the License, or (at your option) any later version. -// -// VirtualFluids 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 VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file ActuatorFarm.cu -//! \ingroup PreCollisionInteractor -//! \author Henrik Asmuth, Henry Korb -//====================================================================================== -#include "ActuatorFarm.h" -#include "ActuatorFarmInlines.h" - -#include <cuda.h> -#include <cuda_runtime.h> -#include <helper_cuda.h> - -#include <logger/Logger.h> -#include <cuda_helper/CudaGrid.h> -#include <basics/constants/NumericConstants.h> -#include <basics/writer/WbWriterVtkXmlBinary.h> - -#include "gpu/core/GPU/GeometryUtils.h" -#include "LBM/GPUHelperFunctions/KernelUtilities.h" -#include "Parameter/Parameter.h" -#include "Parameter/CudaStreamManager.h" -#include "DataStructureInitializer/GridProvider.h" -#include "GPU/CudaMemoryManager.h" - -using namespace vf::basics::constant; - -__host__ __device__ __forceinline__ real distSqrd(real distX, real distY, real distZ) -{ - return distX * distX + distY * distY + distZ * distZ; -} - -void swapArrays(real* &arr1, real* &arr2) -{ - real* tmp = arr1; - arr1 = arr2; - arr2 = tmp; -} - -__host__ __device__ __inline__ void rotateFromBladeToGlobal( - real bladeCoordX_BF, real bladeCoordY_BF, real bladeCoordZ_BF, - real& bladeCoordX_GF, real& bladeCoordY_GF, real& bladeCoordZ_GF, - real azimuth, real yaw) -{ - real tmpX, tmpY, tmpZ; - - rotateAboutX3D(azimuth, bladeCoordX_BF, bladeCoordY_BF, bladeCoordZ_BF, tmpX, tmpY, tmpZ); - rotateAboutZ3D(yaw, tmpX, tmpY, tmpZ, bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF); - -} - -__host__ __device__ __inline__ void rotateFromGlobalToBlade( - real& bladeCoordX_BF, real& bladeCoordY_BF, real& bladeCoordZ_BF, - real bladeCoordX_GF, real bladeCoordY_GF, real bladeCoordZ_GF, - real azimuth, real yaw) -{ - real tmpX, tmpY, tmpZ; - - invRotateAboutZ3D(yaw, bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF, tmpX, tmpY, tmpZ); - invRotateAboutX3D(azimuth, tmpX, tmpY, tmpZ, bladeCoordX_BF, bladeCoordY_BF, bladeCoordZ_BF); -} - -__host__ __device__ __inline__ void calcCoordinateOfBladeNodeInGridFrameOfReference(uint bladeNodeIndex, uint turbine, real localAzimuth, real yaw, - const real* bladeCoordsX, const real* bladeCoordsY, const real* bladeCoordsZ, - const real* turbPosX, const real* turbPosY, const real* turbPosZ, - real& bladeCoordX_GF, real& bladeCoordY_GF, real& bladeCoordZ_GF) -{ - - const real bladeCoordX_BF = bladeCoordsX[bladeNodeIndex]; - const real bladeCoordY_BF = bladeCoordsY[bladeNodeIndex]; - const real bladeCoordZ_BF = bladeCoordsZ[bladeNodeIndex]; - - rotateFromBladeToGlobal(bladeCoordX_BF, bladeCoordY_BF, bladeCoordZ_BF, bladeCoordX_GF, bladeCoordY_GF, - bladeCoordZ_GF, localAzimuth, yaw); - - bladeCoordX_GF += turbPosX[turbine]; - bladeCoordY_GF += turbPosY[turbine]; - bladeCoordZ_GF += turbPosZ[turbine]; -} - -__global__ void interpolateVelocities(real* gridCoordsX, real* gridCoordsY, real* gridCoordsZ, - uint* neighborsX, uint* neighborsY, uint* neighborsZ, uint* neighborsWSB, - real* vx, real* vy, real* vz, - real* bladeCoordsX, real* bladeCoordsY, real* bladeCoordsZ, - real* bladeVelocitiesX, real* bladeVelocitiesY, real* bladeVelocitiesZ, - uint numberOfTurbines, uint numberOfBlades, uint numberOfBladeNodes, - real* azimuths, real* yaws, real* omegas, - real* turbPosX, real* turbPosY, real* turbPosZ, - uint* bladeIndices, real velocityRatio, real invDeltaX) -{ - - //////////////////////////////////////////////////////////////////////////////// - //! - Get node index coordinates from threadIdx, blockIdx, blockDim and gridDim. - //! - const unsigned nodeIndex = vf::gpu::getNodeIndex(); - - if (nodeIndex >= numberOfBladeNodes * numberOfBlades * numberOfTurbines) return; - - auto [turbine, blade, bladeNodeIndexOnBlade] = calcTurbineBladeAndBladeNode(nodeIndex, numberOfBladeNodes, numberOfBlades); - - const real localAzimuth = azimuths[turbine] + blade * c2Pi / numberOfBlades; - const real yaw = yaws[turbine]; - - real bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF; - calcCoordinateOfBladeNodeInGridFrameOfReference(nodeIndex, turbine, localAzimuth, yaw, - bladeCoordsX, bladeCoordsY, bladeCoordsZ, - turbPosX, turbPosY, turbPosZ, - bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF); - - uint k, ke, kn, kt; - uint kne, kte, ktn, ktne; - - k = findNearestCellBSW(bladeIndices[nodeIndex], - gridCoordsX, gridCoordsY, gridCoordsZ, - bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF, - neighborsX, neighborsY, neighborsZ, neighborsWSB); - - bladeIndices[nodeIndex] = k; - - getNeighborIndicesOfBSW(k, ke, kn, kt, kne, kte, ktn, ktne, neighborsX, neighborsY, neighborsZ); - - real dW, dE, dN, dS, dT, dB; - - real distX = invDeltaX * (bladeCoordX_GF - gridCoordsX[k]); - real distY = invDeltaX * (bladeCoordY_GF - gridCoordsY[k]); - real distZ = invDeltaX * (bladeCoordZ_GF - gridCoordsZ[k]); - - getInterpolationWeights(dW, dE, dN, dS, dT, dB, distX, distY, distZ); - - real bladeVelX_GF = trilinearInterpolation(dW, dE, dN, dS, dT, dB, k, ke, kn, kt, kne, kte, ktn, ktne, vx) * velocityRatio; - real bladeVelY_GF = trilinearInterpolation(dW, dE, dN, dS, dT, dB, k, ke, kn, kt, kne, kte, ktn, ktne, vy) * velocityRatio; - real bladeVelZ_GF = trilinearInterpolation(dW, dE, dN, dS, dT, dB, k, ke, kn, kt, kne, kte, ktn, ktne, vz) * velocityRatio; - - real bladeVelX_BF, bladeVelY_BF, bladeVelZ_BF; - - rotateFromGlobalToBlade(bladeVelX_BF, bladeVelY_BF, bladeVelZ_BF, - bladeVelX_GF, bladeVelY_GF, bladeVelZ_GF, - localAzimuth, yaw); - - bladeVelocitiesX[nodeIndex] = bladeVelX_BF; - bladeVelocitiesY[nodeIndex] = bladeVelY_BF + omegas[turbine] * bladeCoordsZ[nodeIndex]; - bladeVelocitiesZ[nodeIndex] = bladeVelZ_BF; -} - -__global__ void applyBodyForces(real* gridCoordsX, real* gridCoordsY, real* gridCoordsZ, - real* gridForcesX, real* gridForcesY, real* gridForcesZ, - real* bladeCoordsX, real* bladeCoordsY, real* bladeCoordsZ, - real* bladeForcesX, real* bladeForcesY, real* bladeForcesZ, - const uint numberOfTurbines, const uint numberOfBlades, const uint numberOfBladeNodes, - real* azimuths, real* yaws, real* diameters, - real* turbPosX, real* turbPosY, real* turbPosZ, - uint* gridIndices, uint nIndices, - const real invEpsilonSqrd, const real factorGaussian) -{ - - const uint index = vf::gpu::getNodeIndex(); - - if (index >= nIndices) return; - - uint gridIndex = gridIndices[index]; - - real gridCoordX_GF = gridCoordsX[gridIndex]; - real gridCoordY_GF = gridCoordsY[gridIndex]; - real gridCoordZ_GF = gridCoordsZ[gridIndex]; - - real gridForceX_RF = c0o1; - real gridForceY_RF = c0o1; - real gridForceZ_RF = c0o1; - - real dAzimuth = c2Pi / numberOfBlades; - - for (uint turbine = 0; turbine < numberOfTurbines; turbine++) { - real radius = c1o2 * diameters[turbine]; - real gridCoordX_RF = gridCoordX_GF - turbPosX[turbine]; - real gridCoordY_RF = gridCoordY_GF - turbPosY[turbine]; - real gridCoordZ_RF = gridCoordZ_GF - turbPosZ[turbine]; - - if (distSqrd(gridCoordX_RF, gridCoordY_RF, gridCoordZ_RF) * invEpsilonSqrd > radius * radius * invEpsilonSqrd + c7o1) continue; - - real azimuth = azimuths[turbine]; - real yaw = yaws[turbine]; - - for (uint blade = 0; blade < numberOfBlades; blade++) { - real localAzimuth = azimuth + blade * dAzimuth; - - real gridCoordX_BF, gridCoordY_BF, gridCoordZ_BF; - - rotateFromGlobalToBlade(gridCoordX_BF, gridCoordY_BF, gridCoordZ_BF, - gridCoordX_RF, gridCoordY_RF, gridCoordZ_RF, - localAzimuth, yaw); - - uint node; - uint nextNode = calcNodeIndexInBladeArrays({ /*.turbine = */ turbine, /* .blade = */ blade, /*.bladeNode =*/0 }, numberOfBladeNodes, numberOfBlades); - - real last_z = c0o1; - real current_z = c0o1; - real next_z = bladeCoordsZ[nextNode]; - - real x, y, dz, eta, forceX_RF, forceY_RF, forceZ_RF; - - for (uint bladeNode = 0; bladeNode < numberOfBladeNodes - 1; bladeNode++) { - node = nextNode; - nextNode = calcNodeIndexInBladeArrays({ /*.turbine = */ turbine, /* .blade = */ blade, /*.bladeNode =*/bladeNode + 1 }, numberOfBladeNodes, numberOfBlades); - - x = bladeCoordsX[node]; - y = bladeCoordsY[node]; - last_z = current_z; - current_z = next_z; - next_z = bladeCoordsZ[nextNode]; - - dz = c1o2 * (next_z - last_z); - - eta = dz * factorGaussian * exp(-distSqrd(x - gridCoordX_BF, y - gridCoordY_BF, current_z - gridCoordZ_BF) * invEpsilonSqrd); - rotateFromBladeToGlobal(bladeForcesX[node], bladeForcesY[node], bladeForcesZ[node], forceX_RF, forceY_RF, forceZ_RF, localAzimuth, yaw); - - gridForceX_RF += forceX_RF * eta; - gridForceY_RF += forceY_RF * eta; - gridForceZ_RF += forceZ_RF * eta; - } - - // Handle last node separately - - node = nextNode; - - x = bladeCoordsX[node]; - y = bladeCoordsY[node]; - last_z = current_z; - current_z = next_z; - - dz = c1o2 * (radius - last_z); - - eta = dz * factorGaussian * exp(-distSqrd(x - gridCoordX_BF, y - gridCoordY_BF, current_z - gridCoordZ_BF) * invEpsilonSqrd); - - rotateFromBladeToGlobal(bladeForcesX[node], bladeForcesY[node], bladeForcesZ[node], - forceX_RF, forceY_RF, forceZ_RF, - localAzimuth, yaw); - - gridForceX_RF += forceX_RF * eta; - gridForceY_RF += forceY_RF * eta; - gridForceZ_RF += forceZ_RF * eta; - } - } - - gridForcesX[gridIndex] += gridForceX_RF; - gridForcesY[gridIndex] += gridForceY_RF; - gridForcesZ[gridIndex] += gridForceZ_RF; -} - -void ActuatorFarm::addTurbine(real posX, real posY, real posZ, real diameter, real omega, real azimuth, real yaw, std::vector<real> bladeRadii) -{ - preInitPosX.push_back(posX); - preInitPosY.push_back(posY); - preInitPosZ.push_back(posZ); - preInitOmegas.push_back(omega); - preInitAzimuths.push_back(azimuth); - preInitYaws.push_back(yaw); - preInitDiameters.push_back(diameter); - preInitBladeRadii.push_back(bladeRadii); -} - -void ActuatorFarm::init(Parameter *para, GridProvider *gridProvider, CudaMemoryManager *cudaMemoryManager) -{ - if (!para->getIsBodyForce()) throw std::runtime_error("try to allocate ActuatorFarm but BodyForce is not set in Parameter."); - this->forceRatio = para->getForceRatio(); - this->initTurbineGeometries(cudaMemoryManager); - this->initBladeCoords(cudaMemoryManager); - this->initBladeIndices(para, cudaMemoryManager); - this->initBladeVelocities(cudaMemoryManager); - this->initBladeForces(cudaMemoryManager); - this->initBoundingSpheres(para, cudaMemoryManager); - this->streamIndex = para->getStreamManager()->registerAndLaunchStream(CudaStreamIndex::ActuatorFarm); -} - -void ActuatorFarm::interact(Parameter *para, CudaMemoryManager *cudaMemoryManager, int level, unsigned int t) -{ - if (level != this->level) return; - - cudaStream_t stream = para->getStreamManager()->getStream(CudaStreamIndex::ActuatorFarm, this->streamIndex); - - if (useHostArrays) cudaMemoryManager->cudaCopyBladeCoordsHtoD(this); - - vf::cuda::CudaGrid bladeGrid = vf::cuda::CudaGrid(para->getParH(level)->numberofthreads, this->numberOfGridNodes); - - // if (t == 0) this->writeBladeCoordsToVtkForDebug("output/ALM/bladecoords_" + std::to_string(t)); - - interpolateVelocities<<< bladeGrid.grid, bladeGrid.threads, 0, stream >>>( - para->getParD(this->level)->coordinateX, para->getParD(this->level)->coordinateY, para->getParD(this->level)->coordinateZ, - para->getParD(this->level)->neighborX, para->getParD(this->level)->neighborY, para->getParD(this->level)->neighborZ, para->getParD(this->level)->neighborInverse, - para->getParD(this->level)->velocityX, para->getParD(this->level)->velocityY, para->getParD(this->level)->velocityZ, - this->bladeCoordsXDCurrentTimestep, this->bladeCoordsYDCurrentTimestep, this->bladeCoordsZDCurrentTimestep, - this->bladeVelocitiesXDCurrentTimestep, this->bladeVelocitiesYDCurrentTimestep, this->bladeVelocitiesZDCurrentTimestep, - this->numberOfTurbines, this->numberOfBlades, this->numberOfBladeNodes, - this->azimuthsD, this->yawsD, this->omegasD, - this->turbinePosXD, this->turbinePosYD, this->turbinePosZD, - this->bladeIndicesD, para->getVelocityRatio(), this->invDeltaX); - - cudaStreamSynchronize(stream); - if (useHostArrays) cudaMemoryManager->cudaCopyBladeVelocitiesDtoH(this); - this->calcBladeForces(); - this->swapDeviceArrays(); - - if (useHostArrays) cudaMemoryManager->cudaCopyBladeForcesHtoD(this); - - vf::cuda::CudaGrid sphereGrid = vf::cuda::CudaGrid(para->getParH(level)->numberofthreads, this->numberOfIndices); - - applyBodyForces<<<sphereGrid.grid, sphereGrid.threads, 0, stream>>>( - para->getParD(this->level)->coordinateX, para->getParD(this->level)->coordinateY, para->getParD(this->level)->coordinateZ, - para->getParD(this->level)->forceX_SP, para->getParD(this->level)->forceY_SP, para->getParD(this->level)->forceZ_SP, - this->bladeCoordsXDCurrentTimestep, this->bladeCoordsYDCurrentTimestep, this->bladeCoordsZDCurrentTimestep, - this->bladeForcesXDCurrentTimestep, this->bladeForcesYDCurrentTimestep, this->bladeForcesZDCurrentTimestep, - this->numberOfTurbines, this->numberOfBlades, this->numberOfBladeNodes, - this->azimuthsD, this->yawsD, this->diametersD, - this->turbinePosXD, this->turbinePosYD, this->turbinePosZD, - this->boundingSphereIndicesD, this->numberOfIndices, - this->invEpsilonSqrd, this->factorGaussian); - cudaMemoryManager->cudaCopyBladeOrientationsHtoD(this); - cudaStreamSynchronize(stream); -} - -void ActuatorFarm::free(Parameter *para, CudaMemoryManager *cudaMemoryManager) -{ - cudaMemoryManager->cudaFreeBladeGeometries(this); - cudaMemoryManager->cudaFreeBladeOrientations(this); - cudaMemoryManager->cudaFreeBladeCoords(this); - cudaMemoryManager->cudaFreeBladeVelocities(this); - cudaMemoryManager->cudaFreeBladeForces(this); - cudaMemoryManager->cudaFreeBladeIndices(this); - cudaMemoryManager->cudaFreeSphereIndices(this); -} - -void ActuatorFarm::calcForcesEllipticWing() -{ - real u_rel, v_rel, u_rel_sq; - real phi; - real Cl = c1o1; - real Cd = c0o1; - real c0 = 20 * c1o10; - real c, Cn, Ct; - - for (uint turbine = 0; turbine < this->numberOfTurbines; turbine++) - { - real diameter = this->diametersH[turbine]; - for (uint blade = 0; blade < this->numberOfBlades; blade++) - { - for (uint bladeNode = 0; bladeNode < this->numberOfBladeNodes; bladeNode++) - { - uint node = calcNodeIndexInBladeArrays({ /*.turbine = */ turbine, /* .blade = */ blade, /*.bladeNode =*/bladeNode }, this->numberOfBladeNodes, this->numberOfBlades); - - u_rel = this->bladeVelocitiesXH[node]; - v_rel = this->bladeVelocitiesYH[node]; - u_rel_sq = u_rel * u_rel + v_rel * v_rel; - phi = atan2(u_rel, v_rel); - - real tmp = c4o1 * this->bladeRadiiH[bladeNode] / diameter - c1o1; - c = c0 * sqrt(c1o1 - tmp * tmp); - Cn = Cl * cos(phi) + Cd * sin(phi); - Ct = Cl * sin(phi) - Cd * cos(phi); - real fx = c1o2 * u_rel_sq * c * this->density * Cn; - real fy = c1o2 * u_rel_sq * c * this->density * Ct; - this->bladeForcesXH[node] = -fx; - this->bladeForcesYH[node] = -fy; - this->bladeForcesZH[node] = c0o1; - // printf("u %f v %f fx %f fy %f \n", u_rel, v_rel, fx, fy); - } - } - azimuthsH[turbine] = azimuthsH[turbine] + deltaT * omegasH[turbine]; - } -} - -void ActuatorFarm::calcBladeForces() -{ - this->calcForcesEllipticWing(); -} - -void ActuatorFarm::getTaggedFluidNodes(Parameter *para, GridProvider *gridProvider) -{ - std::vector<uint> indicesInSphere(this->boundingSphereIndicesH, this->boundingSphereIndicesH + this->numberOfIndices); - gridProvider->tagFluidNodeIndices(indicesInSphere, CollisionTemplate::AllFeatures, this->level); -} - -void ActuatorFarm::initTurbineGeometries(CudaMemoryManager *cudaMemoryManager) -{ - this->numberOfTurbines = uint(this->preInitDiameters.size()); - this->numberOfGridNodes = numberOfTurbines * numberOfBladeNodes * numberOfBlades; - - cudaMemoryManager->cudaAllocBladeGeometries(this); - cudaMemoryManager->cudaAllocBladeOrientations(this); - - for (uint turbine = 0; turbine < this->numberOfTurbines; turbine++) { - for (uint node = 0; node < this->numberOfBladeNodes; node++) { - this->bladeRadiiH[calcNodeIndexInBladeArrays({ /*.turbine = */ turbine, /* .blade = */ 0, /*.bladeNode =*/node }, numberOfBladeNodes, 1)] = this->preInitBladeRadii[turbine][node]; - } - } - std::copy(preInitPosX.begin(), preInitPosX.end(), turbinePosXH); - std::copy(preInitPosY.begin(), preInitPosY.end(), turbinePosYH); - std::copy(preInitPosZ.begin(), preInitPosZ.end(), turbinePosZH); - std::copy(preInitDiameters.begin(), preInitDiameters.end(), diametersH); - - cudaMemoryManager->cudaCopyBladeGeometriesHtoD(this); - std::copy(preInitAzimuths.begin(), preInitAzimuths.end(), this->azimuthsH); - std::copy(preInitOmegas.begin(), preInitOmegas.end(), this->omegasH); - std::copy(preInitYaws.begin(), preInitYaws.end(), this->yawsH); - - cudaMemoryManager->cudaCopyBladeOrientationsHtoD(this); - this->factorGaussian = pow(this->epsilon * sqrt(cPi), -c3o1) / this->forceRatio; -} - -void ActuatorFarm::initBladeCoords(CudaMemoryManager *cudaMemoryManager) -{ - cudaMemoryManager->cudaAllocBladeCoords(this); - - for (uint turbine = 0; turbine < numberOfTurbines; turbine++) - { - for (uint blade = 0; blade < this->numberOfBlades; blade++) - { - for (uint bladeNode = 0; bladeNode < this->numberOfBladeNodes; bladeNode++) { - uint node = calcNodeIndexInBladeArrays({ /*.turbine = */ turbine, /* .blade = */ blade, /*.bladeNode =*/bladeNode }, this->numberOfBladeNodes, this->numberOfBlades); - - this->bladeCoordsXH[node] = c0o1; - this->bladeCoordsYH[node] = c0o1; - this->bladeCoordsZH[node] = this->bladeRadiiH[calcNodeIndexInBladeArrays({ /*.turbine = */ turbine, /* .blade = */ 0, /*.bladeNode =*/bladeNode }, numberOfBladeNodes, 1)]; - } - } - } - cudaMemoryManager->cudaCopyBladeCoordsHtoD(this); - swapArrays(this->bladeCoordsXDCurrentTimestep, this->bladeCoordsXDPreviousTimestep); - swapArrays(this->bladeCoordsYDCurrentTimestep, this->bladeCoordsYDPreviousTimestep); - swapArrays(this->bladeCoordsZDCurrentTimestep, this->bladeCoordsZDPreviousTimestep); - cudaMemoryManager->cudaCopyBladeCoordsHtoD(this); -} - -void ActuatorFarm::initBladeVelocities(CudaMemoryManager *cudaMemoryManager) -{ - cudaMemoryManager->cudaAllocBladeVelocities(this); - - std::fill_n(this->bladeVelocitiesXH, this->numberOfGridNodes, c0o1); - std::fill_n(this->bladeVelocitiesYH, this->numberOfGridNodes, c0o1); - std::fill_n(this->bladeVelocitiesZH, this->numberOfGridNodes, c0o1); - - cudaMemoryManager->cudaCopyBladeVelocitiesHtoD(this); - swapArrays(this->bladeVelocitiesXDCurrentTimestep, this->bladeVelocitiesXDPreviousTimestep); - swapArrays(this->bladeVelocitiesYDCurrentTimestep, this->bladeVelocitiesYDPreviousTimestep); - swapArrays(this->bladeVelocitiesZDCurrentTimestep, this->bladeVelocitiesZDPreviousTimestep); - cudaMemoryManager->cudaCopyBladeVelocitiesHtoD(this); -} - -void ActuatorFarm::initBladeForces(CudaMemoryManager *cudaMemoryManager) -{ - cudaMemoryManager->cudaAllocBladeForces(this); - - std::fill_n(this->bladeForcesXH, this->numberOfGridNodes, c0o1); - std::fill_n(this->bladeForcesYH, this->numberOfGridNodes, c0o1); - std::fill_n(this->bladeForcesZH, this->numberOfGridNodes, c0o1); - - cudaMemoryManager->cudaCopyBladeForcesHtoD(this); - swapArrays(this->bladeForcesXDCurrentTimestep, this->bladeForcesXDPreviousTimestep); - swapArrays(this->bladeForcesYDCurrentTimestep, this->bladeForcesYDPreviousTimestep); - swapArrays(this->bladeForcesZDCurrentTimestep, this->bladeForcesZDPreviousTimestep); - cudaMemoryManager->cudaCopyBladeForcesHtoD(this); -} - -void ActuatorFarm::initBladeIndices(Parameter *para, CudaMemoryManager *cudaMemoryManager) -{ - cudaMemoryManager->cudaAllocBladeIndices(this); - - std::fill_n(this->bladeIndicesH, this->numberOfGridNodes, 1); - - cudaMemoryManager->cudaCopyBladeIndicesHtoD(this); -} - -void ActuatorFarm::initBoundingSpheres(Parameter *para, CudaMemoryManager *cudaMemoryManager) -{ - std::vector<int> nodesInSpheres; - - for (uint turbine = 0; turbine < this->numberOfTurbines; turbine++) { - real sphereRadius = c1o2 * this->diametersH[turbine] + c4o1 * this->epsilon; - - real posX = this->turbinePosXH[turbine]; - real posY = this->turbinePosYH[turbine]; - real posZ = this->turbinePosZH[turbine]; - - real sphereRadiusSqrd = sphereRadius * sphereRadius; - - uint minimumNumberOfNodesPerSphere = - (uint)(c4o3 * cPi * pow(sphereRadius - this->deltaX, c3o1) / pow(this->deltaX, c3o1)); - uint nodesInThisSphere = 0; - - for (size_t pos = 1; pos <= para->getParH(this->level)->numberOfNodes; pos++) { - const real distX = para->getParH(this->level)->coordinateX[pos] - posX; - const real distY = para->getParH(this->level)->coordinateY[pos] - posY; - const real distZ = para->getParH(this->level)->coordinateZ[pos] - posZ; - if (distSqrd(distX, distY, distZ) < sphereRadiusSqrd) { - nodesInSpheres.push_back((int)pos); - nodesInThisSphere++; - } - } - - if (nodesInThisSphere < minimumNumberOfNodesPerSphere) { - VF_LOG_CRITICAL("Found only {} nodes in bounding sphere of turbine no. {}, expected at least {}!", nodesInThisSphere, turbine, minimumNumberOfNodesPerSphere); - throw std::runtime_error("ActuatorFarm::initBoundingSpheres: Turbine bounding sphere partially out of domain."); - } - } - - this->numberOfIndices = uint(nodesInSpheres.size()); - - cudaMemoryManager->cudaAllocSphereIndices(this); - std::copy(nodesInSpheres.begin(), nodesInSpheres.end(), this->boundingSphereIndicesH); - cudaMemoryManager->cudaCopySphereIndicesHtoD(this); -} - -void ActuatorFarm::setAllAzimuths(real *_azimuths) -{ - std::copy_n(_azimuths, this->numberOfTurbines, this->azimuthsH); -} - -void ActuatorFarm::setAllOmegas(real *_omegas) -{ - std::copy_n(_omegas, this->numberOfTurbines, this->omegasH); -} - -void ActuatorFarm::setAllYaws(real *_yaws) -{ - std::copy_n(_yaws, this->numberOfTurbines, this->yawsH); -} - -void ActuatorFarm::setAllBladeCoords(real *_bladeCoordsX, real *_bladeCoordsY, real *_bladeCoordsZ) -{ - std::copy_n(_bladeCoordsX, this->numberOfGridNodes, this->bladeCoordsXH); - std::copy_n(_bladeCoordsY, this->numberOfGridNodes, this->bladeCoordsYH); - std::copy_n(_bladeCoordsZ, this->numberOfGridNodes, this->bladeCoordsZH); -} - -void ActuatorFarm::setAllBladeVelocities(real *_bladeVelocitiesX, real *_bladeVelocitiesY, real *_bladeVelocitiesZ) -{ - std::copy_n(_bladeVelocitiesX, this->numberOfGridNodes, this->bladeVelocitiesXH); - std::copy_n(_bladeVelocitiesY, this->numberOfGridNodes, this->bladeVelocitiesYH); - std::copy_n(_bladeVelocitiesZ, this->numberOfGridNodes, this->bladeVelocitiesZH); -} - -void ActuatorFarm::setAllBladeForces(real *_bladeForcesX, real *_bladeForcesY, real *_bladeForcesZ) -{ - std::copy_n(_bladeForcesX, this->numberOfGridNodes, this->bladeForcesXH); - std::copy_n(_bladeForcesY, this->numberOfGridNodes, this->bladeForcesYH); - std::copy_n(_bladeForcesZ, this->numberOfGridNodes, this->bladeForcesZH); -} -void ActuatorFarm::setTurbineBladeCoords(uint turbine, real *_bladeCoordsX, real *_bladeCoordsY, real *_bladeCoordsZ) -{ - std::copy_n(_bladeCoordsX, numberOfBladeNodes * numberOfBlades, &this->bladeCoordsXH[turbine * numberOfBladeNodes * numberOfBlades]); - std::copy_n(_bladeCoordsY, numberOfBladeNodes * numberOfBlades, &this->bladeCoordsYH[turbine * numberOfBladeNodes * numberOfBlades]); - std::copy_n(_bladeCoordsZ, numberOfBladeNodes * numberOfBlades, &this->bladeCoordsZH[turbine * numberOfBladeNodes * numberOfBlades]); -} - -void ActuatorFarm::setTurbineBladeVelocities(uint turbine, real *_bladeVelocitiesX, real *_bladeVelocitiesY, real *_bladeVelocitiesZ) -{ - std::copy_n(_bladeVelocitiesX, numberOfBladeNodes * numberOfBlades, &this->bladeVelocitiesXH[turbine * numberOfBladeNodes * numberOfBlades]); - std::copy_n(_bladeVelocitiesY, numberOfBladeNodes * numberOfBlades, &this->bladeVelocitiesYH[turbine * numberOfBladeNodes * numberOfBlades]); - std::copy_n(_bladeVelocitiesZ, numberOfBladeNodes * numberOfBlades, &this->bladeVelocitiesZH[turbine * numberOfBladeNodes * numberOfBlades]); -} - -void ActuatorFarm::setTurbineBladeForces(uint turbine, real *_bladeForcesX, real *_bladeForcesY, real *_bladeForcesZ) -{ - std::copy_n(_bladeForcesX, numberOfBladeNodes * numberOfBlades, &this->bladeForcesXH[turbine * numberOfBladeNodes * numberOfBlades]); - std::copy_n(_bladeForcesY, numberOfBladeNodes * numberOfBlades, &this->bladeForcesYH[turbine * numberOfBladeNodes * numberOfBlades]); - std::copy_n(_bladeForcesZ, numberOfBladeNodes * numberOfBlades, &this->bladeForcesZH[turbine * numberOfBladeNodes * numberOfBlades]); -} - -void ActuatorFarm::swapDeviceArrays() -{ - swapArrays(this->bladeCoordsXDPreviousTimestep, this->bladeCoordsXDCurrentTimestep); - swapArrays(this->bladeCoordsYDPreviousTimestep, this->bladeCoordsYDCurrentTimestep); - swapArrays(this->bladeCoordsZDPreviousTimestep, this->bladeCoordsZDCurrentTimestep); - - swapArrays(this->bladeVelocitiesXDPreviousTimestep, this->bladeVelocitiesXDCurrentTimestep); - swapArrays(this->bladeVelocitiesYDPreviousTimestep, this->bladeVelocitiesYDCurrentTimestep); - swapArrays(this->bladeVelocitiesZDPreviousTimestep, this->bladeVelocitiesZDCurrentTimestep); - - swapArrays(this->bladeForcesXDPreviousTimestep, this->bladeForcesXDCurrentTimestep); - swapArrays(this->bladeForcesYDPreviousTimestep, this->bladeForcesYDCurrentTimestep); - swapArrays(this->bladeForcesZDPreviousTimestep, this->bladeForcesZDCurrentTimestep); -} - -void ActuatorFarm::writeBladeCoordsToVtkForDebug(const std::string &filename) -{ - std::vector<real> coordsX(numberOfGridNodes); - std::vector<real> coordsY(numberOfGridNodes); - std::vector<real> coordsZ(numberOfGridNodes); - - for (uint nodeIndex = 0; nodeIndex < numberOfGridNodes; nodeIndex++) { - auto [turbine, blade, bladeNodeIndexOnBlade] = calcTurbineBladeAndBladeNode(nodeIndex, numberOfBladeNodes, numberOfBlades); - - const real localAzimuth = this->getTurbineAzimuth(turbine) + blade * c2Pi / numberOfBlades; - const real yaw = this->getTurbineYaw(turbine); - real bladeCoordX_GF; - real bladeCoordY_GF; - real bladeCoordZ_GF; - calcCoordinateOfBladeNodeInGridFrameOfReference(nodeIndex, turbine, localAzimuth, yaw, this->bladeCoordsXH, this->bladeCoordsYH, this->bladeCoordsZH, this->turbinePosXH, this->turbinePosYH, this->turbinePosZH, bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF); - coordsX[nodeIndex] = bladeCoordX_GF; - coordsY[nodeIndex] = bladeCoordY_GF; - coordsZ[nodeIndex] = bladeCoordZ_GF; - } - - WbWriterVtkXmlBinary::getInstance()->writePolyLines(filename, coordsX, coordsY, coordsZ); -} \ No newline at end of file diff --git a/src/gpu/core/PreCollisionInteractor/ActuatorFarm.h b/src/gpu/core/PreCollisionInteractor/ActuatorFarm.h deleted file mode 100644 index 74f23f3e6a4dc9e3e798ca13aa3632171d0e3bd0..0000000000000000000000000000000000000000 --- a/src/gpu/core/PreCollisionInteractor/ActuatorFarm.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef ActuatorFarm_H -#define ActuatorFarm_H - -#include "PreCollisionInteractor.h" -#include <basics/PointerDefinitions.h> -#include "basics/constants/NumericConstants.h" -#include <stdexcept> - -using namespace vf::basics::constant; - -class Parameter; -class GridProvider; -using namespace vf::basics::constant; - -class ActuatorFarm : public PreCollisionInteractor -{ -public: - ActuatorFarm( - const uint _nBlades, - const real _density, - const uint _nBladeNodes, - const real _epsilon, - int _level, - const real _deltaT, - const real _deltaX, - const bool _useHostArrays - ) : - numberOfBlades(_nBlades), - density(_density), - numberOfBladeNodes(_nBladeNodes), - epsilon(_epsilon), - level(_level), - useHostArrays(_useHostArrays), - numberOfTurbines(0), - numberOfGridNodes(0), - PreCollisionInteractor() - { - this->deltaT = _deltaT*exp2(-this->level); - this->deltaX = _deltaX*exp2(-this->level); - this->invEpsilonSqrd = 1/(epsilon*epsilon); - this->invDeltaX = c1o1/this->deltaX; - - if(this->epsilon<this->deltaX) - throw std::runtime_error("ActuatorFarm::ActuatorFarm: epsilon needs to be larger than dx!"); - } - - ~ActuatorFarm() override = default; - void addTurbine(real turbinePosX, real turbinePosY, real turbinePosZ, real diameter, real omega, real azimuth, real yaw, std::vector<real> bladeRadii); - void init(Parameter* para, GridProvider* gridProvider, CudaMemoryManager* cudaManager) override; - void interact(Parameter* para, CudaMemoryManager* cudaManager, int level, uint t) override; - void free(Parameter* para, CudaMemoryManager* cudaManager) override; - void getTaggedFluidNodes(Parameter *para, GridProvider* gridProvider) override; - - void write(uint t); - - real getDensity(){ return this->density; }; - real getDeltaT(){ return this->deltaT; }; - real getDeltaX(){ return this->deltaX; }; - - uint getNumberOfTurbines(){ return this->numberOfTurbines; }; - uint getNumberOfNodesPerBlade(){ return this->numberOfBladeNodes; }; - uint getNumberOfBladesPerTurbine(){ return this->numberOfBlades; }; - - uint getNumberOfIndices(){ return this->numberOfIndices; }; - uint getNumberOfGridNodes(){ return this->numberOfGridNodes; }; - - real* getAllAzimuths(){ return azimuthsH; }; - real* getAllOmegas(){ return omegasH; }; - real* getAllYaws(){ return yawsH; }; - - real* getAllTurbinePosX(){ return turbinePosXH; }; - real* getAllTurbinePosY(){ return turbinePosYH; }; - real* getAllTurbinePosZ(){ return turbinePosZH; }; - - real getTurbineAzimuth(uint turbine){ return azimuthsH[turbine]; }; - real getTurbineOmega (uint turbine){ return omegasH[turbine]; }; - real getTurbineYaw (uint turbine){ return yawsH[turbine]; }; - - real getTurbinePosX(uint turbine){ return turbinePosXH[turbine]; }; - real getTurbinePosY(uint turbine){ return turbinePosYH[turbine]; }; - real getTurbinePosZ(uint turbine){ return turbinePosZH[turbine]; }; - - real* getAllBladeRadii(){ return this->bladeRadiiH; }; - real* getAllBladeCoordsX(){ return this->bladeCoordsXH; }; - real* getAllBladeCoordsY(){ return this->bladeCoordsYH; }; - real* getAllBladeCoordsZ(){ return this->bladeCoordsZH; }; - real* getAllBladeVelocitiesX(){ return this->bladeVelocitiesXH; }; - real* getAllBladeVelocitiesY(){ return this->bladeVelocitiesYH; }; - real* getAllBladeVelocitiesZ(){ return this->bladeVelocitiesZH; }; - real* getAllBladeForcesX(){ return this->bladeForcesXH; }; - real* getAllBladeForcesY(){ return this->bladeForcesYH; }; - real* getAllBladeForcesZ(){ return this->bladeForcesZH; }; - - real* getTurbineBladeRadii(uint turbine){ return &this->bladeRadiiH[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeCoordsX(uint turbine){ return &this->bladeCoordsXH[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeCoordsY(uint turbine){ return &this->bladeCoordsYH[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeCoordsZ(uint turbine){ return &this->bladeCoordsZH[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeVelocitiesX(uint turbine){ return &this->bladeVelocitiesXH[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeVelocitiesY(uint turbine){ return &this->bladeVelocitiesYH[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeVelocitiesZ(uint turbine){ return &this->bladeVelocitiesZH[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeForcesX(uint turbine){ return &this->bladeForcesXH[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeForcesY(uint turbine){ return &this->bladeForcesYH[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeForcesZ(uint turbine){ return &this->bladeForcesZH[turbine*numberOfBladeNodes*numberOfBlades]; }; - - real* getAllBladeRadiiDevice(){ return this->bladeRadiiD; }; - real* getAllBladeCoordsXDevice(){ return this->bladeCoordsXDCurrentTimestep; }; - real* getAllBladeCoordsYDevice(){ return this->bladeCoordsYDCurrentTimestep; }; - real* getAllBladeCoordsZDevice(){ return this->bladeCoordsZDCurrentTimestep; }; - real* getAllBladeVelocitiesXDevice(){ return this->bladeVelocitiesXDCurrentTimestep; }; - real* getAllBladeVelocitiesYDevice(){ return this->bladeVelocitiesYDCurrentTimestep; }; - real* getAllBladeVelocitiesZDevice(){ return this->bladeVelocitiesZDCurrentTimestep; }; - real* getAllBladeForcesXDevice(){ return this->bladeForcesXDCurrentTimestep; }; - real* getAllBladeForcesYDevice(){ return this->bladeForcesYDCurrentTimestep; }; - real* getAllBladeForcesZDevice(){ return this->bladeForcesZDCurrentTimestep; }; - - real* getTurbineBladeRadiiDevice(uint turbine){ return &this->bladeRadiiD[turbine*numberOfBladeNodes]; }; - real* getTurbineBladeCoordsXDevice(uint turbine){ return &this->bladeCoordsXDCurrentTimestep[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeCoordsYDevice(uint turbine){ return &this->bladeCoordsYDCurrentTimestep[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeCoordsZDevice(uint turbine){ return &this->bladeCoordsZDCurrentTimestep[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeVelocitiesXDevice(uint turbine){ return &this->bladeVelocitiesXDCurrentTimestep[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeVelocitiesYDevice(uint turbine){ return &this->bladeVelocitiesYDCurrentTimestep[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeVelocitiesZDevice(uint turbine){ return &this->bladeVelocitiesZDCurrentTimestep[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeForcesXDevice(uint turbine){ return &this->bladeForcesXDCurrentTimestep[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeForcesYDevice(uint turbine){ return &this->bladeForcesYDCurrentTimestep[turbine*numberOfBladeNodes*numberOfBlades]; }; - real* getTurbineBladeForcesZDevice(uint turbine){ return &this->bladeForcesZDCurrentTimestep[turbine*numberOfBladeNodes*numberOfBlades]; }; - - void setAllAzimuths(real* _azimuth); - void setAllOmegas(real* _omegas); - void setAllYaws(real* yaws); - - void setTurbineAzimuth(uint turbine, real azimuth){ azimuthsH[turbine] = azimuth; }; - void setTurbineYaw(uint turbine, real yaw){ yawsH[turbine] = yaw; }; - void setTurbineOmega(uint turbine, real omega){ omegasH[turbine] = omega; }; - - void setAllBladeCoords(real* _bladeCoordsX, real* _bladeCoordsY, real* _bladeCoordsZ); - void setAllBladeVelocities(real* _bladeVelocitiesX, real* _bladeVelocitiesY, real* _bladeVelocitiesZ); - void setAllBladeForces(real* _bladeForcesX, real* _bladeForcesY, real* _bladeForcesZ); - - void setTurbineBladeCoords(uint turbine, real* _bladeCoordsX, real* _bladeCoordsY, real* _bladeCoordsZ); - void setTurbineBladeVelocities(uint turbine, real* _bladeVelocitiesX, real* _bladeVelocitiesY, real* _bladeVelocitiesZ); - void setTurbineBladeForces(uint turbine, real* _bladeForcesX, real* _bladeForcesY, real* _bladeForcesZ); - - virtual void calcBladeForces(); - -private: - void initTurbineGeometries(CudaMemoryManager* cudaManager); - void initBoundingSpheres(Parameter* para, CudaMemoryManager* cudaManager); - void initBladeCoords(CudaMemoryManager* cudaManager); - void initBladeVelocities(CudaMemoryManager* cudaManager); - void initBladeForces(CudaMemoryManager* cudaManager); - void initBladeIndices(Parameter* para, CudaMemoryManager* cudaManager); - - void calcForcesEllipticWing(); - void rotateBlades(real angle, uint turbineID); - - void writeBladeCoords(uint t); - void writeBladeCoordsToVtkForDebug(const std::string& filename); - void writeBladeForces(uint t); - void writeBladeVelocities(uint t); - - void swapDeviceArrays(); - -public: - real* bladeRadiiH; - real* bladeRadiiD; - real* bladeCoordsXH, * bladeCoordsYH, * bladeCoordsZH; - real* bladeCoordsXDPreviousTimestep, * bladeCoordsYDPreviousTimestep, * bladeCoordsZDPreviousTimestep; - real* bladeCoordsXDCurrentTimestep, * bladeCoordsYDCurrentTimestep, * bladeCoordsZDCurrentTimestep; - real* bladeVelocitiesXH, * bladeVelocitiesYH, * bladeVelocitiesZH; - real* bladeVelocitiesXDPreviousTimestep, * bladeVelocitiesYDPreviousTimestep, * bladeVelocitiesZDPreviousTimestep; - real* bladeVelocitiesXDCurrentTimestep, * bladeVelocitiesYDCurrentTimestep, * bladeVelocitiesZDCurrentTimestep; - real* bladeForcesXH, * bladeForcesYH, * bladeForcesZH; - real* bladeForcesXDPreviousTimestep, * bladeForcesYDPreviousTimestep, * bladeForcesZDPreviousTimestep; - real* bladeForcesXDCurrentTimestep, * bladeForcesYDCurrentTimestep, * bladeForcesZDCurrentTimestep; - uint* bladeIndicesH; - uint* bladeIndicesD; - uint* boundingSphereIndicesH; - uint* boundingSphereIndicesD; - real* turbinePosXH, *turbinePosYH, *turbinePosZH, *omegasH, *azimuthsH, *yawsH, *diametersH; - real* turbinePosXD, *turbinePosYD, *turbinePosZD, *omegasD, *azimuthsD, *yawsD, *diametersD; - -private: - std::vector<real> preInitPosX, preInitPosY, preInitPosZ, preInitDiameters, preInitOmegas, preInitAzimuths, preInitYaws; - std::vector<std::vector<real>> preInitBladeRadii; - const bool useHostArrays; - const real density; - real deltaT, deltaX; - const uint numberOfBladeNodes, numberOfBlades; - uint numberOfTurbines; - const real epsilon; // in m - const int level; - uint numberOfIndices; - uint numberOfGridNodes; - real forceRatio, factorGaussian, invEpsilonSqrd, invDeltaX; - int streamIndex; -}; - -#endif diff --git a/src/parallel/CMakeLists.txt b/src/parallel/CMakeLists.txt index 742ebc3631ed3419bae3ebf1a67b40baf6a5be28..5fe3586c83bf9ffb3c46bf84ed9c91f57558ea6c 100644 --- a/src/parallel/CMakeLists.txt +++ b/src/parallel/CMakeLists.txt @@ -1,6 +1,11 @@ -vf_add_library(PUBLIC_LINK logger MPI::MPI_CXX basics) +vf_add_library(PUBLIC_LINK logger) if(MSVC) target_link_libraries(parallel PRIVATE ws2_32) endif() + +# TODO: https://git.rz.tu-bs.de/irmb/VirtualFluids_dev/-/issues/139 +# if(BUILD_USE_MPI) + target_link_libraries(parallel PUBLIC MPI::MPI_CXX) +# endif() diff --git a/src/parallel/Communicator.h b/src/parallel/Communicator.h index 23a760981944cfa143d7521275255f39a92bb7fe..815f5540039d8ed905b0d928d663f6dfba60b95a 100644 --- a/src/parallel/Communicator.h +++ b/src/parallel/Communicator.h @@ -55,6 +55,8 @@ public: virtual ~Communicator() = default; + + virtual double Wtime() = 0; virtual int getBundleID() const = 0; virtual int getNumberOfBundles() const = 0; virtual int getProcessID() const = 0; diff --git a/src/parallel/MPICommunicator.cpp b/src/parallel/MPICommunicator.cpp index 8ae7ea66387f5e02b2e90dcacefbc324e81ca564..4aff91ea2b746ff241ad54583d4e6c0d13ec2066 100644 --- a/src/parallel/MPICommunicator.cpp +++ b/src/parallel/MPICommunicator.cpp @@ -17,6 +17,11 @@ using namespace std; namespace vf::parallel { +////////////////////////////////////////////////////////////////////////// +double MPICommunicator::Wtime() +{ + return MPI_Wtime(); +} std::shared_ptr<Communicator> MPICommunicator::getInstance() { std::lock_guard<std::mutex> myLock(instantiation_mutex); diff --git a/src/parallel/MPICommunicator.h b/src/parallel/MPICommunicator.h index 466a3c3f8d311c743b546116a0a4ca9a23735488..66e00893473b4861f2af21e39d1e44c64348d7e8 100644 --- a/src/parallel/MPICommunicator.h +++ b/src/parallel/MPICommunicator.h @@ -33,6 +33,7 @@ public: ~MPICommunicator() override; static std::shared_ptr<Communicator> getInstance(); + double Wtime() override; int getBundleID() const override; int getNumberOfBundles() const override; int getProcessID() const override; diff --git a/src/parallel/NullCommunicator.cpp b/src/parallel/NullCommunicator.cpp index 56c17a8c3c466dae3299d0b32f9e918c68cc1610..3bac9fe2c80d63871476e9741ae5599f4a977d07 100644 --- a/src/parallel/NullCommunicator.cpp +++ b/src/parallel/NullCommunicator.cpp @@ -47,6 +47,11 @@ std::shared_ptr<Communicator> NullCommunicator::getInstance() return instance; } ////////////////////////////////////////////////////////////////////////// +double NullCommunicator::Wtime() +{ + return 0; +} +////////////////////////////////////////////////////////////////////////// int NullCommunicator::getBundleID() const { return 0; diff --git a/src/parallel/NullCommunicator.h b/src/parallel/NullCommunicator.h index 295f946dbe8dd05c89ec57b733aa84867b5bea70..dc49fb3b7fae0b277e960d8f04c54abfc0731a13 100644 --- a/src/parallel/NullCommunicator.h +++ b/src/parallel/NullCommunicator.h @@ -46,6 +46,7 @@ class NullCommunicator : public Communicator public: static std::shared_ptr<Communicator> getInstance(); + double Wtime() override; int getBundleID() const override; int getNumberOfBundles() const override; int getProcessID() const override;