Skip to content

Commit 784077a

Browse files
Merge pull request #1144 from Geode-solutions/fix/modeler-clean
fix(Mesh): add helper functions to correct vertex duplications in meshes
2 parents 01d9632 + 6d3cfcc commit 784077a

File tree

11 files changed

+537
-5
lines changed

11 files changed

+537
-5
lines changed

include/geode/geometry/nn_search.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ namespace geode
6868
return mapping;
6969
}
7070

71+
[[nodiscard]] geode::GenericMapping< geode::index_t >
72+
vertices_mapping() const
73+
{
74+
geode::GenericMapping< geode::index_t > mapping;
75+
for( const auto& p : geode::Indices{ colocated_input_points } )
76+
{
77+
mapping.map( p, colocated_input_points[p] );
78+
}
79+
return mapping;
80+
}
81+
7182
std::vector< Point< dimension > > unique_points;
7283
/*!
7384
* This list has the size of the number of points in the tree.

include/geode/mesh/builder/solid_mesh_builder.hpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
#include <absl/container/inlined_vector.h>
2929

30+
#include <geode/basic/mapping.hpp>
31+
3032
#include <geode/mesh/builder/coordinate_reference_system_managers_builder.hpp>
3133
#include <geode/mesh/builder/vertex_set_builder.hpp>
3234
#include <geode/mesh/common.hpp>
@@ -93,16 +95,26 @@ namespace geode
9395
const PolyhedronVertex& polyhedron_vertex, index_t vertex_id );
9496

9597
/*!
96-
* Replace old polygon vertices from a given vertex to another.
98+
* Replace old polyhedron vertices from a given vertex to another.
9799
* @param[in] old_vertex_id Index of the initial mesh vertex to modify
98100
* @param[in] new_vertex_id Index of the target mesh vertex to set as
99101
* polyhedron vertex
102+
* @warning This function supposes that the mesh is manifold
103+
* around old vertex
100104
*/
101105
void replace_vertex( index_t old_vertex_id, index_t new_vertex_id );
102106

