Skip to content

Commit 49f67eb

Browse files
committed
fix(Mesh): add mesh validity fix for non manifold vertices on Surfaces and Solids
1 parent b04c5e6 commit 49f67eb

File tree

12 files changed

+440
-61
lines changed

12 files changed

+440
-61
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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/basic/mapping.hpp>
27+
28+
#include <geode/mesh/common.hpp>
29+
30+
namespace geode
31+
{
32+
FORWARD_DECLARATION_DIMENSION_CLASS( SolidMesh );
33+
FORWARD_DECLARATION_DIMENSION_CLASS( SolidMeshBuilder );
34+
} // namespace geode
35+
36+
namespace geode
37+
{
38+
namespace detail
39+
{
40+
template < index_t dimension >
41+
GenericMapping< index_t > repair_non_manifold_vertices(
42+
const SolidMesh< dimension >& mesh,
43+
SolidMeshBuilder< dimension >& builder );
44+
} // namespace detail
45+
} // namespace geode
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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/basic/mapping.hpp>
27+
28+
#include <geode/mesh/common.hpp>
29+
30+
namespace geode
31+
{
32+
FORWARD_DECLARATION_DIMENSION_CLASS( SurfaceMesh );
33+
FORWARD_DECLARATION_DIMENSION_CLASS( SurfaceMeshBuilder );
34+
} // namespace geode
35+
36+
namespace geode
37+
{
38+
namespace detail
39+
{
40+
template < index_t dimension >
41+
GenericMapping< index_t > repair_non_manifold_vertices(
42+
const SurfaceMesh< dimension >& mesh,
43+
SurfaceMeshBuilder< dimension >& builder );
44+
} // namespace detail
45+
} // namespace geode
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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/basic/mapping.hpp>
27+
28+
#include <geode/model/common.hpp>
29+
30+
namespace geode
31+
{
32+
class BRep;
33+
class BRepBuilder;
34+
FORWARD_DECLARATION_DIMENSION_CLASS( Block );
35+
ALIAS_3D( Block );
36+
} // namespace geode
37+
38+
namespace geode
39+
{
40+
namespace detail
41+
{
42+
GenericMapping< index_t >
43+
opengeode_model_api repair_non_manifold_vertices(
44+
const BRep& model, BRepBuilder& builder, const Block3D& block );
45+
} // namespace detail
46+
} // namespace geode

include/geode/model/helpers/detail/surface_mesh_validity_fix.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
#pragma once
2525

26+
#include <geode/basic/mapping.hpp>
27+
2628
#include <geode/model/common.hpp>
2729

2830
namespace geode
@@ -35,7 +37,9 @@ namespace geode
3537
namespace detail
3638
{
3739
template < typename Model >
38-
void repair_non_manifold_vertices(
39-
Model& model, const Surface< Model::dim >& surface );
40+
GenericMapping< index_t > repair_non_manifold_vertices(
41+
const Model& model,
42+
typename Model::Builder& builder,
43+
const Surface< Model::dim >& surface );
4044
} // namespace detail
4145
} // namespace geode

