Skip to content

Commit 2f511f0

Browse files
authored
fix issue #8773 "c3t3 -> binary -> c3t3 -> vtu writes invalid vtu files" (#8778)
## Summary of Changes fix issue #8773: c3t3 -> binary -> c3t3 -> vtu writes invalid vtu files When a c3t3 is loaded, its far vertices were not loaded correctly. ## Release Management * Affected package(s): Mesh_3/SMDS_3 * Issue(s) solved (if any): fix #0000, fix #8773 * License and copyright ownership: maintenance by GF
2 parents 82bd9a0 + 4f4f789 commit 2f511f0

File tree

4 files changed

+146
-6
lines changed

4 files changed

+146
-6
lines changed

Mesh_3/include/CGAL/Mesh_3/Mesher_3.h

+9-6
Original file line numberDiff line numberDiff line change
@@ -687,14 +687,16 @@ initialize()
687687
bbox.xmin() + 0.5*xdelta,
688688
bbox.ymin() + 0.5*ydelta,
689689
bbox.zmin() + 0.5*zdelta);
690-
# ifdef CGAL_CONCURRENT_MESH_3_VERBOSE
691-
std::cerr << "Adding points on a far sphere (radius = " << radius <<")...";
692-
# endif
693690
CGAL::Random rnd(0);
694691
Random_points_on_sphere_3<Bare_point> random_point(radius, rnd);
695692
const int NUM_PSEUDO_INFINITE_VERTICES = static_cast<int>(
696693
float(std::thread::hardware_concurrency())
697694
* Concurrent_mesher_config::get().num_pseudo_infinite_vertices_per_core);
695+
#ifdef CGAL_MESH_3_VERBOSE
696+
std::cerr << "Adding " << NUM_PSEUDO_INFINITE_VERTICES
697+
<< " points on a far sphere (radius = " << radius << ")...";
698+
#endif
699+
698700
for (int i = 0 ; i < NUM_PSEUDO_INFINITE_VERTICES ; ++i, ++random_point)
699701
r_c3t3_.add_far_point(r_c3t3_.triangulation().geom_traits().construct_weighted_point_3_object()
700702
(r_c3t3_.triangulation().geom_traits().construct_translated_point_3_object()(*random_point, center)));
@@ -745,11 +747,12 @@ initialize()
745747
bbox.xmin() + 0.5*xdelta,
746748
bbox.ymin() + 0.5*ydelta,
747749
bbox.zmin() + 0.5*zdelta);
748-
# ifdef CGAL_MESH_3_VERBOSE
749-
std::cerr << "Adding points on a far sphere (radius = " << radius << ")...";
750-
# endif
751750
Random_points_on_sphere_3<Bare_point> random_point(radius);
752751
const int NUM_PSEUDO_INFINITE_VERTICES = 12*2;
752+
# ifdef CGAL_MESH_3_VERBOSE
753+
std::cerr << "Adding " << NUM_PSEUDO_INFINITE_VERTICES
754+
<< " points on a far sphere (radius = " << radius << ")...";
755+
#endif
753756
for (int i = 0 ; i < NUM_PSEUDO_INFINITE_VERTICES ; ++i, ++random_point)
754757
r_c3t3_.add_far_point(r_c3t3_.triangulation().geom_traits().construct_weighted_point_3_object()
755758
(r_c3t3_.triangulation().geom_traits().construct_translated_point_3_object()(*random_point, center)));

