3232
3333#include < geode/geometry/point.h>
3434
35+ #include < geode/mesh/builder/solid_edges_builder.h>
3536#include < geode/mesh/builder/solid_facets_builder.h>
3637#include < geode/mesh/builder/solid_mesh_builder.h>
38+ #include < geode/mesh/core/solid_edges.h>
3739#include < geode/mesh/core/solid_facets.h>
3840#include < geode/mesh/core/solid_mesh.h>
3941
@@ -61,40 +63,45 @@ namespace geode
6163 }
6264
6365 MeshesElementsMapping cut_solid_along_facets (
64- absl::Span< index_t > facets_list )
66+ absl::Span< const PolyhedronFacet > facets_list )
6567 {
66- const auto nb_initial_facets = solid_.facets ().nb_facets ();
68+ bool facets_enabled = solid_.are_facets_enabled ();
69+ bool edges_enabled = solid_.are_edges_enabled ();
70+ const auto nb_initial_facets =
71+ facets_enabled ? solid_.facets ().nb_facets () : 0 ;
72+ const auto nb_initial_edges =
73+ edges_enabled ? solid_.edges ().nb_edges () : 0 ;
6774 const auto solid_info =
6875 remove_adjacencies_along_facets ( facets_list );
6976 MeshesElementsMapping mapping;
7077 mapping.vertices = duplicate_points ( solid_info );
71- mapping.polygons =
72- process_solid_facets ( nb_initial_facets, mapping.vertices );
78+ if ( facets_enabled )
79+ {
80+ mapping.polygons = process_solid_facets (
81+ nb_initial_facets, mapping.vertices );
82+ }
83+ if ( edges_enabled )
84+ {
85+ mapping.edges = process_solid_edges (
86+ nb_initial_edges, mapping.vertices );
87+ }
7388 return mapping;
7489 }
7590
7691 private:
7792 SolidInfo remove_adjacencies_along_facets (
78- absl::Span< index_t > facets_list )
93+ absl::Span< const PolyhedronFacet > facets_list )
7994 {
8095 SolidInfo info{ solid_.nb_vertices () };
81- for ( const auto facet_id : facets_list )
96+ for ( const auto solid_facet : facets_list )
8297 {
83- const auto facet_vertices =
84- solid_.facets ().facet_vertices ( facet_id );
85- const auto solid_facet =
86- solid_.polyhedron_facet_from_vertices ( facet_vertices );
87- OPENGEODE_EXCEPTION ( solid_facet,
88- " [CutAlongSolidFacets::remove_adjacencies_"
89- " along_facets] Should have found a "
90- " PolyhedronFacet from facet vertices." );
91- if ( const auto adj = solid_.polyhedron_adjacent_facet (
92- solid_facet.value () ) )
98+ if ( const auto adj =
99+ solid_.polyhedron_adjacent_facet ( solid_facet ) )
93100 {
94- builder_.unset_polyhedron_adjacent (
95- solid_facet.value () );
101+ builder_.unset_polyhedron_adjacent ( solid_facet );
96102 builder_.unset_polyhedron_adjacent ( adj.value () );
97- for ( const auto vertex_id : facet_vertices )
103+ for ( const auto vertex_id :
104+ solid_.polyhedron_facet_vertices ( solid_facet ) )
98105 {
99106 info.vertices_to_check [vertex_id] = true ;
100107 }
@@ -168,8 +175,9 @@ namespace geode
168175 builder_.create_point ( solid_.point ( vertex_id ) );
169176 solid_.vertex_attribute_manager ().copy_attribute_value (
170177 vertex_id, new_vertex_id );
171- // / Replaces vertex for all polyhedra around through current
172- // / adjacencies
178+ // / Replaces vertex for polyhedra around through current
179+ // / adjacencies -> for these polyhedra, removes facets on which
180+ // / adjacency was removed
173181 builder_.replace_vertex ( vertex_id, new_vertex_id );
174182 for ( const auto & polyhedron_vertex : all_polyhedra_around )
175183 {
@@ -234,7 +242,7 @@ namespace geode
234242 absl::Span< const index_t > clean_mapping ) const
235243 {
236244 ElementsMapping facets_mapping;
237- for ( const auto solid2cut : solid2cut_mapping.in2out_map () )
245+ for ( const auto & solid2cut : solid2cut_mapping.in2out_map () )
238246 {
239247 for ( const auto facet_after_cut : solid2cut.second )
240248 {
@@ -245,6 +253,60 @@ namespace geode
245253 return facets_mapping;
246254 }
247255
256+ ElementsMapping process_solid_edges ( index_t nb_initial_edges,
257+ const ElementsMapping& vertices_mapping )
258+ {
259+ ElementsMapping edges_mapping;
260+ auto edges_builder = builder_.edges_builder ();
261+ const auto & solid_edges = solid_.edges ();
262+ for ( const auto edge_id : Range{ solid_edges.nb_edges () } )
263+ {
264+ // / Recreate edges which were set to be deleted during
265+ // / duplication process by the replace_vertex method
266+ auto edge_vertices = solid_edges.edge_vertices ( edge_id );
267+ if ( solid_edges.is_edge_isolated ( edge_id ) )
268+ {
269+ if ( !solid_.polyhedron_facet_edge_from_vertices (
270+ edge_vertices ) )
271+ {
272+ continue ;
273+ }
274+ edges_builder.find_or_create_edge (
275+ solid_edges.edge_vertices ( edge_id ) );
276+ }
277+ if ( edge_id < nb_initial_edges )
278+ {
279+ edges_mapping.map ( edge_id, edge_id );
280+ continue ;
281+ }
282+ for ( auto & edge_vertex : edge_vertices )
283+ {
284+ edge_vertex = vertices_mapping.out2in ( edge_vertex )[0 ];
285+ }
286+ edges_mapping.map (
287+ solid_edges.edge_from_vertices ( edge_vertices ).value (),
288+ edge_id );
289+ }
290+ auto old2new = edges_builder.delete_isolated_edges ();
291+ return final_edges_mapping ( edges_mapping, old2new );
292+ }
293+
294+ ElementsMapping final_edges_mapping (
295+ const ElementsMapping& solid2cut_mapping,
296+ absl::Span< const index_t > clean_mapping ) const
297+ {
298+ ElementsMapping edges_mapping;
299+ for ( const auto & solid2cut : solid2cut_mapping.in2out_map () )
300+ {
301+ for ( const auto edge_after_cut : solid2cut.second )
302+ {
303+ edges_mapping.map (
304+ solid2cut.first , clean_mapping[edge_after_cut] );
305+ }
306+ }
307+ return edges_mapping;
308+ }
309+
248310 private:
249311 const SolidMesh3D& solid_;
250312 SolidMeshBuilder3D& builder_;
@@ -259,8 +321,9 @@ namespace geode
259321 CutAlongSolidFacets::~CutAlongSolidFacets () {}
260322
261323 MeshesElementsMapping CutAlongSolidFacets::cut_solid_along_facets (
262- absl::Span< index_t > facets_list )
324+ absl::Span< const PolyhedronFacet > facets_list )
263325 {
326+ return impl_->cut_solid_along_facets ( facets_list );
264327 }
265328 } // namespace detail
266329} // namespace geode
0 commit comments