src/geode/mesh/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,10 @@ add_geode_library(
127127
"helpers/detail/mesh_intersection_detection.cpp"
128128
"helpers/detail/point_set_merger.cpp"
129129
"helpers/detail/solid_merger.cpp"
130+
"helpers/detail/solid_mesh_validity_fix.cpp"
130131
"helpers/detail/split_along_solid_facets.cpp"
131132
"helpers/detail/surface_merger.cpp"
133+
"helpers/detail/surface_mesh_validity_fix.cpp"
132134
"helpers/detail/vertex_merger.cpp"
133135
"helpers/internal/copy.cpp"
134136
"helpers/internal/grid_shape_function.cpp"
@@ -316,8 +318,10 @@ add_geode_library(
316318
"helpers/detail/mesh_intersection_detection.hpp"
317319
"helpers/detail/point_set_merger.hpp"
318320
"helpers/detail/solid_merger.hpp"
321+
"helpers/detail/solid_mesh_validity_fix.hpp"
319322
"helpers/detail/split_along_solid_facets.hpp"
320323
"helpers/detail/surface_merger.hpp"
324+
"helpers/detail/surface_mesh_validity_fix.hpp"
321325
"helpers/detail/vertex_merger.hpp"
322326
INTERNAL_HEADERS
323327
"core/internal/edges_impl.hpp"

src/geode/mesh/builder/solid_mesh_builder.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,11 @@ namespace
204204
vertices_old2new[solid.polyhedron_vertex( { p, v } )];
205205
OPENGEODE_EXCEPTION( new_vertex != geode::NO_ID,
206206
"[SolidMesh::update_polyhedron_vertices] No polyhedron "
207-
"should be removed" );
207+
"should be removed (",
208+
p, ", ", v, " -> ", solid.polyhedron_vertex( { p, v } ),
209+
" located at ",
210+
solid.point( solid.polyhedron_vertex( { p, v } ) ).string(),
211+
")" );
208212
}
209213
}
210214
}
@@ -803,6 +807,11 @@ namespace geode
803807
for( const auto v : Range{ solid_mesh_.nb_vertices() } )
804808
{
805809
to_delete[v] = !solid_mesh_.polyhedron_around_vertex( v );
810+
if( to_delete[v] )
811+
{
812+
DEBUG( v );
813+
SDEBUG( solid_mesh_.point( v ) );
814+
}
806815
}
807816
return delete_vertices( to_delete );
808817
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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+
#include <geode/mesh/helpers/detail/solid_mesh_validity_fix.hpp>
25+
26+
#include <geode/basic/uuid.hpp>
27+
28+
#include <geode/geometry/point.hpp>
29+
30+
#include <geode/mesh/builder/solid_mesh_builder.hpp>
31+
#include <geode/mesh/core/solid_mesh.hpp>
32+
33+
namespace geode
34+
{
35+
namespace detail
36+
{
37+
template < index_t dimension >
38+
GenericMapping< index_t > repair_non_manifold_vertices(
39+
const SolidMesh< dimension >& mesh,
40+
SolidMeshBuilder< dimension >& builder )
41+
{
42+
absl::FixedArray< PolyhedraAroundVertex > polyhedra_around_vertices(
43+
mesh.nb_vertices() );
44+
for( const auto p : Range{ mesh.nb_polyhedra() } )
45+
{
46+
for( const auto v : LRange{ mesh.nb_polyhedron_vertices( p ) } )
47+
{
48+
polyhedra_around_vertices[mesh.polyhedron_vertex(
49+
{ p, v } )]
50+
.emplace_back( p, v );
51+
}
52+
}
53+
GenericMapping< index_t > vertex_mappings;
54+
for( const auto v : Range{ mesh.nb_vertices() } )
55+
{
56+
auto polyhedra_around = mesh.polyhedra_around_vertex( v );
57+
const auto& polyhedron_vertices = polyhedra_around_vertices[v];
58+
auto nb_polyhedra_around = polyhedra_around.size();
59+
if( nb_polyhedra_around == polyhedron_vertices.size() )
60+
{
61+
continue;
62+
}
63+
PolyhedraAroundVertex total_polyhedra;
64+
while( nb_polyhedra_around != polyhedron_vertices.size() )
65+
{
66+
for( auto&& polyhedron : polyhedra_around )
67+
{
68+
total_polyhedra.emplace_back( std::move( polyhedron ) );
69+
}
70+
const auto new_vertex_id =
71+
builder.create_point( mesh.point( v ) );
72+
builder.replace_vertex( v, new_vertex_id );
73+
for( const auto& polyhedron_vertex : polyhedron_vertices )
74+
{
75+
if( absl::c_find( total_polyhedra, polyhedron_vertex )
76+
== total_polyhedra.end() )
77+
{
78+
builder.associate_polyhedron_vertex_to_vertex(
79+
polyhedron_vertex, v );
80+
break;
81+
}
82+
}
83+
vertex_mappings.map( v, new_vertex_id );
84+
polyhedra_around = mesh.polyhedra_around_vertex( v );
85+
nb_polyhedra_around += polyhedra_around.size();
86+
}
87+
}
88+
return vertex_mappings;
89+
}
90+
91+
template GenericMapping< index_t >
92+
opengeode_mesh_api repair_non_manifold_vertices(
93+
const SolidMesh< 3 >&, SolidMeshBuilder< 3 >& );
94+
} // namespace detail
95+
} // namespace geode

0 commit comments

Comments
 (0)