Mesh_3/test/Mesh_3/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ create_single_source_cgal_program( "test_meshing_with_default_edge_size.cpp" )
4949
create_single_source_cgal_program( "test_meshing_determinism.cpp" )
5050
create_single_source_cgal_program( "test_meshing_without_features_determinism.cpp" )
5151
create_single_source_cgal_program( "test_mesh_3_issue_1554.cpp" )
52+
create_single_source_cgal_program( "test_mesh_3_issue_8773.cpp" )
5253
create_single_source_cgal_program( "test_mesh_polyhedral_domain_with_features_deprecated.cpp" )
5354
create_single_source_cgal_program( "test_meshing_with_one_step.cpp" )
5455
create_single_source_cgal_program( "test_meshing_with_one_step_with_features.cpp" )
@@ -79,6 +80,7 @@ foreach(target
7980
test_meshing_determinism
8081
test_meshing_without_features_determinism
8182
test_mesh_3_issue_1554
83+
test_mesh_3_issue_8773
8284
test_mesh_polyhedral_domain_with_features_deprecated
8385
test_mesh_cell_base_3
8486
test_meshing_with_one_step
@@ -108,6 +110,7 @@ if(TARGET CGAL::TBB_support)
108110
test_meshing_determinism
109111
test_meshing_without_features_determinism
110112
test_mesh_3_issue_1554
113+
test_mesh_3_issue_8773
111114
test_mesh_polyhedral_domain_with_features_deprecated
112115
test_mesh_cell_base_3
113116
test_min_edge_length
@@ -129,6 +132,7 @@ if(TARGET CGAL::TBB_support)
129132
"execution of test_meshing_polyhedral_complex"
130133
"execution of test_mesh_capsule_var_distance_bound"
131134
"execution of test_mesh_3_issue_1554"
135+
"execution of test_mesh_3_issue_8773"
132136
"execution of test_mesh_polyhedral_domain_with_features_deprecated"
133137
"execution of test_mesh_cell_base_3"
134138
PROPERTY RUN_SERIAL 1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
2+
#include <CGAL/IO/File_binary_mesh_3.h>
3+
#include <CGAL/IO/output_to_vtu.h>
4+
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
5+
#include <CGAL/Mesh_criteria_3.h>
6+
#include <CGAL/Mesh_triangulation_3.h>
7+
#include <CGAL/Polyhedral_mesh_domain_with_features_3.h>
8+
#include <CGAL/Surface_mesh.h>
9+
#include <CGAL/boost/graph/helpers.h>
10+
#include <CGAL/make_mesh_3.h>
11+
#include <fstream>
12+
#include <iostream>
13+
14+
// Domain
15+
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
16+
using Polyhedron = CGAL::Surface_mesh<K::Point_3>;
17+
using Mesh_domain = CGAL::Polyhedral_mesh_domain_with_features_3<K, Polyhedron>;
18+
19+
// Triangulation
20+
using Tr = CGAL::Mesh_triangulation_3<Mesh_domain, CGAL::Default,
21+
CGAL::Parallel_if_available_tag>::type;
22+
using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3<Tr>;
23+
24+
// Criteria
25+
using Mesh_criteria = CGAL::Mesh_criteria_3<Tr>;
26+
27+
namespace params = CGAL::parameters;
28+
29+
void check_stream(const std::ios& stream,
30+
const std::string& filename,
31+
const std::string& operation,
32+
bool ok = true) {
33+
if(!stream || !ok) {
34+
std::cerr << "Stream error after " << operation << " file: " << filename << std::endl;
35+
std::cerr << "Stream state: ";
36+
if(stream.rdstate() == std::ios::goodbit) {
37+
std::cerr << "no error";
38+
} else {
39+
if(stream.rdstate() & std::ios::eofbit) {
40+
std::cerr << "eofbit ";
41+
}
42+
if(stream.rdstate() & std::ios::failbit) {
43+
std::cerr << "failbit ";
44+
}
45+
if(stream.rdstate() & std::ios::badbit) {
46+
std::cerr << "badbit ";
47+
}
48+
}
49+
std::cerr << std::endl;
50+
std::exit(EXIT_FAILURE);
51+
}
52+
}
53+
54+
int main(int argc, char* argv[]) {
55+
const std::string fname = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/cube.off");
56+
57+
// Create input polyhedron
58+
Polyhedron polyhedron;
59+
std::ifstream input(fname);
60+
check_stream(input, fname, "opening");
61+
input >> polyhedron;
62+
check_stream(input, fname, "reading polyhedron from");
63+
64+
// Create domain
65+
Mesh_domain domain(polyhedron);
66+
domain.detect_features();
67+
68+
// Mesh criteria (no cell_size set)
69+
Mesh_criteria criteria(params::facet_angle(25).facet_size(0.15).facet_distance(0.05).cell_radius_edge_ratio(3));
70+
71+
// Mesh generation
72+
const C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria, params::no_perturb().no_exude());
73+
74+
const auto nb_vertices = c3t3.triangulation().number_of_vertices();
75+
const auto nb_far_vertices = c3t3.number_of_far_points();
76+
const auto nb_cells = c3t3.number_of_cells();
77+
78+
std::cout << "Created a c3t3 with " << c3t3.triangulation().number_of_vertices() << " vertices, and "
79+
<< c3t3.number_of_cells() << " cells" << std::endl;
80+
81+
// Output
82+
{
83+
const std::string filename = "ascii.vtu";
84+
std::ofstream out(filename);
85+
check_stream(out, filename, "opening");
86+
CGAL::IO::output_to_vtu(out, c3t3, CGAL::IO::ASCII);
87+
check_stream(out, filename, "writing (ASCII)");
88+
}
89+
90+
{
91+
const std::string filename = "binary.vtu";
92+
std::ofstream out(filename, std::ios::binary);
93+
check_stream(out, filename, "opening");
94+
CGAL::IO::output_to_vtu(out, c3t3, CGAL::IO::BINARY);
95+
check_stream(out, filename, "writing (BINARY)");
96+
}
97+
98+
const std::string filename = "mesh.binary.cgal";
99+
{
100+
std::ofstream out(filename, std::ios::binary);
101+
check_stream(out, filename, "opening");
102+
bool ok = CGAL::IO::save_binary_file(out, c3t3);
103+
check_stream(out, filename, "writing (binary)", ok);
104+
}
105+
106+
// Input
107+
C3t3 bis;
108+
{
109+
std::ifstream in(filename, std::ios::binary);
110+
check_stream(in, filename, "opening (binary)");
111+
bool ok = CGAL::IO::load_binary_file(in, bis);
112+
check_stream(in, filename, "reading binary file", ok);
113+
}
114+
115+
{
116+
const std::string bis_filename = "bis.vtu";
117+
std::ofstream bis_os(bis_filename);
118+
check_stream(bis_os, bis_filename, "opening (bis.vtu)");
119+
CGAL::IO::output_to_vtu(bis_os, bis, CGAL::IO::ASCII);
120+
check_stream(bis_os, bis_filename, "writing (ASCII)");
121+
}
122+
123+
assert(bis.number_of_cells() == nb_cells);
124+
assert(bis.triangulation().number_of_vertices() == nb_vertices);
125+
assert(bis.number_of_far_points() == nb_far_vertices);
126+
127+
std::cout << "Mesh generation and output completed successfully." << std::endl;
128+
129+
return EXIT_SUCCESS;
130+
}

SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h

+3
Original file line numberDiff line numberDiff line change
@@ -2034,13 +2034,16 @@ Mesh_complex_3_in_triangulation_3<Tr,CI_,CSI_>::
20342034
rescan_after_load_of_triangulation()
20352035
{
20362036
corners_.clear();
2037+
far_vertices_.clear();
20372038
for(typename Tr::Finite_vertices_iterator
20382039
vit = this->triangulation().finite_vertices_begin(),
20392040
end = this->triangulation().finite_vertices_end();
20402041
vit != end; ++vit)
20412042
{
20422043
if ( vit->in_dimension() == 0 ) {
20432044
add_to_complex(vit, Corner_index(1));
2045+
} else if(vit->in_dimension() == -1) {
2046+
far_vertices_.push_back(vit);
20442047
}
20452048
}
20462049

0 commit comments

Comments
 (0)