Skip to content

Commit 9b92db1

Browse files
authored
Merge pull request #917 from Geode-solutions/fix/build-grid
Fix/build grid
2 parents 36154ab + d02ae60 commit 9b92db1

File tree

10 files changed

+252
-26
lines changed

10 files changed

+252
-26
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2019 - 2024 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.h>
27+
#include <geode/mesh/core/light_regular_grid.h>
28+
29+
namespace geode
30+
{
31+
FORWARD_DECLARATION_DIMENSION_CLASS( BoundingBox );
32+
} // namespace geode
33+
34+
namespace geode
35+
{
36+
template < index_t dimension >
37+
LightRegularGrid< dimension >
38+
build_grid_from_bbox_target_length_and_maximum_cell_number(
39+
const BoundingBox< dimension >& bbox,
40+
double target_cell_length,
41+
index_t max_nb_cells );
42+
} // namespace geode

src/geode/geometry/mensuration.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,33 +81,32 @@ namespace geode
8181
double tetrahedron_signed_volume( const Tetrahedron& tetra )
8282
{
8383
const auto& vertices = tetra.vertices();
84+
for( const auto v0 : LRange{ 3 } )
85+
{
86+
for( const auto v1 : LRange{ v0 + 1, 4 } )
87+
{
88+
const Vector3D edge{ vertices[v0], vertices[v1] };
89+
if( edge.length() == 0 )
90+
{
91+
return 0;
92+
}
93+
}
94+
}
8495
for( const auto v : LRange{ 4 } )
8596
{
8697
const auto v1 = signed_volume_vertices_order[v][0];
8798
const auto v2 = signed_volume_vertices_order[v][1];
8899
const auto v3 = signed_volume_vertices_order[v][2];
89100
const Vector3D edge02{ vertices[v], vertices[v2] };
90101
const auto edge02_length = edge02.length();
91-
if( edge02_length == 0 )
92-
{
93-
return 0;
94-
}
95102
const Vector3D edge03{ vertices[v], vertices[v3] };
96103
const auto edge03_length = edge03.length();
97-
if( edge03_length == 0 )
98-
{
99-
return 0;
100-
}
101104
const auto cross02_03 = edge02.cross( edge03 );
102105
if( cross02_03.length()
103106
> global_angular_epsilon * edge02_length * edge03_length )
104107
{
105108
const Vector3D edge01{ vertices[v], vertices[v1] };
106109
const auto edge01_length = edge01.length();
107-
if( edge01_length == 0 )
108-
{
109-
return 0;
110-
}
111110
return edge01.dot( cross02_03 ) / 6.;
112111
}
113112
}

src/geode/geometry/position.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,15 @@ namespace geode
175175
{
176176
const auto& facet_vertices =
177177
Tetrahedron::tetrahedron_facet_vertex[f];
178-
const auto volume = tetrahedron_signed_volume(
179-
{ vertices[facet_vertices[0]], vertices[facet_vertices[1]],
180-
vertices[facet_vertices[2]], point } );
181-
if( volume < -10 * global_epsilon )
178+
const Triangle3D facet{ vertices[facet_vertices[0]],
179+
vertices[facet_vertices[1]], vertices[facet_vertices[2]] };
180+
const auto signed_distance =
181+
std::get< 0 >( point_triangle_signed_distance( point, facet ) );
182+
if( signed_distance < -global_epsilon )
182183
{
183184
return Position::outside;
184185
}
185-
if( volume < 10 * global_epsilon )
186+
if( signed_distance < global_epsilon )
186187
{
187188
return point_tetrahedron_position_exact( point, tetra );
188189
}

src/geode/mesh/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ add_geode_library(
9797
"helpers/aabb_edged_curve_helpers.cpp"
9898
"helpers/aabb_surface_helpers.cpp"
9999
"helpers/aabb_solid_helpers.cpp"
100+
"helpers/build_grid.cpp"
100101
"helpers/convert_edged_curve.cpp"
101102
"helpers/convert_point_set.cpp"
102103
"helpers/convert_surface_mesh.cpp"
@@ -226,6 +227,7 @@ add_geode_library(
226227
"helpers/aabb_edged_curve_helpers.h"
227228
"helpers/aabb_surface_helpers.h"
228229
"helpers/aabb_solid_helpers.h"
230+
"helpers/build_grid.h"
229231
"helpers/convert_edged_curve.h"
230232
"helpers/convert_point_set.h"
231233
"helpers/convert_surface_mesh.h"
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2019 - 2024 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/build_grid.h>
25+
26+
#include <geode/geometry/bounding_box.h>
27+
28+
namespace geode
29+
{
30+
template < index_t dimension >
31+
LightRegularGrid< dimension >
32+
build_grid_from_bbox_target_length_and_maximum_cell_number(
33+
const BoundingBox< dimension >& bbox,
34+
double target_cell_length,
35+
index_t max_nb_cells )
36+
{
37+
const auto diagonal = bbox.max() - bbox.min();
38+
double numerator{ 1 };
39+
for( const auto d : LRange{ dimension } )
40+
{
41+
numerator *= diagonal.value( d );
42+
}
43+
const auto min_cell_length =
44+
std::pow( numerator / max_nb_cells, 1. / dimension );
45+
const auto target_is_ok = target_cell_length > min_cell_length;
46+
auto cell_length = std::max( min_cell_length, target_cell_length );
47+
std::array< index_t, dimension > cell_numbers;
48+
std::array< double, dimension > cell_lengths;
49+
for( const auto d : LRange{ dimension } )
50+
{
51+
if( target_is_ok )
52+
{
53+
cell_numbers[d] = std::max( static_cast< index_t >( 1 ),
54+
static_cast< index_t >(
55+
std::ceil( diagonal.value( d ) / cell_length ) ) );
56+
}
57+
else
58+
{
59+
cell_numbers[d] = std::max( static_cast< index_t >( 1 ),
60+
static_cast< index_t >(
61+
std::floor( diagonal.value( d ) / cell_length ) ) );
62+
}
63+
cell_lengths[d] = diagonal.value( d ) / cell_numbers[d];
64+
}
65+
return { bbox.min(), std::move( cell_numbers ),
66+
std::move( cell_lengths ) };
67+
}
68+
69+
template LightRegularGrid2D opengeode_mesh_api
70+
build_grid_from_bbox_target_length_and_maximum_cell_number(
71+
const BoundingBox2D&, double, index_t );
72+
template LightRegularGrid3D opengeode_mesh_api
73+
build_grid_from_bbox_target_length_and_maximum_cell_number(
74+
const BoundingBox3D&, double, index_t );
75+
} // namespace geode

src/geode/mesh/helpers/convert_solid_mesh.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ namespace
5858
{
5959
builder.reserve_tetrahedra( 6 * grid.nb_cells() );
6060
geode::GenericMapping< geode::index_t > old2new_mapping;
61-
for( const auto k : geode::LRange{ grid.nb_cells_in_direction( 2 ) } )
61+
for( const auto k : geode::Range{ grid.nb_cells_in_direction( 2 ) } )
6262
{
6363
for( const auto j :
64-
geode::LRange{ grid.nb_cells_in_direction( 1 ) } )
64+
geode::Range{ grid.nb_cells_in_direction( 1 ) } )
6565
{
6666
for( const auto i :
67-
geode::LRange{ grid.nb_cells_in_direction( 0 ) } )
67+
geode::Range{ grid.nb_cells_in_direction( 0 ) } )
6868
{
6969
const auto cell_vertices =
7070
grid.cell_vertices( { i, j, k } );

src/geode/mesh/helpers/convert_surface_mesh.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,10 @@ namespace
131131
{
132132
builder.reserve_triangles( 2 * grid.nb_cells() );
133133
geode::GenericMapping< geode::index_t > old2new_mapping;
134-
for( const auto j : geode::LRange{ grid.nb_cells_in_direction( 1 ) } )
134+
for( const auto j : geode::Range{ grid.nb_cells_in_direction( 1 ) } )
135135
{
136136
for( const auto i :
137-
geode::LRange{ grid.nb_cells_in_direction( 0 ) } )
137+
geode::Range{ grid.nb_cells_in_direction( 0 ) } )
138138
{
139139
const auto cell_vertices = grid.cell_vertices( { i, j } );
140140
const auto cell = grid.cell_index( { i, j } );

tests/geometry/test-mensuration.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ void test_triangle_signed_area()
145145
test_triangle_signed_area_3d();
146146
}
147147

148-
void test_tetrahedron_signed_area()
148+
void test_tetrahedron_signed_volume()
149149
{
150150
const geode::Point3D a{ { 0.0, 0.0, 0.0 } };
151151
const geode::Point3D b{ { 1.0, 0.0, 0.0 } };
@@ -165,11 +165,36 @@ void test_tetrahedron_signed_area()
165165
"with query tetra tetra2" );
166166
}
167167

168+
void test_tetrahedron_signed_volume2()
169+
{
170+
const geode::Point3D a{ { 130295.505221494, 243533.759356966,
171+
-41066.8949388236 } };
172+
const geode::Point3D b{ { 138908.732244318, 234168.317708333,
173+
-45594.02734375 } };
174+
const geode::Point3D c{ { 132108.6875, 242111.890625, -39388.34375 } };
175+
const geode::Point3D b2{ { 138908.732244319, 234168.317708334,
176+
-45594.02734376 } };
177+
178+
const geode::Tetrahedron tetra1{ a, b, c, b };
179+
const auto volume1 = geode::tetrahedron_signed_volume( tetra1 );
180+
OPENGEODE_EXCEPTION( std::fabs( volume1 ) < geode::global_epsilon,
181+
"[Test] Wrong result for tetrahedron_signed_volume2 "
182+
"with query tetra tetra1" );
183+
184+
const geode::Tetrahedron tetra2{ a, b, c, b };
185+
const auto volume2 = geode::tetrahedron_signed_volume( tetra2 );
186+
DEBUG( volume2 );
187+
OPENGEODE_EXCEPTION( std::fabs( volume2 ) < geode::global_epsilon,
188+
"[Test] Wrong result for tetrahedron_signed_volume2 "
189+
"with query tetra tetra2" );
190+
}
191+
168192
void test()
169193
{
170-
test_triangle_area();
171-
test_triangle_signed_area();
172-
test_tetrahedron_signed_area();
194+
// test_triangle_area();
195+
// test_triangle_signed_area();
196+
// test_tetrahedron_signed_volume();
197+
test_tetrahedron_signed_volume2();
173198
}
174199

175200
OPENGEODE_TEST( "signed-mensuration" )

tests/mesh/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,10 @@ add_geode_test(
275275
${PROJECT_NAME}::geometry
276276
${PROJECT_NAME}::mesh
277277
)
278+
add_geode_test(
279+
SOURCE "test-build-grid.cpp"
280+
DEPENDENCIES
281+
${PROJECT_NAME}::basic
282+
${PROJECT_NAME}::geometry
283+
${PROJECT_NAME}::mesh
284+
)

tests/mesh/test-build-grid.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2019 - 2024 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+
#include <geode/basic/logger.h>
24+
25+
#include <geode/geometry/bounding_box.h>
26+
#include <geode/geometry/point.h>
27+
28+
#include <geode/mesh/helpers/build_grid.h>
29+
30+
#include <geode/tests/common.h>
31+
32+
void test()
33+
{
34+
geode::OpenGeodeMeshLibrary::initialize();
35+
const geode::index_t max_nb_cells{ 100 };
36+
geode::BoundingBox2D bbox;
37+
bbox.add_point( { { 0, 0 } } );
38+
bbox.add_point( { { 1, 1 } } );
39+
const auto grid =
40+
geode::build_grid_from_bbox_target_length_and_maximum_cell_number(
41+
bbox, 0.01, max_nb_cells );
42+
DEBUG( grid.nb_cells() );
43+
DEBUG( grid.nb_cells_in_direction( 0 ) );
44+
DEBUG( grid.nb_cells_in_direction( 1 ) );
45+
DEBUG( grid.cell_length_in_direction( 0 ) );
46+
DEBUG( grid.cell_length_in_direction( 1 ) );
47+
OPENGEODE_EXCEPTION( grid.nb_cells() <= max_nb_cells,
48+
"[Test] Too much cells in built grid" );
49+
50+
bbox.add_point( { { 1, 10 } } );
51+
const auto grid2 =
52+
geode::build_grid_from_bbox_target_length_and_maximum_cell_number(
53+
bbox, 0.01, max_nb_cells );
54+
DEBUG( grid2.nb_cells() );
55+
DEBUG( grid2.nb_cells_in_direction( 0 ) );
56+
DEBUG( grid2.nb_cells_in_direction( 1 ) );
57+
DEBUG( grid2.cell_length_in_direction( 0 ) );
58+
DEBUG( grid2.cell_length_in_direction( 1 ) );
59+
OPENGEODE_EXCEPTION( grid.nb_cells() <= max_nb_cells,
60+
"[Test] Too much cells in built grid2" );
61+
62+
bbox.add_point( { { 3, 10 } } );
63+
const auto grid3 =
64+
geode::build_grid_from_bbox_target_length_and_maximum_cell_number(
65+
bbox, 0.01, max_nb_cells );
66+
DEBUG( grid3.nb_cells() );
67+
DEBUG( grid3.nb_cells_in_direction( 0 ) );
68+
DEBUG( grid3.nb_cells_in_direction( 1 ) );
69+
DEBUG( grid3.cell_length_in_direction( 0 ) );
70+
DEBUG( grid3.cell_length_in_direction( 1 ) );
71+
OPENGEODE_EXCEPTION( grid.nb_cells() <= max_nb_cells,
72+
"[Test] Too much cells in built grid3" );
73+
}
74+
75+
OPENGEODE_TEST( "graph" )

0 commit comments

Comments
 (0)