1 /* 2 * Copyright (c) 2012-2016, Bruno Levy 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * * Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * * Neither the name of the ALICE Project-Team nor the names of its 14 * contributors may be used to endorse or promote products derived from this 15 * software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * If you modify this software, you should include a notice giving the 30 * name of the person performing the modification, the date of modification, 31 * and the reason for such modification. 32 * 33 * Contact: Bruno Levy 34 * 35 * Bruno.Levy@inria.fr 36 * http://www.loria.fr/~levy 37 * 38 * ALICE Project 39 * LORIA, INRIA Lorraine, 40 * Campus Scientifique, BP 239 41 * 54506 VANDOEUVRE LES NANCY CEDEX 42 * FRANCE 43 * 44 */ 45 46 #ifndef GEOGRAM_GFX_GLUP_GLUP_MARCHING_CELLS 47 #define GEOGRAM_GFX_GLUP_GLUP_MARCHING_CELLS 48 49 #include <geogram_gfx/GLUP/GLUP.h> 50 #include <geogram_gfx/basic/common.h> 51 #include <geogram/basic/logger.h> 52 #include <geogram/mesh/mesh.h> // For cell descriptors / marching cells. 53 54 /** 55 * \file geogram_gfx/GLUP/GLUP_marching_cells.h 56 * \brief Implementation of the marching cells algorithms. 57 * \details Used to implement GLUP_CLIP_SLICE_CELLS clipping mode. 58 */ 59 60 namespace GLUP { 61 using namespace GEO; 62 63 /**********************************************************************/ 64 65 /** 66 * \brief Implements the MarchingCells algorithm. 67 * \details MarchingCell compute the intersection between 68 * a cell and a plane, using only combinatorial information. 69 * It uses the static tables from the Mesh class, so that cell 70 * numberings are coherent between storage and graphics. 71 */ 72 class MarchingCell { 73 public: 74 75 /** 76 * \brief MarchingCell constructor 77 * \param[in] prim the GLUP volumetric primitive, should be one 78 * of GLUP_TETRAHEDRA, GLUP_HEXAHEDRA, GLUP_PRISMS, GLUP_PYRAMIDS. 79 */ 80 MarchingCell(GLUPprimitive prim); 81 82 /** 83 * \brief MarchingCell destructor. 84 */ 85 ~MarchingCell(); 86 87 /** 88 * \brief Gets the number of vertices. 89 * \return the number of vertices in a cell 90 */ nb_vertices()91 index_t nb_vertices() const { 92 return nb_vertices_; 93 } 94 95 /** 96 * \brief Gets the number of edges. 97 * \return the number of edges in a cell 98 */ nb_edges()99 index_t nb_edges() const { 100 return nb_edges_; 101 } 102 103 104 /** 105 * \brief Gets the number of configurations. 106 * \return the number of configurations 107 */ nb_configs()108 index_t nb_configs() const { 109 return nb_configs_; 110 } 111 112 /** 113 * \brief Gets a vertex by edge index and local vertex index. 114 * \param[in] e the index of the edge 115 * \param[in] lv the local vertex index in the edge, one of 0,1 116 * \return the vertex index 117 */ edge_vertex(index_t e,index_t lv)118 index_t edge_vertex(index_t e, index_t lv) const { 119 geo_debug_assert(e < nb_edges()); 120 geo_debug_assert(lv < 2); 121 return edge_[e*2+lv]; 122 } 123 124 /** 125 * \brief Gets the number of intersected edges in a configuration. 126 * \param[in] config the vertex configuration bitcode. The 127 * bit corresponding to vertex v is set if v is on the positive 128 * side of the intersection plane. 129 * \return the number of intersected edges in configuration \p config 130 */ config_size(index_t config)131 index_t config_size(index_t config) const { 132 geo_debug_assert(config < nb_configs()); 133 return config_size_[config]; 134 } 135 136 /** 137 * \brief Gets the maximum configuration size. 138 * \return the largest number of vertices in an intersection polygon 139 */ max_config_size()140 index_t max_config_size() const { 141 return max_config_size_; 142 } 143 144 /** 145 * \brief Gets the list of intersected edges in a configuration. 146 * \param[in] config the vertex configuration bitcode. The 147 * bit corresponding to vertex v is set if v is on the positive 148 * side of the intersection plane. 149 * \return a pointer to the array of edge indices that correspond to 150 * this configuration, of size config_size() 151 */ config_edges(index_t config)152 const index_t* config_edges(index_t config) const { 153 geo_debug_assert(config < nb_configs()); 154 return config_ + config * nb_edges_; 155 } 156 157 /** 158 * \brief Gets the GLSL declaration of marching cell uniform state. 159 * \return a pointer to GLSL source code that declares this 160 * marching cell's uniform state. 161 */ GLSL_uniform_state_declaration()162 const char* GLSL_uniform_state_declaration() const { 163 return GLSL_uniform_state_declaration_.c_str(); 164 } 165 166 /** 167 * \brief Gets the GLSL declaration of the function that 168 * computes the intersections. 169 * \return a pointer to GLSL source code. 170 */ GLSL_compute_intersections()171 const char* GLSL_compute_intersections() const { 172 return GLSL_compute_intersections_.c_str(); 173 } 174 175 176 /** 177 * \brief Gets the binding point of the uniform buffer that 178 * contains the tables for the marching cell. 179 * \return the uniform binding point 180 */ uniform_binding_point()181 GLuint uniform_binding_point() const { 182 return uniform_binding_point_; 183 } 184 185 /** 186 * \brief Creates a Uniform Buffer Object that contains 187 * the tables for the marching cell. 188 * \details Used by GLUP150 and GLUP440 profiles that support 189 * UBOs. This MarchingCells keeps ownership of the created 190 * UBO (it is destroyed by the destructor of this MarchingCells). 191 */ 192 GLuint create_UBO(); 193 194 /** 195 * \brief Creates a Vertex Buffer Object with the indices 196 * for all configurations. 197 * \details Used by GLUPES2 that does not support UBOs. 198 * This MarchingCells keeps ownership of the created 199 * VBO (it is destroyed by the destructor of this MarchingCells). 200 * \note NOT USED YET. 201 */ 202 GLuint create_elements_VBO(); 203 204 /** 205 * \brief Binds the uniform state marching cell variables 206 * to a given program. 207 */ 208 void bind_uniform_state(GLuint program); 209 210 protected: 211 212 /** 213 * \brief Computes the intersection polygon for a configuration. 214 * \param[in] config the vertex configuration bitcode. The 215 * bit corresponding to vertex v is set if v is on the positive 216 * side of the intersection plane. 217 */ 218 void compute_config(index_t config); 219 220 /** 221 * \brief Moves from a given halfedge to the next halfege. 222 * \details The halfedge is refered to as a facet index and a 223 * local vertex index within the facet. 224 * \param[in,out] f the index of the facet 225 * \param[in,out] lv the local index of the vertex in the facet. 226 */ move_to_next(index_t & f,index_t & lv)227 void move_to_next(index_t& f, index_t& lv) { 228 lv = (lv+1) % desc_->nb_vertices_in_facet[f]; 229 } 230 231 /** 232 * \brief Gets the origin vertex of a halfedge. 233 * \details The halfedge is refered to as a facet index and a 234 * local vertex index within the facet. 235 * \param[in] f the index of the facet 236 * \param[in] lv the local index of the vertex in the facet. 237 * \return the index of the origin vertex of the halfedge 238 */ origin_vertex(index_t f,index_t lv)239 index_t origin_vertex(index_t f, index_t lv) { 240 return desc_->facet_vertex[f][lv]; 241 } 242 243 /** 244 * \brief Gets the destination vertex of a halfedge. 245 * \details The halfedge is refered to as a facet index and a 246 * local vertex index within the facet. 247 * \param[in] f the index of the facet 248 * \param[in] lv the local index of the vertex in the facet. 249 * \return the index of the destination vertex of the halfedge 250 */ destination_vertex(index_t f,index_t lv)251 index_t destination_vertex(index_t f, index_t lv) { 252 move_to_next(f, lv); 253 return origin_vertex(f, lv); 254 } 255 256 /** 257 * \brief Gets the edge index that corresponds to a given halfedge. 258 * \details The halfedge is refered to as a facet index and a 259 * local vertex index within the facet. 260 * \param[in] f the index of the facet 261 * \param[in] lv the local index of the vertex in the facet. 262 * \return the index of the edge. 263 */ edge(index_t f,index_t lv)264 index_t edge(index_t f, index_t lv) { 265 index_t v1 = origin_vertex(f, lv); 266 index_t v2 = destination_vertex(f, lv); 267 index_t result = vv_to_e_[v1*desc_->nb_vertices+v2]; 268 geo_debug_assert(result != index_t(-1)); 269 return result; 270 } 271 272 /** 273 * \brief Moves from a given halfedge to the opposite halfege. 274 * \details The halfedge is refered to as a facet index and a 275 * local vertex index within the facet. 276 * \param[in,out] f the index of the facet 277 * \param[in,out] lv the local index of the vertex in the facet. 278 */ 279 void move_to_opposite(index_t& f, index_t& lv); 280 281 /** 282 * \brief Tests whether a given edge is intersected. 283 * \details The halfedge is refered to as a facet index and a 284 * local vertex index within the facet. 285 * \param[in] f the index of the facet 286 * \param[in] lv the local index of the vertex in the facet. 287 * \param[in] config the vertex configuration bitcode. The 288 * bit corresponding to vertex v is set if v is on the positive 289 * side of the intersection plane. 290 * \retval true if the edge is intersected 291 * \retval false otherwise 292 */ edge_is_intersected(index_t f,index_t lv,index_t config)293 bool edge_is_intersected(index_t f, index_t lv, index_t config) { 294 index_t v1 = origin_vertex(f, lv); 295 index_t v2 = destination_vertex(f, lv); 296 bool v1_in = ((config & 1u<<v1) != 0); 297 bool v2_in = ((config & 1u<<v2) != 0); 298 return (v1_in != v2_in); 299 } 300 301 /** 302 * \brief Tests whether a vertex configuration bitcode is 303 * ambiguous. 304 * \details A configuration is ambiguous if it results in several 305 * intersection polygons. 306 * \param[in] config the vertex configuration bitcode. The 307 * bit corresponding to vertex v is set if v is on the positive 308 * side of the intersection plane. 309 * \retval true if the configuration is ambiguous 310 * \retval false otherwise 311 */ 312 bool config_is_ambiguous(index_t config); 313 314 /** 315 * \brief Gets the first intersected halfedge given a 316 * vertex configuration. 317 * \param[out] f the facet of the first intersected halfedge 318 * \param[out] lv the local vertex index of the first intersected 319 * halfedge 320 * \param[in] config the vertex configuration bitcode. The 321 * bit corresponding to vertex v is set if v is on the positive 322 * side of the intersection plane. 323 * \retval true if there was an intersection 324 * \retval false otherwise 325 */ 326 bool get_first_edge(index_t& f, index_t& lv, index_t config); 327 328 private: 329 /** 330 * \brief Forbids copy. 331 */ 332 MarchingCell(const MarchingCell& rhs); 333 334 /** 335 * \brief Forbids copy. 336 */ 337 MarchingCell& operator=(const MarchingCell& rhs); 338 339 private: 340 const CellDescriptor* desc_; 341 index_t vv_to_e_[64]; 342 index_t nb_vertices_; 343 index_t nb_configs_; 344 index_t* config_size_; 345 index_t max_config_size_; 346 index_t* config_; 347 index_t nb_edges_; 348 index_t* edge_; 349 std::string GLSL_uniform_state_declaration_; 350 std::string GLSL_compute_intersections_; 351 GLuint uniform_binding_point_; 352 GLuint UBO_; 353 GLuint elements_VBO_; 354 }; 355 356 /**********************************************************************/ 357 358 } 359 360 #endif 361