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