Skip to content

Commit c0317ef

Browse files
committed
feat(Model_: add API helpers to compute unique vertices of models
1 parent fa0628e commit c0317ef

7 files changed

Lines changed: 271 additions & 0 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2019 - 2026 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/model/common.hpp>
27+
28+
namespace geode
29+
{
30+
} // namespace geode
31+
32+
namespace geode
33+
{
34+
template < typename Model >
35+
void compute_model_unique_vertices(
36+
const Model& model, typename Model::Builder& builder );
37+
} // namespace geode

src/geode/model/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ add_geode_library(
2929
"helpers/component_mesh_polyhedra.cpp"
3030
"helpers/component_mesh_vertices.cpp"
3131
"helpers/component_mensurations.cpp"
32+
"helpers/compute_unique_vertices.cpp"
3233
"helpers/convert_brep_section.cpp"
3334
"helpers/convert_model_meshes.cpp"
3435
"helpers/convert_to_mesh.cpp"
@@ -108,6 +109,7 @@ add_geode_library(
108109
"helpers/component_mesh_polyhedra.hpp"
109110
"helpers/component_mesh_vertices.hpp"
110111
"helpers/component_mensurations.hpp"
112+
"helpers/compute_unique_vertices.hpp"
111113
"helpers/convert_brep_section.hpp"
112114
"helpers/convert_model_meshes.hpp"
113115
"helpers/convert_to_mesh.hpp"
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/*
2+
* Copyright (c) 2019 - 2026 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/model/helpers/compute_unique_vertices.hpp>
25+
26+
#include <geode/geometry/nn_search.hpp>
27+
28+
#include <geode/mesh/core/edged_curve.hpp>
29+
#include <geode/mesh/core/point_set.hpp>
30+
#include <geode/mesh/core/solid_mesh.hpp>
31+
#include <geode/mesh/core/surface_mesh.hpp>
32+
33+
#include <geode/model/mixin/core/block.hpp>
34+
#include <geode/model/mixin/core/corner.hpp>
35+
#include <geode/model/mixin/core/line.hpp>
36+
#include <geode/model/mixin/core/surface.hpp>
37+
#include <geode/model/representation/builder/brep_builder.hpp>
38+
#include <geode/model/representation/builder/section_builder.hpp>
39+
#include <geode/model/representation/core/brep.hpp>
40+
#include <geode/model/representation/core/section.hpp>
41+
42+
namespace
43+
{
44+
template < typename Model >
45+
std::vector< geode::Point< Model::dim > > get_all_points_base(
46+
const Model& model )
47+
{
48+
std::vector< geode::Point< Model::dim > > points;
49+
for( const auto& corner : model.corners() )
50+
{
51+
for( const auto v : geode::Range{ corner.mesh().nb_vertices() } )
52+
{
53+
points.emplace_back( corner.mesh().point( v ) );
54+
}
55+
}
56+
for( const auto& line : model.lines() )
57+
{
58+
for( const auto v : geode::Range{ line.mesh().nb_vertices() } )
59+
{
60+
points.emplace_back( line.mesh().point( v ) );
61+
}
62+
}
63+
for( const auto& surface : model.surfaces() )
64+
{
65+
for( const auto v : geode::Range{ surface.mesh().nb_vertices() } )
66+
{
67+
points.emplace_back( surface.mesh().point( v ) );
68+
}
69+
}
70+
return points;
71+
}
72+
73+
std::vector< geode::Point2D > get_all_points( const geode::Section& model )
74+
{
75+
return get_all_points_base< geode::Section >( model );
76+
}
77+
78+
std::vector< geode::Point3D > get_all_points( const geode::BRep& model )
79+
{
80+
auto points = get_all_points_base< geode::BRep >( model );
81+
for( const auto& block : model.blocks() )
82+
{
83+
for( const auto v : geode::Range{ block.mesh().nb_vertices() } )
84+
{
85+
points.emplace_back( block.mesh().point( v ) );
86+
}
87+
}
88+
return points;
89+
}
90+
91+
template < typename Model >
92+
void set_unique_vertices_base( const Model& model,
93+
typename Model::Builder& builder,
94+
const geode::NNSearch< Model::dim >& unique_nns )
95+
{
96+
for( const auto& corner : model.corners() )
97+
{
98+
for( const auto v : geode::Range{ corner.mesh().nb_vertices() } )
99+
{
100+
const auto& point = corner.mesh().point( v );
101+
builder.set_unique_vertex( { corner.component_id(), v },
102+
unique_nns.closest_neighbor( point ) );
103+
}
104+
}
105+
for( const auto& line : model.lines() )
106+
{
107+
for( const auto v : geode::Range{ line.mesh().nb_vertices() } )
108+
{
109+
const auto& point = line.mesh().point( v );
110+
builder.set_unique_vertex( { line.component_id(), v },
111+
unique_nns.closest_neighbor( point ) );
112+
}
113+
}
114+
for( const auto& surface : model.surfaces() )
115+
{
116+
for( const auto v : geode::Range{ surface.mesh().nb_vertices() } )
117+
{
118+
const auto& point = surface.mesh().point( v );
119+
builder.set_unique_vertex( { surface.component_id(), v },
120+
unique_nns.closest_neighbor( point ) );
121+
}
122+
}
123+
}
124+
125+
void set_unique_vertices( const geode::Section& model,
126+
geode::SectionBuilder& builder,
127+
const geode::NNSearch2D& unique_nns )
128+
{
129+
set_unique_vertices_base( model, builder, unique_nns );
130+
}
131+
132+
void set_unique_vertices( const geode::BRep& model,
133+
geode::BRepBuilder& builder,
134+
const geode::NNSearch3D& unique_nns )
135+
{
136+
set_unique_vertices_base( model, builder, unique_nns );
137+
for( const auto& block : model.blocks() )
138+
{
139+
for( const auto v : geode::Range{ block.mesh().nb_vertices() } )
140+
{
141+
const auto& point = block.mesh().point( v );
142+
builder.set_unique_vertex( { block.component_id(), v },
143+
unique_nns.closest_neighbor( point ) );
144+
}
145+
}
146+
}
147+
148+
} // namespace
149+
150+
namespace geode
151+
{
152+
template < typename Model >
153+
void compute_model_unique_vertices(
154+
const Model& model, typename Model::Builder& builder )
155+
{
156+
if( model.nb_unique_vertices() > 0 )
157+
{
158+
return;
159+
}
160+
auto all_vertices = get_all_points( model );
161+
NNSearch< Model::dim > nns{ all_vertices };
162+
const auto colocated_info =
163+
nns.colocated_index_mapping( GLOBAL_EPSILON );
164+
builder.create_unique_vertices( colocated_info.nb_unique_points() );
165+
NNSearch< Model::dim > unique_nns{ colocated_info.unique_points };
166+
set_unique_vertices( model, builder, unique_nns );
167+
}
168+
169+
template void opengeode_model_api compute_model_unique_vertices(
170+
const BRep&, BRepBuilder& );
171+
template void opengeode_model_api compute_model_unique_vertices(
172+
const Section&, SectionBuilder& );
173+
} // namespace geode

src/geode/model/helpers/detail/surface_mesh_validity_fix.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
#include <geode/geometry/point.hpp>
3131

32+
#include <geode/mesh/builder/surface_mesh_builder.hpp>
33+
#include <geode/mesh/core/surface_mesh.hpp>
3234
#include <geode/mesh/helpers/detail/surface_mesh_validity_fix.hpp>
3335

3436
#include <geode/model/mixin/core/surface.hpp>
12 KB
Binary file not shown.

tests/model/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ add_geode_test(
4444
${PROJECT_NAME}::basic
4545
${PROJECT_NAME}::model
4646
)
47+
add_geode_test(
48+
SOURCE "test-compute-unique-vertices.cpp"
49+
DEPENDENCIES
50+
${PROJECT_NAME}::basic
51+
${PROJECT_NAME}::geometry
52+
${PROJECT_NAME}::model
53+
)
4754
add_geode_test(
4855
SOURCE "test-convert-brep.cpp"
4956
DEPENDENCIES
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2019 - 2026 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/tests/common.hpp>
25+
26+
#include <geode/basic/assert.hpp>
27+
#include <geode/basic/logger.hpp>
28+
29+
#include <geode/model/helpers/compute_unique_vertices.hpp>
30+
#include <geode/model/representation/builder/brep_builder.hpp>
31+
#include <geode/model/representation/core/brep.hpp>
32+
#include <geode/model/representation/io/brep_input.hpp>
33+
34+
void test_brep()
35+
{
36+
auto brep = geode::load_brep( absl::StrCat(
37+
geode::DATA_PATH, "rectangular_cuboid_without_uv.og_brep" ) );
38+
geode::BRepBuilder brep_builder{ brep };
39+
geode::compute_model_unique_vertices( brep, brep_builder );
40+
OPENGEODE_EXCEPTION( brep.nb_unique_vertices() == 8,
41+
"[Test] Wrong number of unique vertices" );
42+
}
43+
44+
void test()
45+
{
46+
geode::OpenGeodeModelLibrary::initialize();
47+
test_brep();
48+
}
49+
50+
OPENGEODE_TEST( "convert-brep" )

0 commit comments

Comments
 (0)