Skip to content

Commit 6c25beb

Browse files
committed
Merge branch 'next' into fix/serialize-attribute
2 parents 409fa9c + 53cdf19 commit 6c25beb

File tree

8 files changed

+255
-15
lines changed

8 files changed

+255
-15
lines changed

include/geode/basic/detail/geode_input_impl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ namespace geode
6868
absl::AsciiStrToLower( extension_from_filename( filename ) );
6969
OPENGEODE_EXCEPTION( Factory::has_creator( extension ),
7070
"Unknown extension: ", extension );
71-
return Factory::create( extension, filename );
71+
return Factory::create(
72+
extension, expand_predefined_folders( filename ) );
7273
}
7374

7475
template < typename Factory, typename... Args >

include/geode/basic/detail/geode_output_impl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ namespace geode
4949
absl::AsciiStrToLower( extension_from_filename( filename ) );
5050
OPENGEODE_EXCEPTION( Factory::has_creator( extension ),
5151
"Unknown extension: ", extension );
52-
return Factory::create( extension, filename );
52+
return Factory::create(
53+
extension, expand_predefined_folders( filename ) );
5354
}
5455

5556
template < typename Factory, typename Object >

include/geode/basic/filename.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,7 @@ namespace geode
4141

4242
absl::string_view opengeode_basic_api extension_from_filename(
4343
absl::string_view filename );
44+
45+
std::string opengeode_basic_api expand_predefined_folders(
46+
absl::string_view path );
4447
} // namespace geode

include/geode/basic/io.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <absl/strings/string_view.h>
2828

2929
#include <geode/basic/common.h>
30+
#include <geode/basic/filename.h>
3031
#include <geode/basic/logger.h>
3132

3233
namespace geode
@@ -42,10 +43,13 @@ namespace geode
4243
}
4344

4445
protected:
45-
IOFile( absl::string_view filename ) : filename_( filename ) {}
46+
IOFile( absl::string_view filename )
47+
: filename_( expand_predefined_folders( filename ) )
48+
{
49+
}
4650

4751
private:
48-
absl::string_view filename_;
52+
std::string filename_;
4953
};
5054

5155
template < typename Factory >

src/geode/basic/filename.cpp

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

2424
#include <geode/basic/filename.h>
2525

26+
#include <absl/strings/string_view.h>
27+
2628
#include <ghc/filesystem.hpp>
2729

2830
namespace geode
@@ -55,4 +57,17 @@ namespace geode
5557
{
5658
return filename.substr( filename.find_last_of( '.' ) + 1 );
5759
}
60+
61+
std::string expand_predefined_folders( absl::string_view path )
62+
{
63+
if( path.empty() )
64+
{
65+
return to_string( path );
66+
}
67+
if( path[0] == '~' )
68+
{
69+
return absl::StrCat( std::getenv( "HOME" ), path.substr( 1 ) );
70+
}
71+
return to_string( path );
72+
}
5873
} // namespace geode

src/geode/mesh/helpers/convert_solid_mesh.cpp

