17 : source_mesh(std::make_unique<
GEO::Mesh>()),
18 dimension_voronoi(dim + 1),
19 RVD_mesh(std::make_unique<
GEO::Mesh>())
24 CmdLine::import_arg_group(
"standard");
25 CmdLine::import_arg_group(
"algo");
26 CmdLine::import_arg_group(
"opt");
27 CmdLine::declare_arg(
"nb_iter", 1000,
"number of iterations for OTM");
29 CmdLine::declare_arg_group(
30 "RVD",
"RVD output options", CmdLine::ARG_ADVANCED);
31 CmdLine::declare_arg(
"RVD",
false,
"save restricted Voronoi diagram");
33 "RVD_iter",
false,
"save restricted Voronoi diagram at each iteration");
35 "RVD:borders_only",
false,
"save only border of RVD");
37 "RVD:integration_simplices",
true,
"export RVD as integration simplices");
39 CmdLine::declare_arg(
"multilevel",
true,
"use multilevel algorithm");
40 CmdLine::declare_arg(
"BRIO",
true,
41 "use BRIO reordering to compute the levels");
42 CmdLine::declare_arg(
"ratio", 0.125,
"ratio between levels");
43 CmdLine::declare_arg(
"epsilon", 0.01,
"relative measure error in a cell");
45 "lock",
true,
"Lock lower levels when sampling shape");
47 "fitting_degree", 2,
"degree for interpolating weights");
49 "project",
true,
"project sampling on border");
51 "feature_sensitive",
true,
"attempt to recover hard edges");
53 "singular",
false,
"compute and save singular surface");
54 CmdLine::set_arg(
"algo:delaunay",
"BPOW");
56 "recenter",
true,
"recenter target onto source mesh");
58 "rescale",
true,
"rescale target to match source volume");
61 throw std::runtime_error(
"Failed to load source mesh: " + source_mesh_file);
71 const std::vector<Point<spacedim>> &points,
72 const Vector<double> &potentials)
74 this->generator_points = points;
75 this->generator_potentials.resize(potentials.size());
76 for (
unsigned int i = 0; i < potentials.size(); ++i) {
77 this->generator_potentials[i] = potentials[i];
81 points_mesh_target.clear();
82 points_mesh_target.reserve(points.size() * dim);
83 for (
const auto& point : points) {
84 for (
unsigned int d = 0; d < dim; ++d) {
85 points_mesh_target.push_back(point[d]);
95 const size_t nb_points = this->generator_points.size();
98 points_mesh_target_lifted.resize(nb_points * dimension_voronoi);
101 for (
size_t i = 0; i < nb_points; ++i) {
102 for (
int d = 0; d < dim; ++d) {
103 points_mesh_target_lifted[i * dimension_voronoi + d] =
104 points_mesh_target[i * dim + d];
110 for (
size_t i = 0; i < nb_points; ++i) {
111 W = std::max(W, this->generator_potentials[i]);
114 for (
size_t i = 0; i < nb_points; ++i) {
115 points_mesh_target_lifted[dimension_voronoi * i + dim] =
116 ::sqrt(W - this->generator_potentials[i]);
120 delaunay = GEO::Delaunay::create(GEO::coord_index_t(dimension_voronoi),
"BPOW");
123 RVD = GEO::RestrictedVoronoiDiagram::create(delaunay, source_mesh.get());
125 RVD->set_volumetric(
true);
126 RVD->set_check_SR(
true);
127 RVD->create_threads();
158 throw std::runtime_error(
"Power diagram not computed. Call compute_power_diagram first.");
161 GEO::Attribute<GEO::index_t> tet_region(RVD_mesh->cells.attributes(),
"region");
163 const size_t nb_vertices = RVD->delaunay()->nb_vertices();
164 std::vector<GEO::vec3> centroids(nb_vertices, GEO::vec3(0.0, 0.0, 0.0));
165 std::vector<double> volumes(nb_vertices, 0.0);
168 std::cout <<
"Computing centroids..." << std::endl;
169 for (GEO::index_t t = 0; t < RVD_mesh->cells.nb(); ++t) {
170 const GEO::index_t v = tet_region[t];
171 const GEO::index_t v0 = RVD_mesh->cells.tet_vertex(t, 0);
172 const GEO::index_t v1 = RVD_mesh->cells.tet_vertex(t, 1);
173 const GEO::index_t v2 = RVD_mesh->cells.tet_vertex(t, 2);
174 const GEO::index_t v3 = RVD_mesh->cells.tet_vertex(t, 3);
176 GEO::vec3 p0(RVD_mesh->vertices.point_ptr(v0));
177 GEO::vec3 p1(RVD_mesh->vertices.point_ptr(v1));
178 GEO::vec3 p2(RVD_mesh->vertices.point_ptr(v2));
179 GEO::vec3 p3(RVD_mesh->vertices.point_ptr(v3));
181 const double volume = GEO::Geom::tetra_signed_volume(p0, p1, p2, p3);
182 centroids[v] += (volume / 4.0) * (p0 + p1 + p2 + p3);
183 volumes[v] += volume;
187 this->cell_centroids.clear();
188 for (
size_t v = 0; v < nb_vertices; ++v) {
189 if (volumes[v] != 0.0) {
190 const double s = 1.0 / ::fabs(volumes[v]);
191 const GEO::vec3& c = centroids[v] * s;
192 this->cell_centroids.push_back(Point<spacedim>(c.x, c.y, c.z));
219 GEO::MeshIOFlags flags;
220 flags.set_element(GEO::MESH_CELLS);
221 flags.set_attribute(GEO::MESH_CELL_REGION);
223 if (!GEO::mesh_load(filename, mesh, flags)) {
227 if (!mesh.cells.are_simplices()) {
228 std::cerr <<
"File " << filename
229 <<
" should only have tetrahedra" << std::endl;
233 if (mesh.cells.nb() == 0) {
234 std::cout <<
"File " << filename
235 <<
" does not contain a volume" << std::endl;
236 std::cout <<
"Trying to tetrahedralize..." << std::endl;
237 if (!GEO::mesh_tetrahedralize(mesh,
true,
false)) {
void write_vector(const VectorContainer &points, const std::string &filepath, const std::string &fileMode="txt")
Write a vector container to a file in binary or text format.