@@ -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+
166306namespace 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 () } )
0 commit comments