Lines changed: 148 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,148 @@ namespace
161161
}
162162
return true;
163163
}
164+
165+
std::array< geode::index_t, 8 > order_hexahedron_vertices(
166+
const geode::index_t hexahedron_id, const geode::SolidMesh3D& solid )
167+
{
168+
std::array< geode::index_t, 8 > ordered_vertices;
169+
const auto first_polyhedron_facet_vertices =
170+
solid.polyhedron_facet_vertices( { hexahedron_id, 0 } );
171+
ordered_vertices[0] = first_polyhedron_facet_vertices[0];
172+
ordered_vertices[1] = first_polyhedron_facet_vertices[3];
173+
ordered_vertices[2] = first_polyhedron_facet_vertices[2];
174+
ordered_vertices[3] = first_polyhedron_facet_vertices[1];
175+
for( const auto f : geode::LRange( 1, 6 ) )
176+
{
177+
const auto polyhedron_facet_vertices =
178+
solid.polyhedron_facet_vertices( { hexahedron_id, f } );
179+
const auto v_id_0 =
180+
absl::c_find( polyhedron_facet_vertices, ordered_vertices[0] );
181+
if( v_id_0 != polyhedron_facet_vertices.end()
182+
&& absl::c_find(
183+
polyhedron_facet_vertices, ordered_vertices[1] )
184+
!= polyhedron_facet_vertices.end() )
185+
{
186+
const auto index_v_id_0 =
187+
std::distance( polyhedron_facet_vertices.begin(), v_id_0 );
188+
ordered_vertices[4] =
189+
polyhedron_facet_vertices[( index_v_id_0 + 1 ) % 4];
190+
ordered_vertices[5] =
191+
polyhedron_facet_vertices[( index_v_id_0 + 2 ) % 4];
192+
continue;
193+
}
194+
const auto v_id_2 =
195+
absl::c_find( polyhedron_facet_vertices, ordered_vertices[2] );
196+
if( v_id_2 != polyhedron_facet_vertices.end()
197+
&& absl::c_find(
198+
polyhedron_facet_vertices, ordered_vertices[3] )
199+
!= polyhedron_facet_vertices.end() )
200+
{
201+
const auto index_v_id_2 =
202+
std::distance( polyhedron_facet_vertices.begin(), v_id_2 );
203+
ordered_vertices[6] =
204+
polyhedron_facet_vertices[( index_v_id_2 + 1 ) % 4];
205+
ordered_vertices[7] =
206+
polyhedron_facet_vertices[( index_v_id_2 + 2 ) % 4];
207+
continue;
208+
}
209+
}
210+
return ordered_vertices;
211+
}
212+
213+
std::array< geode::index_t, 6 > order_prism_vertices(
214+
const geode::index_t prism_id, const geode::SolidMesh3D& solid )
215+
{
216+
std::array< geode::index_t, 6 > ordered_vertices;
217+
geode::index_t already_used_facet{ 0 };
218+
for( const auto f : geode::LRange{ 5 } )
219+
{
220+
if( solid.nb_polyhedron_facet_vertices( { prism_id, f } ) == 3 )
221+
{
222+
const auto vertices =
223+
solid.polyhedron_facet_vertices( { prism_id, f } );
224+
ordered_vertices[0] = vertices[0];
225+
ordered_vertices[1] = vertices[2];
226+
ordered_vertices[2] = vertices[1];
227+
already_used_facet = f;
228+
break;
229+
}
230+
}
231+
for( const auto f : geode::LRange{ 5 } )
232+
{
233+
if( f == already_used_facet )
234+
{
235+
continue;
236+
}
237+
const auto facet_vertices =
238+
solid.polyhedron_facet_vertices( { prism_id, f } );
239+
const auto v_id =
240+
absl::c_find( facet_vertices, ordered_vertices[0] );
241+
if( v_id == facet_vertices.end()
242+
|| absl::c_find( facet_vertices, ordered_vertices[2] )
243+
== facet_vertices.end() )
244+
{
245+
continue;
246+
}
247+
const auto index_v_id =
248+
std::distance( facet_vertices.begin(), v_id );
249+
ordered_vertices[3] = facet_vertices[( index_v_id + 1 ) % 4];
250+
ordered_vertices[5] = facet_vertices[( index_v_id + 2 ) % 4];
251+
break;
252+
}
253+
for( const auto v : geode::LRange{ 6 } )
254+
{
255+
const auto solid_vertex =
256+
solid.polyhedron_vertex( { prism_id, v } );
257+
if( ordered_vertices[1] == solid_vertex
258+
|| ordered_vertices[2] == solid_vertex
259+
|| ordered_vertices[3] == solid_vertex
260+
|| ordered_vertices[5] == solid_vertex
261+
|| ordered_vertices[0] == solid_vertex )
262+
{
263+
continue;
264+
}
265+
ordered_vertices[4] = solid_vertex;
266+
break;
267+
}
268+
return ordered_vertices;
269+
}
164270
} // namespace
165271

