Skip to content

Commit 1d46405

Browse files
Merge pull request #1083 from Geode-solutions/fix/nnsearch
fix(Geometry): now unique points from ColocatedInfo have distances wi…
2 parents ac869c5 + e748be3 commit 1d46405

File tree

5 files changed

+160
-9
lines changed

5 files changed

+160
-9
lines changed

include/geode/geometry/distance.hpp

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

2424
#pragma once
2525

26+
#include <optional>
27+
2628
#include <geode/geometry/common.hpp>
2729

2830
namespace geode

src/geode/geometry/nn_search.cpp

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

2424
#include <geode/geometry/nn_search.hpp>
2525

26+
#include <mutex>
2627
#include <numeric>
2728

2829
#include <absl/algorithm/container.h>
@@ -34,6 +35,25 @@
3435
#include <geode/basic/logger.hpp>
3536
#include <geode/basic/pimpl_impl.hpp>
3637

38+
namespace
39+
{
40+
geode::index_t find_min_unmapped_element(
41+
absl::Span< const geode::index_t > elements,
42+
absl::Span< const geode::index_t > mapping )
43+
{
44+
geode::index_t min_index{ geode::NO_ID };
45+
for( const auto e : elements )
46+
{
47+
if( mapping[e] != e )
48+
{
49+
continue;
50+
}
51+
min_index = std::min( min_index, e );
52+
}
53+
return min_index;
54+
}
55+
} // namespace
56+
3757
namespace geode
3858
{
3959
template < index_t dimension >
@@ -190,14 +210,27 @@ namespace geode
190210
typename NNSearch< dimension >::ColocatedInfo result;
191211
std::vector< index_t > mapping( nb_points() );
192212
absl::c_iota( mapping, 0 );
213+
std::mutex mutex;
193214
async::parallel_for( async::irange( index_t{ 0 }, nb_points() ),
194-
[&epsilon, &mapping, this]( index_t p ) {
195-
if( mapping[p] == p )
215+
[&epsilon, &mapping, &mutex, this]( index_t p ) {
216+
if( mapping[p] != p )
217+
{
218+
return;
219+
}
220+
const auto vertices = radius_neighbors( point( p ), epsilon );
221+
auto min_index = find_min_unmapped_element( vertices, mapping );
222+
std::lock_guard< std::mutex > lock( mutex );
223+
if( mapping[p] != p )
224+
{
225+
return;
226+
}
227+
if( min_index != mapping[min_index] )
228+
{
229+
min_index = find_min_unmapped_element( vertices, mapping );
230+
}
231+
for( const auto id : vertices )
196232
{
197-
const auto vertices =
198-
radius_neighbors( point( p ), epsilon );
199-
const auto min_index = *absl::c_min_element( vertices );
200-
for( const auto id : vertices )
233+
if( id == mapping[id] )
201234
{
202235
mapping[id] = min_index;
203236
}

tests/data/surface_degen.og_tsf3d

4.36 MB
Binary file not shown.

tests/geometry/test-nnsearch.cpp

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@
2323

2424
#include <geode/basic/logger.hpp>
2525

26+
#include <geode/geometry/distance.hpp>
2627
#include <geode/geometry/nn_search.hpp>
2728
#include <geode/geometry/point.hpp>
2829

2930
#include <geode/tests/common.hpp>
3031

31-
void test()
32+
void first_test()
3233
{
3334
const geode::NNSearch2D search{ { geode::Point2D{ { 0.1, 4.2 } },
3435
geode::Point2D{ { 5.9, 7.3 } }, geode::Point2D{ { 1.8, -5 } },
@@ -70,4 +71,58 @@ void test()
7071
"[Test] Error in unique points" );
7172
}
7273

74+
void second_test()
75+
{
76+
geode::Logger::set_level( geode::Logger::LEVEL::debug );
77+
std::vector< geode::Point2D > points{
78+
geode::Point2D{ { 0, 0.2 } },
79+
geode::Point2D{ { 0.25, 0 } },
80+
geode::Point2D{ { -0.25, 0 } },
81+
geode::Point2D{ { 0, 0.8 } },
82+
geode::Point2D{ { 0.25, 1 } },
83+
geode::Point2D{ { -0.25, 1 } },
84+
};
85+
const geode::NNSearch2D colocator{ points };
86+
const double DISTANCE{ 0.8 };
87+
88+
const auto colocated_info = colocator.colocated_index_mapping( DISTANCE );
89+
DEBUG( colocated_info.nb_unique_points() );
90+
for( const auto p : geode::Indices{ points } )
91+
{
92+
OPENGEODE_EXCEPTION( colocated_info.colocated_mapping[p]
93+
< colocated_info.unique_points.size(),
94+
"[Test] Wrong value of colocated_mapping (bigger than unique "
95+
"points size)" );
96+
const auto& colocated_point =
97+
colocated_info.unique_points[colocated_info.colocated_mapping[p]];
98+
OPENGEODE_EXCEPTION(
99+
geode::point_point_distance( points[p], colocated_point )
100+
<= DISTANCE,
101+
"[Test] Colocated point is not close enough to original point" );
102+
}
103+
for( const auto up0 : geode::Indices{ colocated_info.unique_points } )
104+
{
105+
for( const auto up1 : geode::Indices{ colocated_info.unique_points } )
106+
{
107+
if( up1 <= up0 )
108+
{
109+
continue;
110+
}
111+
OPENGEODE_EXCEPTION(
112+
geode::point_point_distance( colocated_info.unique_points[up0],
113+
colocated_info.unique_points[up1] )
114+
> DISTANCE,
115+
"[Test] Colocated points are too close" );
116+
}
117+
}
118+
OPENGEODE_EXCEPTION( colocated_info.nb_unique_points() == 2,
119+
"[Test] Should be 2 unique points" );
120+
}
121+
122+
void test()
123+
{
124+
first_test();
125+
second_test();
126+
}
127+
73128
OPENGEODE_TEST( "nnsearch" )

tests/mesh/test-merge-surface.cpp

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

2424
#include <geode/tests/common.hpp>
2525

26+
#include <async++.h>
27+
2628
#include <geode/basic/assert.hpp>
2729
#include <geode/basic/logger.hpp>
2830

31+
#include <geode/geometry/nn_search.hpp>
2932
#include <geode/geometry/point.hpp>
3033

3134
#include <geode/mesh/builder/surface_mesh_builder.hpp>
3235
#include <geode/mesh/core/surface_mesh.hpp>
36+
#include <geode/mesh/core/triangulated_surface.hpp>
3337
#include <geode/mesh/helpers/convert_surface_mesh.hpp>
38+
#include <geode/mesh/io/triangulated_surface_input.hpp>
39+
#include <geode/mesh/io/triangulated_surface_output.hpp>
3440

35-
void test()
41+
void test_create()
3642
{
37-
geode::OpenGeodeMeshLibrary::initialize();
3843
std::vector< geode::Point2D > points{ geode::Point2D{ { 0, 0 } },
3944
geode::Point2D{ { 0, 1 } }, geode::Point2D{ { 0, 2 } },
4045
geode::Point2D{ { 1, 0 } }, geode::Point2D{ { 1, 1 } },
@@ -112,4 +117,60 @@ void test()
112117
"[Test] Wrong adjacency for { 3, 2 }" );
113118
}
114119

120+
void test_import()
121+
{
122+
auto surface = geode::load_triangulated_surface< 3 >(
123+
absl::StrCat( geode::DATA_PATH, "surface_degen.og_tsf3d" ) );
124+
std::vector< std::reference_wrapper< const geode::SurfaceMesh3D > > meshes{
125+
*surface
126+
};
127+
const auto merged = geode::merge_surface_meshes< 3 >( meshes );
128+
geode::save_triangulated_surface(
129+
*dynamic_cast< geode::TriangulatedSurface3D* >( merged.get() ),
130+
"output.og_tsf3d" );
131+
132+
std::vector< geode::Point3D > points( merged->nb_vertices() );
133+
for( const auto v : geode::Range{ merged->nb_vertices() } )
134+
{
135+
points[v] = merged->point( v );
136+
}
137+
geode::NNSearch3D nns( points );
138+
const auto mappings = nns.colocated_index_mapping( geode::GLOBAL_EPSILON );
139+
OPENGEODE_EXCEPTION( mappings.nb_colocated_points() == 0,
140+
"[Test] Should be nomore colocated points" );
141+
for( const auto p : geode::Indices{ points } )
142+
{
143+
OPENGEODE_EXCEPTION(
144+
mappings.colocated_mapping[p] < mappings.unique_points.size(),
145+
"[Test] Wrong value of colocated_mapping (bigger than unique "
146+
"points size)" );
147+
const auto& colocated_point =
148+
mappings.unique_points[mappings.colocated_mapping[p]];
149+
OPENGEODE_EXCEPTION( points[p].inexact_equal( colocated_point ),
150+
"[Test] Colocated point is not close enough to original point" );
151+
}
152+
async::parallel_for(
153+
async::irange( geode::index_t{ 0 }, mappings.unique_points.size() ),
154+
[&mappings]( geode::index_t up0 ) {
155+
for( const auto up1 : geode::Indices{ mappings.unique_points } )
156+
{
157+
if( up1 <= up0 )
158+
{
159+
continue;
160+
}
161+
OPENGEODE_EXCEPTION( !mappings.unique_points[up0].inexact_equal(
162+
mappings.unique_points[up1] ),
163+
"[Test] Colocated points are too close" );
164+
}
165+
} );
166+
}
167+
168+
void test()
169+
{
170+
geode::OpenGeodeMeshLibrary::initialize();
171+
geode::Logger::set_level( geode::Logger::LEVEL::debug );
172+
test_create();
173+
test_import();
174+
}
175+
115176
OPENGEODE_TEST( "merge-surface" )

0 commit comments

Comments
 (0)