File indexing completed on 2024-04-28 03:40:49
0001 // Aqsis 0002 // Copyright (C) 2006, Paul C. Gregory 0003 // 0004 // Contact: pgregory@aqsis.org 0005 // 0006 // This library is free software; you can redistribute it and/or 0007 // modify it under the terms of the GNU General Public 0008 // License as published by the Free Software Foundation; either 0009 // version 2 of the License, or (at your option) any later version. 0010 // 0011 // This library is distributed in the hope that it will be useful, 0012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 // General Public License for more details. 0015 // 0016 // You should have received a copy of the GNU General Public 0017 // License along with this library; if not, write to the Free Software 0018 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 0019 0020 /** \file 0021 \brief MarchingCubes Algorithm 0022 \author Thomas Lewiner <thomas.lewiner@polytechnique.org> 0023 \author Math Dept, PUC-Rio 0024 \version 0.2 0025 \date 12/08/2002 0026 */ 0027 0028 // Minor modifications for KDE-Edu/Analitza Library: Copyright (C) 2014 by Percy Camilo T. Aucahuasi <percy.camilo.ta@gmail.com> 0029 0030 #ifndef MARCHINGCUBES_H 0031 #define MARCHINGCUBES_H 0032 0033 #include <QVector> 0034 0035 struct SpaceLimits { 0036 double minX; 0037 double maxX; 0038 double minY; 0039 double maxY; 0040 double minZ; 0041 double maxZ; 0042 }; 0043 0044 0045 0046 0047 0048 0049 // Compute normals 0050 #define COMPUTE_NORMALS 1 0051 0052 #include <QDebug> 0053 // types 0054 //----------------------------------------------------------------------------- 0055 // Vertex structure 0056 /** \struct Vertex "MarchingCubes.h" MarchingCubes 0057 * Position and normal of a vertex 0058 * \brief vertex structure 0059 * \param x X coordinate 0060 * \param y Y coordinate 0061 * \param z Z coordinate 0062 * \param nx X component of the normal 0063 * \param ny Y component of the normal 0064 * \param nz Z component of the normal 0065 */ 0066 typedef struct 0067 { 0068 double x, y, z ; /**< Vertex coordinates */ 0069 #ifdef COMPUTE_NORMALS 0070 double nx, ny, nz ; /**< Vertex normal */ 0071 #endif 0072 } Vertex ; 0073 0074 //----------------------------------------------------------------------------- 0075 // Triangle structure 0076 /** \struct Triangle "MarchingCubes.h" MarchingCubes 0077 * Indices of the oriented triange vertices 0078 * \brief triangle structure 0079 * \param v1 First vertex index 0080 * \param v2 Second vertex index 0081 * \param v3 Third vertex index 0082 */ 0083 typedef struct 0084 { 0085 int v1,v2,v3 ; /**< Triangle vertices */ 0086 } Triangle ; 0087 //_____________________________________________________________________________ 0088 0089 0090 0091 //_____________________________________________________________________________ 0092 /** Marching Cubes algorithm wrapper */ 0093 class MarchingCubes 0094 //----------------------------------------------------------------------------- 0095 { 0096 // Constructors 0097 public : 0098 /** 0099 * Main and default constructor 0100 * \brief constructor 0101 * \param size_x width of the grid 0102 * \param size_y depth of the grid 0103 * \param size_z height of the grid 0104 */ 0105 MarchingCubes () ; 0106 /** Destructor */ 0107 virtual ~MarchingCubes() ; 0108 0109 virtual double evalScalarField(double x, double y, double z) = 0; 0110 void setupSpace(const SpaceLimits &spaceLimits); 0111 void buildGeometry() {run();} 0112 0113 //----------------------------------------------------------------------------- 0114 // Accessors 0115 0116 /** accesses the number of vertices of the generated mesh */ 0117 int nverts() const { return i_nverts ; } 0118 /** accesses the number of triangles of the generated mesh */ 0119 int ntrigs() const { return i_ntrigs ; } 0120 /** accesses a specific vertex of the generated mesh */ 0121 Vertex * vert( const int i ) const { if( i < 0 || i >= i_nverts ) return ( Vertex *)nullptr ; return i_vertices + i ; } 0122 /** accesses a specific triangle of the generated mesh */ 0123 Triangle * trig( const int i ) const { if( i < 0 || i >= i_ntrigs ) return (Triangle*)nullptr ; return i_triangles + i ; } 0124 0125 /** accesses the vertex buffer of the generated mesh */ 0126 Vertex *mc_vertices () { return i_vertices ; } 0127 /** accesses the triangle buffer of the generated mesh */ 0128 Triangle *triangles() { return i_triangles ; } 0129 0130 /** accesses the width of the grid */ 0131 int size_x() const { return i_size_x ; } 0132 /** accesses the depth of the grid */ 0133 int size_y() const { return i_size_y ; } 0134 /** accesses the height of the grid */ 0135 int size_z() const { return i_size_z ; } 0136 0137 /** 0138 * changes the size of the grid 0139 * \param size_x width of the grid 0140 * \param size_y depth of the grid 0141 * \param size_z height of the grid 0142 * se encesita llamar a setup space y buildgeometry para que se tome efecto ... esto solo cambia los attr de la clase 0143 */ 0144 void set_resolution( const int size_x, const int size_y, const int size_z ) { i_size_x = size_x ; i_size_y = size_y ; i_size_z = size_z ; } 0145 0146 0147 0148 // Data access 0149 /** 0150 * accesses a specific cube of the grid 0151 * \param i abscisse of the cube 0152 * \param j ordinate of the cube 0153 * \param k height of the cube 0154 */ 0155 double get_data ( const int i, const int j, const int k ) const { return i_data[ i + j*i_size_x + k*i_size_x*i_size_y] ; } 0156 0157 //eval de analitza es muy costoso, asi que este aproach esta deprecated... es mejor el triple bucle para llenar la data 0158 // const double get_data ( const int i, const int j, const int k ) 0159 // { 0160 // double x = xmin+hx*i; 0161 // double y = ymin+hy*j; 0162 // double z = zmin+hz*k; 0163 // 0164 // // qDebug() << x << y << z; 0165 // 0166 // return evalScalarField(x,y,z); 0167 // } 0168 0169 0170 /** 0171 * sets a specific cube of the grid 0172 * \param val new value for the cube 0173 * \param i abscisse of the cube 0174 * \param j ordinate of the cube 0175 * \param k height of the cube 0176 */ 0177 void set_data ( const double val, const int i, const int j, const int k ) { i_data[ i + j*i_size_x + k*i_size_x*i_size_y] = val ; } 0178 0179 private: 0180 /** 0181 * selects whether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes 0182 * \param originalMC true for the original Marching Cubes 0183 * DEPRECATED el metodo original no tiene consistencia topologica 0184 */ 0185 void set_method ( const bool originalMC = false ) { i_originalMC = originalMC ; } 0186 0187 // Data initialization 0188 /** inits temporary structures (must set sizes before call) : the grid and the vertex index per cube */ 0189 void init_temps () ; 0190 /** inits all structures (must set sizes before call) : the temporary structures and the mesh buffers */ 0191 void init_all () ; 0192 /** clears temporary structures : the grid and the main */ 0193 void clean_temps() ; 0194 /** clears all structures : the temporary structures and the mesh buffers */ 0195 void clean_all () ; 0196 0197 0198 //----------------------------------------------------------------------------- 0199 // Exportation 0200 public : 0201 /** 0202 * GTS exportation of the generated mesh 0203 * \param fn name of the GTS file to create 0204 * \param bin if true, the GTS will be written in binary mode 0205 */ 0206 void write( const char *fn, bool bin = false ) ; 0207 0208 0209 //----------------------------------------------------------------------------- 0210 // Algorithm 0211 private : 0212 /** Main algorithm : must be called after init_all */ 0213 void run() ; 0214 0215 private : 0216 /** tesselates one cube */ 0217 void process_cube () ; 0218 /** tests if the components of the tesselation of the cube should be connected by the interior of an ambiguous face */ 0219 bool test_face ( int face ) ; 0220 /** tests if the components of the tesselation of the cube should be connected through the interior of the cube */ 0221 bool test_interior( int s ) ; 0222 0223 0224 //----------------------------------------------------------------------------- 0225 // Operations 0226 private : 0227 /** computes almost all the vertices of the mesh by interpolation along the cubes edges */ 0228 void compute_intersection_points() ; 0229 0230 /** 0231 * routine to add a triangle to the mesh 0232 * \param trig the code for the triangle as a sequence of edges index 0233 * \param n the number of triangles to produce 0234 * \param v12 the index of the interior vertex to use, if necessary 0235 */ 0236 void add_triangle ( const int* trig, char n, int v12 = -1 ) ; 0237 0238 /** tests and eventually doubles the vertex buffer capacity for a new vertex insertion */ 0239 void test_vertex_addition() ; 0240 /** adds a vertex on the current horizontal edge */ 0241 int add_x_vertex() ; 0242 /** adds a vertex on the current longitudinal edge */ 0243 int add_y_vertex() ; 0244 /** adds a vertex on the current vertical edge */ 0245 int add_z_vertex() ; 0246 /** adds a vertex inside the current cube */ 0247 int add_c_vertex() ; 0248 0249 /** 0250 * interpolates the horizontal gradient of the implicit function at the lower vertex of the specified cube 0251 * \param i abscisse of the cube 0252 * \param j ordinate of the cube 0253 * \param k height of the cube 0254 */ 0255 double get_x_grad( const int i, const int j, const int k ) ; 0256 /** 0257 * interpolates the longitudinal gradient of the implicit function at the lower vertex of the specified cube 0258 * \param i abscisse of the cube 0259 * \param j ordinate of the cube 0260 * \param k height of the cube 0261 */ 0262 double get_y_grad( const int i, const int j, const int k ) ; 0263 /** 0264 * interpolates the vertical gradient of the implicit function at the lower vertex of the specified cube 0265 * \param i abscisse of the cube 0266 * \param j ordinate of the cube 0267 * \param k height of the cube 0268 */ 0269 double get_z_grad( const int i, const int j, const int k ) ; 0270 0271 /** 0272 * accesses the pre-computed vertex index on the lower horizontal edge of a specific cube 0273 * \param i abscisse of the cube 0274 * \param j ordinate of the cube 0275 * \param k height of the cube 0276 */ 0277 int get_x_vert( const int i, const int j, const int k ) const { return i_x_verts[ i + j*i_size_x + k*i_size_x*i_size_y] ; } 0278 /** 0279 * accesses the pre-computed vertex index on the lower longitudinal edge of a specific cube 0280 * \param i abscisse of the cube 0281 * \param j ordinate of the cube 0282 * \param k height of the cube 0283 */ 0284 int get_y_vert( const int i, const int j, const int k ) const { return i_y_verts[ i + j*i_size_x + k*i_size_x*i_size_y] ; } 0285 /** 0286 * accesses the pre-computed vertex index on the lower vertical edge of a specific cube 0287 * \param i abscisse of the cube 0288 * \param j ordinate of the cube 0289 * \param k height of the cube 0290 */ 0291 int get_z_vert( const int i, const int j, const int k ) const { return i_z_verts[ i + j*i_size_x + k*i_size_x*i_size_y] ; } 0292 0293 /** 0294 * sets the pre-computed vertex index on the lower horizontal edge of a specific cube 0295 * \param val the index of the new vertex 0296 * \param i abscisse of the cube 0297 * \param j ordinate of the cube 0298 * \param k height of the cube 0299 */ 0300 void set_x_vert( const int val, const int i, const int j, const int k ) { i_x_verts[ i + j*i_size_x + k*i_size_x*i_size_y] = val ; } 0301 /** 0302 * sets the pre-computed vertex index on the lower longitudinal edge of a specific cube 0303 * \param val the index of the new vertex 0304 * \param i abscisse of the cube 0305 * \param j ordinate of the cube 0306 * \param k height of the cube 0307 */ 0308 void set_y_vert( const int val, const int i, const int j, const int k ) { i_y_verts[ i + j*i_size_x + k*i_size_x*i_size_y] = val ; } 0309 /** 0310 * sets the pre-computed vertex index on the lower vertical edge of a specific cube 0311 * \param val the index of the new vertex 0312 * \param i abscisse of the cube 0313 * \param j ordinate of the cube 0314 * \param k height of the cube 0315 */ 0316 void set_z_vert( const int val, const int i, const int j, const int k ) { i_z_verts[ i + j*i_size_x + k*i_size_x*i_size_y] = val ; } 0317 0318 /** prints cube for debug */ 0319 void print_cube() ; 0320 0321 //----------------------------------------------------------------------------- 0322 // Elements 0323 private : 0324 int i_originalMC ; /**< selects whether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes */ 0325 int i_N[15] ; /**< counts the occurrence of each case for debug */ 0326 0327 int i_size_x ; /**< width of the grid */ 0328 int i_size_y ; /**< depth of the grid */ 0329 int i_size_z ; /**< height of the grid */ 0330 double *i_data ; /**< implicit function values sampled on the grid */ 0331 0332 //BEGIN percy addons 0333 double xmin; 0334 double xmax; 0335 double ymin; 0336 double ymax; 0337 double zmin; 0338 double zmax; 0339 double hx; 0340 double hy; 0341 double hz; 0342 //END 0343 0344 int *i_x_verts ; /**< pre-computed vertex indices on the lower horizontal edge of each cube */ 0345 int *i_y_verts ; /**< pre-computed vertex indices on the lower longitudinal edge of each cube */ 0346 int *i_z_verts ; /**< pre-computed vertex indices on the lower vertical edge of each cube */ 0347 0348 int i_nverts ; /**< number of allocated vertices in the vertex buffer */ 0349 int i_ntrigs ; /**< number of allocated triangles in the triangle buffer */ 0350 int i_Nverts ; /**< size of the vertex buffer */ 0351 int i_Ntrigs ; /**< size of the triangle buffer */ 0352 Vertex *i_vertices ; /**< vertex buffer */ 0353 Triangle *i_triangles ; /**< triangle buffer */ 0354 0355 int i_i ; /**< abscisse of the active cube */ 0356 int i_j ; /**< height of the active cube */ 0357 int i_k ; /**< ordinate of the active cube */ 0358 0359 double i_cube[8] ; /**< values of the implicit function on the active cube */ 0360 unsigned char i_lut_entry ; /**< cube sign representation in [0..255] */ 0361 unsigned char i_case ; /**< case of the active cube in [0..15] */ 0362 unsigned char i_config ; /**< configuration of the active cube */ 0363 unsigned char i_subconfig ; /**< subconfiguration of the active cube */ 0364 }; 0365 //_____________________________________________________________________________ 0366 0367 0368 0369 0370 #endif