272+
std::array< geode::index_t, 5 > order_pyramid_vertices(
273+
const geode::index_t pyramid_id, const geode::SolidMesh3D& solid )
274+
{
275+
std::array< geode::index_t, 5 > ordered_vertices;
276+
277+
for( const auto f : geode::LRange{ 5 } )
278+
{
279+
if( solid.nb_polyhedron_facet_vertices( { pyramid_id, f } ) == 4 )
280+
{
281+
const auto vertices =
282+
solid.polyhedron_facet_vertices( { pyramid_id, f } );
283+
ordered_vertices[0] = vertices[0];
284+
ordered_vertices[1] = vertices[3];
285+
ordered_vertices[2] = vertices[2];
286+
ordered_vertices[3] = vertices[1];
287+
break;
288+
}
289+
}
290+
for( const auto v : geode::LRange{ 5 } )
291+
{
292+
const auto solid_vertex = solid.polyhedron_vertex( { pyramid_id, v } );
293+
if( ordered_vertices[1] == solid_vertex
294+
|| ordered_vertices[2] == solid_vertex
295+
|| ordered_vertices[3] == solid_vertex
296+
|| ordered_vertices[0] == solid_vertex )
297+
{
298+
continue;
299+
}
300+
ordered_vertices[4] = solid_vertex;
301+
break;
302+
}
303+
return ordered_vertices;
304+
}
305+
166306
namespace geode
167307
{
168308
absl::optional< std::unique_ptr< TetrahedralSolid3D > >
@@ -253,19 +393,20 @@ namespace geode
253393
}
254394
else if( vertices.size() == 8 )
255395
{
256-
builder->create_hexahedron(
257-
{ vertices[0], vertices[1], vertices[2], vertices[3],
258-
vertices[4], vertices[5], vertices[6], vertices[7] } );
396+
const auto ordered_vertices =
397+
order_hexahedron_vertices( p, solid );
398+
builder->create_hexahedron( { ordered_vertices } );
259399
}
260400
else if( vertices.size() == 5 )
261401
{
262-
builder->create_pyramid( { vertices[0], vertices[1],
263-
vertices[2], vertices[3], vertices[4] } );
402+
const auto ordered_vertices =
403+
order_pyramid_vertices( p, solid );
404+
builder->create_pyramid( ordered_vertices );
264405
}
265406
else if( vertices.size() == 6 )
266407
{
267-
builder->create_prism( { vertices[0], vertices[1], vertices[2],
268-
vertices[3], vertices[4], vertices[5] } );
408+
const auto ordered_vertices = order_prism_vertices( p, solid );
409+
builder->create_prism( { ordered_vertices } );
269410
}
270411
}
271412
for( const auto p : Range{ solid.nb_polyhedra() } )