107+
/*!
108+
* Replace old polyhedron vertices from given vertices to another ones.
109+
* @warning This function does not suppose that the mesh is manifold
110+
* around old vertices
111+
*/
112+
void replace_vertices(
113+
const GenericMapping< index_t >& vertices_mapping );
114+
103115
/*!
104116
* Set a polyhedron adgjacent through a facet.
105-
* @param[in] polygon_facet The index of the polygon facet
117+
* @param[in] polyhedron_facet The index of the polyhedron facet
106118
* @param[in] adjacent_id Index of the adjacent polyhedron
107119
*/
108120
void set_polyhedron_adjacent(
@@ -111,7 +123,7 @@ namespace geode
111123
/*!
112124
* Unset a polyhedron adjacency through a facet.
113125
114-
* @param[in] polygon_facet The index of the polygon facet
126+
* @param[in] polyhedron_facet The index of the polyhedron facet
115127
*/
116128
void unset_polyhedron_adjacent(
117129
const PolyhedronFacet& polyhedron_facet );

include/geode/mesh/builder/surface_mesh_builder.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
#include <absl/types/span.h>
2929

30+
#include <geode/basic/mapping.hpp>
31+
3032
#include <geode/mesh/builder/coordinate_reference_system_managers_builder.hpp>
3133
#include <geode/mesh/builder/vertex_set_builder.hpp>
3234
#include <geode/mesh/common.hpp>
@@ -96,9 +98,19 @@ namespace geode
9698
* @param[in] old_vertex_id Index of the initial mesh vertex to modify
9799
* @param[in] new_vertex_id Index of the target mesh vertex to set as
98100
* polygon vertex
101+
* @warning This function supposes that the mesh is manifold around old
102+
* vertex
99103
*/
100104
void replace_vertex( index_t old_vertex_id, index_t new_vertex_id );
101105

106+
/*!
107+
* Replace old polygon vertices from given vertices to another ones.
108+
* @warning This function does not suppose that the mesh is manifold
109+
* around old vertices
110+
*/
111+
void replace_vertices(
112+
const GenericMapping< index_t >& vertices_mapping );
113+
102114
/*!
103115
* Set a polygon adjacent through an edge.
104116
* @param[in] polygon_edge The index of the polygon edge

include/geode/mesh/helpers/detail/split_along_solid_facets.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,11 @@
2929

3030
#include <geode/mesh/common.hpp>
3131
#include <geode/mesh/core/meshes_mapping.hpp>
32+
#include <geode/mesh/core/solid_mesh.hpp>
3233

3334
namespace geode
3435
{
35-
FORWARD_DECLARATION_DIMENSION_CLASS( SolidMesh );
3636
FORWARD_DECLARATION_DIMENSION_CLASS( SolidMeshBuilder );
37-
ALIAS_3D( SolidMesh );
3837
ALIAS_3D( SolidMeshBuilder );
3938
} // namespace geode
4039

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (c) 2019 - 2025 Geode-solutions
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*
22+
*/
23+
24+
#pragma once
25+
26+
#include <geode/mesh/common.hpp>
27+
28+
namespace geode
29+
{
30+
FORWARD_DECLARATION_DIMENSION_CLASS( PointSet );
31+
FORWARD_DECLARATION_DIMENSION_CLASS( EdgedCurve );
32+
FORWARD_DECLARATION_DIMENSION_CLASS( SurfaceMesh );
33+
FORWARD_DECLARATION_DIMENSION_CLASS( SolidMesh );
34+
FORWARD_DECLARATION_DIMENSION_CLASS( PointSetBuilder );
35+
FORWARD_DECLARATION_DIMENSION_CLASS( EdgedCurveBuilder );
36+
FORWARD_DECLARATION_DIMENSION_CLASS( SurfaceMeshBuilder );
37+
FORWARD_DECLARATION_DIMENSION_CLASS( SolidMeshBuilder );
38+
ALIAS_3D( SolidMesh );
39+
ALIAS_3D( SolidMeshBuilder );
40+
} // namespace geode
41+
42+
namespace geode
43+
{
44+
template < index_t dimension >
45+
void remove_vertex_duplication( const PointSet< dimension >& mesh,
46+
PointSetBuilder< dimension >& builder );
47+
48+
template < index_t dimension >
49+
void remove_vertex_duplication( const EdgedCurve< dimension >& mesh,
50+
EdgedCurveBuilder< dimension >& builder );
51+
52+
template < index_t dimension >
53+
void remove_vertex_duplication( const SurfaceMesh< dimension >& mesh,
54+
SurfaceMeshBuilder< dimension >& builder );
55+
56+
void opengeode_mesh_api remove_vertex_duplication(
57+
const SolidMesh3D& mesh, SolidMeshBuilder3D& builder );
58+
} // namespace geode

src/geode/mesh/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ add_geode_library(
114114
"helpers/grid_point_function.cpp"
115115
"helpers/grid_scalar_function.cpp"
116116
"helpers/repair_polygon_orientations.cpp"
117+
"helpers/remove_vertex_duplication.cpp"
117118
"helpers/tetrahedral_solid_point_function.cpp"
118119
"helpers/tetrahedral_solid_scalar_function.cpp"
119120
"helpers/triangulated_surface_point_function.cpp"
@@ -253,6 +254,7 @@ add_geode_library(
253254
"helpers/grid_point_function.hpp"
254255
"helpers/grid_scalar_function.hpp"
255256
"helpers/repair_polygon_orientations.hpp"
257+
"helpers/remove_vertex_duplication.hpp"
256258
"helpers/tetrahedral_solid_point_function.hpp"
257259
"helpers/tetrahedral_solid_scalar_function.hpp"
258260
"helpers/triangulated_surface_point_function.hpp"

src/geode/mesh/builder/solid_mesh_builder.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,44 @@ namespace geode
405405
reset_polyhedra_around_vertex( old_vertex_id );
406406
}
407407

408+
template < index_t dimension >
409+
void SolidMeshBuilder< dimension >::replace_vertices(
410+
const GenericMapping< index_t >& vertices_mapping )
411+
{
412+
for( const auto p : Range{ solid_mesh_.nb_polyhedra() } )
413+
{
414+
for( const auto v :
415+
LRange{ solid_mesh_.nb_polyhedron_vertices( p ) } )
416+
{
417+
const PolyhedronVertex polyhedron_vertex{ p, v };
418+
const auto old_vertex_id =
419+
solid_mesh_.polyhedron_vertex( polyhedron_vertex );
420+
if( !vertices_mapping.has_mapping_input( old_vertex_id ) )
421+
{
422+
continue;
423+
}
424+
const auto old2news = vertices_mapping.in2out( old_vertex_id );
425+
OPENGEODE_ASSERT( old2news.size() == 1,
426+
"[SolidMeshBuilder::replace_vertices] "
427+
"Invalid mapping" );
428+
const auto new_vertex_id = old2news[0];
429+
if( old_vertex_id == new_vertex_id )
430+
{
431+
continue;
432+
}
433+
disassociate_polyhedron_vertex_to_vertex( old_vertex_id );
434+
reset_polyhedra_around_vertex( old_vertex_id );
435+
if( solid_mesh_.are_edges_enabled()
436+
|| solid_mesh_.are_facets_enabled() )
437+
{
438+
update_edge_and_facet(
439+
solid_mesh_, *this, polyhedron_vertex, new_vertex_id );
440+
}
441+
update_polyhedron_vertex( polyhedron_vertex, new_vertex_id );
442+
}
443+
}
444+
}
445+
408446
template < index_t dimension >
409447
void SolidMeshBuilder< dimension >::set_polyhedron_vertex(
410448
const PolyhedronVertex& polyhedron_vertex, index_t new_vertex_id )

src/geode/mesh/builder/surface_mesh_builder.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,43 @@ namespace geode
417417
reset_polygons_around_vertex( old_vertex_id );
418418
}
419419

420+
template < index_t dimension >
421+
void SurfaceMeshBuilder< dimension >::replace_vertices(
422+
const GenericMapping< index_t >& vertices_mapping )
423+
{
424+
for( const auto p : Range{ surface_mesh_.nb_polygons() } )
425+
{
426+
for( const auto v :
427+
LRange{ surface_mesh_.nb_polygon_vertices( p ) } )
428+
{
429+
const PolygonVertex polygon_vertex{ p, v };
430+
const auto old_vertex_id =
431+
surface_mesh_.polygon_vertex( polygon_vertex );
432+
if( !vertices_mapping.has_mapping_input( old_vertex_id ) )
433+
{
434+
continue;
435+
}
436+
const auto old2news = vertices_mapping.in2out( old_vertex_id );
437+
OPENGEODE_ASSERT( old2news.size() == 1,
438+
"[SurfaceMeshBuilder::replace_vertices] "
439+
"Invalid mapping" );
440+
const auto new_vertex_id = old2news[0];
441+
if( old_vertex_id == new_vertex_id )
442+
{
443+
continue;
444+
}
445+
disassociate_polygon_vertex_to_vertex( old_vertex_id );
446+
reset_polygons_around_vertex( old_vertex_id );
447+
if( surface_mesh_.are_edges_enabled() )
448+
{
449+
update_edge( surface_mesh_, *this, polygon_vertex,
450+
old_vertex_id, new_vertex_id );
451+
}
452+
update_polygon_vertex( polygon_vertex, new_vertex_id );
453+
}
454+
}
455+
}
456+
420457
template < index_t dimension >
421458
void SurfaceMeshBuilder< dimension >::set_polygon_vertex(
422459
const PolygonVertex& polygon_vertex, index_t new_vertex_id )

0 commit comments

Comments
 (0)