Skip to content

Commit caad1e7

Browse files
committed
fix(Geometry): now unique points from ColocatedInfo have distances wider than given epsilon from each other
1 parent a1ef2cd commit caad1e7

File tree

5 files changed

+151
-6
lines changed

5 files changed

+151
-6
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: 29 additions & 3 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,16 +210,22 @@ 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 ) {
215+
[&epsilon, &mapping, &mutex, this]( index_t p ) {
195216
if( mapping[p] == p )
196217
{
197218
const auto vertices =
198219
radius_neighbors( point( p ), epsilon );
199-
const auto min_index = *absl::c_min_element( vertices );
220+
const auto min_index =
221+
find_min_unmapped_element( vertices, mapping );
222+
std::lock_guard< std::mutex > lock( mutex );
200223
for( const auto id : vertices )
201224
{
202-
mapping[id] = min_index;
225+
if( id == mapping[id] )
226+
{
227+
mapping[id] = min_index;
228+
}
203229
}
204230
}
205231
} );

tests/data/surface_degen.og_tsf3d

4.36 MB
Binary file not shown.

tests/geometry/test-nnsearch.cpp

Lines changed: 55 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,57 @@ 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+
OPENGEODE_EXCEPTION( colocated_info.nb_unique_points() == 2,
90+
"[Test] Should be 2 unique points" );
91+
for( const auto p : geode::Indices{ points } )
92+
{
93+
OPENGEODE_EXCEPTION( colocated_info.colocated_mapping[p]
94+
< colocated_info.unique_points.size(),
95+
"[Test] Wrong value of colocated_mapping (bigger than unique "
96+
"points size)" );
97+
const auto& colocated_point =
98+
colocated_info.unique_points[colocated_info.colocated_mapping[p]];
99+
OPENGEODE_EXCEPTION(
100+
geode::point_point_distance( points[p], colocated_point )
101+
<= DISTANCE,
102+
"[Test] Colocated point is not close enough to original point" );
103+
}
104+
for( const auto up0 : geode::Indices{ colocated_info.unique_points } )
105+
{
106+
for( const auto up1 : geode::Indices{ colocated_info.unique_points } )
107+
{
108+
if( up1 <= up0 )
109+
{
110+
continue;
111+
}
112+
OPENGEODE_EXCEPTION(
113+
geode::point_point_distance( colocated_info.unique_points[up0],
114+
colocated_info.unique_points[up1] )
115+
> DISTANCE,
116+
"[Test] Colocated points are too close" );
117+
}
118+
}
119+
}
120+
121+
void test()
122+
{
123+
first_test();
124+
second_test();
125+
}
126+
73127
OPENGEODE_TEST( "nnsearch" )

tests/mesh/test-merge-surface.cpp

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

0 commit comments

Comments
 (0)