src/geode/mesh/helpers/detail/element_identifier.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,13 @@ namespace geode
8181
}
8282
const auto facets_vertices =
8383
solid.polyhedron_facets_vertices( polyhedron_id );
84-
if( facets_vertices.size() != 8 )
84+
if( facets_vertices.size() != 5 )
8585
{
8686
return false;
8787
}
8888
for( const auto &facet_vertices : facets_vertices )
8989
{
90-
if( facet_vertices.size() != 3 )
90+
if( facet_vertices.size() != 3 && facet_vertices.size() != 4 )
9191
{
9292
return false;
9393
}

tests/mesh/test-convert-solid.cpp

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,19 @@
3030

3131
#include <geode/mesh/builder/regular_grid_solid_builder.h>
3232
#include <geode/mesh/builder/tetrahedral_solid_builder.h>
33+
#include <geode/mesh/core/hybrid_solid.h>
3334
#include <geode/mesh/core/light_regular_grid.h>
3435
#include <geode/mesh/core/regular_grid_solid.h>
3536
#include <geode/mesh/core/tetrahedral_solid.h>
3637
#include <geode/mesh/helpers/detail/split_along_solid_facets.h>
38+
#include <geode/mesh/io/hybrid_solid_output.h>
3739
#include <geode/mesh/io/tetrahedral_solid_output.h>
3840

3941
#include <geode/mesh/helpers/convert_solid_mesh.h>
4042

41-
void test()
43+
// NOLINTBEGIN(*-magic-numbers)
44+
45+
void test_tetrahedral_solid()
4246
{
4347
geode::OpenGeodeMeshLibrary::initialize();
4448
auto mesh_grid = geode::RegularGrid3D::create();
@@ -86,4 +90,75 @@ void test()
8690
splitter.split_solid_along_facets( {} );
8791
}
8892

89-
OPENGEODE_TEST( "convert-solid" )
93+
void test_hybrid_solid()
94+
{
95+
geode::OpenGeodeMeshLibrary::initialize();
96+
std::vector< geode::Point3D > hex_points{
97+
{ { 0, 0, 0 } },
98+
{ { 1, 0, 0 } },
99+
{ { 0, 1, 0 } },
100+
{ { 1, 1, 0 } },
101+
{ { 0, 0, 1 } },
102+
{ { 1, 0, 1 } },
103+
{ { 0, 1, 1 } },
104+
{ { 1, 1, 1 } },
105+
};
106+
auto hex = geode::SolidMesh3D::create();
107+
auto builder_hex = geode::SolidMeshBuilder3D::create( *hex );
108+
for( const auto& point : hex_points )
109+
{
110+
builder_hex->create_point( point );
111+
}
112+
builder_hex->create_polyhedron( { 0, 1, 2, 3, 4, 5, 6, 7 },
113+
{ { 0, 2, 3, 1 }, { 0, 4, 5, 1 }, { 3, 1, 5, 7 }, { 4, 6, 7, 5 },
114+
{ 2, 3, 7, 6 }, { 0, 2, 6, 4 } } );
115+
auto hybrid_solid_hex = geode::convert_solid_mesh_into_hybrid_solid( *hex );
116+
geode::save_hybrid_solid(
117+
*hybrid_solid_hex.value(), "hybrid_solid_hex.og_hso3d" );
118+
std::vector< geode::Point3D > prism_points{
119+
{ { 0, 0, 0 } },
120+
{ { 1, 0, 0 } },
121+
{ { 0, 1, 0 } },
122+
{ { 0, 0, 1 } },
123+
{ { 1, 0, 1 } },
124+
{ { 0, 1, 1 } },
125+
};
126+
auto prism = geode::SolidMesh3D::create();
127+
auto builder_prism = geode::SolidMeshBuilder3D::create( *prism );
128+
for( const auto& point : prism_points )
129+
{
130+
builder_prism->create_point( point );
131+
}
132+
builder_prism->create_polyhedron(
133+
{ 0, 1, 2, 3, 4, 5 }, { { 0, 2, 1 }, { 3, 5, 4 }, { 0, 3, 4, 1 },
134+
{ 0, 3, 5, 2 }, { 1, 4, 5, 2 } } );
135+
auto hybrid_solid_prism =
136+
geode::convert_solid_mesh_into_hybrid_solid( *prism );
137+
geode::save_hybrid_solid(
138+
*hybrid_solid_prism.value(), "hybrid_solid_prism.og_hso3d" );
139+
std::vector< geode::Point3D > pyramid_points{ { { 0, 0, 0 } },
140+
{ { 1, 0, 0 } }, { { 1, 1, 0 } }, { { 0, 1, 0 } },
141+
{ { 0.5, 0.5, 1 } } };
142+
auto pyramid = geode::SolidMesh3D::create();
143+
auto builder_pyramid = geode::SolidMeshBuilder3D::create( *pyramid );
144+
for( const auto& point : pyramid_points )
145+
{
146+
builder_pyramid->create_point( point );
147+
}
148+
builder_pyramid->create_polyhedron(
149+
{ 0, 1, 2, 3, 4 }, { { 0, 4, 1 }, { 0, 4, 3 }, { 1, 4, 2 }, { 4, 3, 2 },
150+
{ 0, 3, 2, 1 } } );
151+
auto hybrid_solid_pyramid =
152+
geode::convert_solid_mesh_into_hybrid_solid( *pyramid );
153+
geode::save_hybrid_solid(
154+
*hybrid_solid_pyramid.value(), "hybrid_solid_pyramid.og_hso3d" );
155+
}
156+
157+
void test()
158+
{
159+
test_tetrahedral_solid();
160+
test_hybrid_solid();
161+
}
162+
163+
OPENGEODE_TEST( "convert-solid" )
164+
// NOLINTEND(*-magic-numbers)

0 commit comments

Comments
 (0)