GCC Code Coverage Report


Directory: ./
File: lib/exploragram/hexdom/hexdom_pipeline.cpp
Date: 2026-09-07 02:28:19
Exec Total Coverage
Lines: 0 67 0.0%
Functions: 0 8 0.0%
Branches: 0 162 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2022 Inria
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 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40 #include <exploragram/hexdom/hexdom_pipeline.h>
41
42 #include <exploragram/hexdom/preprocessing.h>
43 #include <exploragram/hexdom/FF.h>
44 #include <exploragram/hexdom/PGP.h>
45 #include <exploragram/hexdom/hex_candidates.h>
46 #include <exploragram/hexdom/meshcomesh.h>
47 #include <exploragram/hexdom/quad_dominant.h>
48 #include <exploragram/hexdom/hex.h>
49 #include <exploragram/hexdom/cavity.h>
50 #include <exploragram/hexdom/hex_dominant.h>
51
52 #include <exploragram/hexdom/time_log.h>
53
54
55 #include <geogram/mesh/mesh_geometry.h>
56 #include <geogram/mesh/mesh_tetrahedralize.h>
57
58 #include <geogram/points/colocate.h>
59
60
61 namespace GEO {
62
63 namespace HexdomPipeline {
64
65 #define STEP(funcname,args) { \
66 logt.add_step(#funcname); \
67 funcname args; \
68 }
69
70 bool SetConstraints(Mesh*m, std::string& msg,bool hilbert_sort,
71 bool relaxed) {
72 try {
73 STEP(produce_hexdom_input,(m, msg, hilbert_sort, relaxed));
74 }
75 catch (const char* s) {
76 plop(s);
77 msg = std::string(s);
78 logt.add_string("fail", msg);
79 return false;
80 }
81 return true;
82 }
83
84 void FrameField(Mesh*m, bool smooth) {
85 GEO::FFopt ffopt(m);
86 STEP(ffopt.FF_init,(true));
87 if (smooth)
88 STEP(ffopt.FF_smooth,());
89 STEP(ffopt.compute_Bid_norm,());
90 //uncomment may ease debugging... STEP(ffopt.brush_frame,());
91 }
92
93 //{algo} = {0: CubeCover, 1 : PGP with correction, 2 PGP}
94 void Parameterization(Mesh*m, int algo, double PGP_max_scale_corr) {
95 {// scope to allows destruction of attributes that are members of pgp
96 PGPopt pgp(m);
97 #ifdef WITH_CUBECOVER
98 if (algo > 0) {
99 STEP(pgp.optimize_corr,(PGP_max_scale_corr));
100 STEP(pgp.optimize_PGP,());
101 }
102 else if (algo == 0) {
103 STEP(pgp.cubcover,());
104 }
105 else geo_assert_not_reached;
106 #else
107 geo_argused(PGP_max_scale_corr);
108 if(algo != 2) {
109 Logger::warn("PGP")
110 << "cubecover/scale correction not available in the public version"
111 << std::endl;
112 Logger::warn("PGP")
113 << "falling back with PGP without scale correction"
114 << std::endl;
115 }
116 algo = 2;
117 STEP(pgp.optimize_corr,(0.0));
118 STEP(pgp.optimize_PGP,());
119 #endif
120 }
121
122 m->edges.attributes().delete_attribute_store("corr"); // ? can we really do that ?
123 //m->vertices.attributes().delete_attribute_store("U");
124 //m->edges.clear();
125 }
126
127 void HexCandidates(Mesh*m, Mesh* result) {
128 STEP(export_hexes, (m, result));
129 }
130
131 bool QuadDominant(Mesh*m, Mesh* chartmesh) {
132
133 STEP(export_boundary_with_uv,(m, chartmesh, "uv", "singular"));
134 //get_facet_stats(chartmesh, "export with uv");
135
136
137 STEP(imprint, (chartmesh, "uv", "singular"));
138
139 // STEP(split_edges_by_iso_uvs, (chartmesh, "uv", "singular"));
140 // STEP(facets_split,(chartmesh, "uv", "singular"));
141
142 STEP(mark_charts,(chartmesh, "uv", "chart", "singular"));
143
144 STEP(simplify_quad_charts,(chartmesh));
145
146 // bool res = true;
147 // STEP(res = export_quadtri_from_charts,(chartmesh));
148 // if (res) {
149 // plop("self-intersections!");
150 // return true;
151 // } else return false;
152
153 /// vector<index_t> fails;
154 /// find_degenerate_facets(chartmesh, fails);
155 /// plop(fails.size());
156
157 /*
158 vector<index_t> intersections;
159 chartmesh->facets.triangulate();
160 find_self_intersections(chartmesh, intersections);
161 plop(intersections.size());
162 std::string msg;
163 plop (surface_is_manifold(chartmesh, msg));
164 plop(msg);
165 FOR(f, chartmesh->facets.nb()) {
166 double area = Geom::mesh_facet_area(*chartmesh, f, 3);
167 GEO::Logger::out("HexDom") << area << std::endl;
168 }
169
170 */
171
172
173
174 if (!surface_is_tetgenifiable(chartmesh)) {
175 logt.add_string("fail", " tetgen is not able to remesh the quadtri");
176 return false;
177 }
178
179 chartmesh->facet_corners.attributes().delete_attribute_store("uv");
180 // chartmesh->facets.attributes().delete_attribute_store("chart");
181 chartmesh->facets.attributes().delete_attribute_store("quadelement");
182 chartmesh->facets.attributes().delete_attribute_store("singular");
183 chartmesh->vertices.attributes().delete_attribute_store("quadcorners");
184 chartmesh->facets.attributes().delete_attribute_store("orig_tri_fid");
185 chartmesh->facet_corners.attributes().delete_attribute_store("isovalue");
186 return true;
187 }
188
189 void Hexahedrons(Mesh* quaddominant, Mesh* hexcandidates, Mesh* result) {
190 result->copy(*hexcandidates);
191 STEP(hex_set_2_hex_mesh,(result, quaddominant));
192 }
193
194 bool Cavity(Mesh* quaddominant, Mesh* hexahedrons, Mesh* result) {
195 result->copy(*quaddominant);
196 STEP(merge_hex_boundary_and_quadtri,(hexahedrons, result));
197
198 if (result->facets.nb() > 0 && !surface_is_tetgenifiable(result)) {
199 logt.add_string("fail", "empty cavity, is it normal?");
200 return false;
201 }
202
203 return true;
204 }
205
206 void HexDominant(Mesh* cavity, Mesh* hexahedrons, Mesh* result, bool with_pyramid,bool baudoin_carrier, bool vertex_puncher) {
207 geo_argused(vertex_puncher);
208
209 {
210 #ifndef HAS_TET2HEX
211 if(baudoin_carrier) {
212 Logger::warn("hexdom") << "This version does not have Vorpaline" << std::endl;
213 Logger::warn("hexdom") << "Ignored flag: Carrier-Baudouin algo." << std::endl;
214 Logger::warn("hexdom") << "(filling cavity with tets, no recombination)" << std::endl;
215 }
216 #endif
217 Mesh tets;
218 tets.copy(*cavity);
219 STEP(fill_cavity_with_tetgen,(cavity, &tets, with_pyramid));
220 result->copy(tets);
221 result->facets.clear();
222 STEP(add_hexes_to_tetmesh,(hexahedrons, result));
223 result->cells.connect();
224 result->cells.compute_borders();
225 }
226 }
227 }
228
229 }
230