Skip to content

Commit bb60b47

Browse files
Merge pull request #108 from Geode-solutions/fix/add-check-for-brep-validity
fix(BRepMeshesManifold): add test to detect non manifold facets and e…
2 parents 02ac485 + 7e6a89c commit bb60b47

File tree

6 files changed

+303
-104
lines changed

6 files changed

+303
-104
lines changed

bindings/python/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# This file is autogenerated by pip-compile with Python 3.10
33
# by the following command:
44
#
5-
# pip-compile bindings/python/requirements.in
5+
# pip-compile --pre bindings/python/requirements.in
66
#
7-
opengeode-core==15.*,>=15.4.7
7+
opengeode-core==15.*,>=15.4.8
88
# via -r bindings/python/requirements.in

bindings/python/tests/test-py-brep.py

Lines changed: 124 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -31,146 +31,172 @@
3131
import opengeode_inspector_py_inspector as inspector
3232

3333

34-
def corners_topological_validity(result, verbose ) :
35-
nb_issues = 0
36-
for corner_issue in result.corners_not_linked_to_a_unique_vertex.issues_map() :
34+
def corners_topological_validity(result, verbose):
35+
nb_issues = 0
36+
for corner_issue in result.corners_not_linked_to_a_unique_vertex.issues_map():
3737
nb_issues += corner_issue[1].nb_issues()
3838
nb_issues += result.corners_not_meshed.nb_issues()
3939
nb_issues += result.unique_vertices_liked_to_not_boundary_line_corner.nb_issues()
4040
nb_issues += result.unique_vertices_linked_to_multiple_corners.nb_issues()
4141
nb_issues += result.unique_vertices_linked_to_multiple_internals_corner.nb_issues()
42-
nb_issues += result.unique_vertices_linked_to_not_internal_nor_boundary_corner.nb_issues()
43-
print( "BRep Corners Topology check: ", nb_issues, " issues." )
44-
if verbose :
45-
print(result.string(), "\n" )
42+
nb_issues += (
43+
result.unique_vertices_linked_to_not_internal_nor_boundary_corner.nb_issues()
44+
)
45+
print("BRep Corners Topology check: ", nb_issues, " issues.")
46+
if verbose:
47+
print(result.string(), "\n")
4648
return nb_issues
4749

50+
4851
def lines_topological_validity(result, verbose):
4952
nb_issues = 0
50-
for issue in result.lines_not_linked_to_a_unique_vertex.issues_map() :
53+
for issue in result.lines_not_linked_to_a_unique_vertex.issues_map():
5154
nb_issues += issue[1].nb_issues()
5255
nb_issues += result.lines_not_meshed.nb_issues()
53-
nb_issues += result.unique_vertices_linked_to_a_line_with_invalid_embeddings.nb_issues()
56+
nb_issues += (
57+
result.unique_vertices_linked_to_a_line_with_invalid_embeddings.nb_issues()
58+
)
5459
nb_issues += result.unique_vertices_linked_to_a_single_and_invalid_line.nb_issues()
55-
nb_issues += result.unique_vertices_linked_to_not_internal_nor_boundary_line.nb_issues()
56-
nb_issues += result.unique_vertices_linked_to_several_lines_but_not_linked_to_a_corner.nb_issues()
57-
print("BRep Lines Topology check: ", nb_issues, " issues." )
58-
if verbose : print(result.string(), "\n" )
60+
nb_issues += (
61+
result.unique_vertices_linked_to_not_internal_nor_boundary_line.nb_issues()
62+
)
63+
nb_issues += (
64+
result.unique_vertices_linked_to_several_lines_but_not_linked_to_a_corner.nb_issues()
65+
)
66+
print("BRep Lines Topology check: ", nb_issues, " issues.")
67+
if verbose:
68+
print(result.string(), "\n")
5969
return nb_issues
6070

61-
def surfaces_topological_validity( result, verbose ) :
71+
72+
def surfaces_topological_validity(result, verbose):
6273
nb_issues = 0
63-
for issue in result.surfaces_not_linked_to_a_unique_vertex.issues_map() :
74+
for issue in result.surfaces_not_linked_to_a_unique_vertex.issues_map():
6475
nb_issues += issue[1].nb_issues()
6576
nb_issues += result.surfaces_not_meshed.nb_issues()
66-
nb_issues += result.unique_vertices_linked_to_a_line_but_is_not_on_a_surface_border.nb_issues()
67-
nb_issues += result.unique_vertices_linked_to_a_single_and_invalid_surface.nb_issues()
68-
nb_issues += result.unique_vertices_linked_to_not_internal_nor_boundary_surface.nb_issues()
69-
nb_issues += result.unique_vertices_linked_to_several_and_invalid_surfaces.nb_issues()
70-
71-
print("BRep Surfaces Topology check: ", nb_issues, " issues." )
72-
if verbose :
73-
print(result.string(), "\n" )
77+
nb_issues += (
78+
result.unique_vertices_linked_to_a_line_but_is_not_on_a_surface_border.nb_issues()
79+
)
80+
nb_issues += (
81+
result.unique_vertices_linked_to_a_single_and_invalid_surface.nb_issues()
82+
)
83+
nb_issues += (
84+
result.unique_vertices_linked_to_not_internal_nor_boundary_surface.nb_issues()
85+
)
86+
nb_issues += (
87+
result.unique_vertices_linked_to_several_and_invalid_surfaces.nb_issues()
88+
)
89+
90+
print("BRep Surfaces Topology check: ", nb_issues, " issues.")
91+
if verbose:
92+
print(result.string(), "\n")
7493
return nb_issues
7594

76-
def blocks_topological_validity(result, verbose ):
95+
96+
def blocks_topological_validity(result, verbose):
7797
nb_issues = 0
78-
for issue in result.blocks_not_linked_to_a_unique_vertex.issues_map() :
98+
for issue in result.blocks_not_linked_to_a_unique_vertex.issues_map():
7999
nb_issues += issue[1].nb_issues()
80100
nb_issues += result.blocks_not_meshed.nb_issues()
81-
nb_issues += result.unique_vertices_part_of_two_blocks_and_no_boundary_surface.nb_issues()
101+
nb_issues += (
102+
result.unique_vertices_part_of_two_blocks_and_no_boundary_surface.nb_issues()
103+
)
82104
nb_issues += result.unique_vertices_with_incorrect_block_cmvs_count.nb_issues()
83-
print(
84-
"BRep Blocks Topology check: ", nb_issues, " issues." )
85-
if verbose :
86-
print(result.string(), "\n" )
105+
print("BRep Blocks Topology check: ", nb_issues, " issues.")
106+
if verbose:
107+
print(result.string(), "\n")
87108
return nb_issues
88109

89-
def launch_topological_validity_checks(result, verbose ):
90-
nb_issues = corners_topological_validity( result.corners, verbose )
91-
nb_issues += lines_topological_validity( result.lines, verbose )
92-
nb_issues += surfaces_topological_validity( result.surfaces, verbose )
93-
nb_issues += blocks_topological_validity( result.blocks, verbose )
110+
111+
def launch_topological_validity_checks(result, verbose):
112+
nb_issues = corners_topological_validity(result.corners, verbose)
113+
nb_issues += lines_topological_validity(result.lines, verbose)
114+
nb_issues += surfaces_topological_validity(result.surfaces, verbose)
115+
nb_issues += blocks_topological_validity(result.blocks, verbose)
94116
return nb_issues
95117

96-
def meshes_adjacencies_validity(result, verbose ) :
97-
nb_issues= 0
98-
for issue in result.surfaces_edges_with_wrong_adjacencies.issues_map() :
118+
119+
def meshes_adjacencies_validity(result, verbose):
120+
nb_issues = 0
121+
for issue in result.surfaces_edges_with_wrong_adjacencies.issues_map():
99122
nb_issues += issue[1].nb_issues()
100-
for issue in result.blocks_facets_with_wrong_adjacencies.issues_map() :
123+
for issue in result.blocks_facets_with_wrong_adjacencies.issues_map():
101124
nb_issues += issue[1].nb_issues()
102-
print(
103-
"BRep meshes adjacencies check: ", nb_issues, " issues." )
104-
if verbose :
105-
print( result.string(), "\n" )
125+
print("BRep meshes adjacencies check: ", nb_issues, " issues.")
126+
if verbose:
127+
print(result.string(), "\n")
106128
return nb_issues
107129

108130

109-
def meshes_degenerations_validity (result, verbose) :
131+
def meshes_degenerations_validity(result, verbose):
110132
nb_issues = 0
111-
for degenerated_elements in result.degenerated_edges.issues_map() :
133+
for degenerated_elements in result.degenerated_edges.issues_map():
112134
nb_issues += degenerated_elements[1].nb_issues()
113-
for degenerated_elements in result.degenerated_polygons.issues_map() :
135+
for degenerated_elements in result.degenerated_polygons.issues_map():
114136
nb_issues += degenerated_elements[1].nb_issues()
115-
for degenerated_elements in result.degenerated_polyhedra.issues_map() :
137+
for degenerated_elements in result.degenerated_polyhedra.issues_map():
116138
nb_issues += degenerated_elements[1].nb_issues()
117-
print(
118-
"BRep meshes degenerated elements check: ", nb_issues, " issues." )
119-
if verbose : print( result.string(), "\n" )
139+
print("BRep meshes degenerated elements check: ", nb_issues, " issues.")
140+
if verbose:
141+
print(result.string(), "\n")
120142
return nb_issues
121143

122-
def meshes_intersections_validity( result, verbose ) :
123-
nb_issues = 0
144+
145+
def meshes_intersections_validity(result, verbose):
146+
nb_issues = 0
124147
nb_issues += result.elements_intersections.nb_issues()
125-
print(
126-
"BRep meshes element intersections check: ", nb_issues, " issues." )
127-
if verbose :
128-
print( result.string(), "\n" )
148+
print("BRep meshes element intersections check: ", nb_issues, " issues.")
149+
if verbose:
150+
print(result.string(), "\n")
129151
return nb_issues
130152

131153

132-
def meshes_manifolds_validity(result, verbose) :
133-
nb_issues= 0
134-
for issue in result.meshes_non_manifold_vertices.issues_map() :
154+
def meshes_manifolds_validity(result, verbose):
155+
nb_issues = 0
156+
for issue in result.meshes_non_manifold_vertices.issues_map():
135157
nb_issues += issue[1].nb_issues()
136-
for issue in result.meshes_non_manifold_edges.issues_map() :
158+
for issue in result.meshes_non_manifold_edges.issues_map():
137159
nb_issues += issue[1].nb_issues()
138-
for issue in result.meshes_non_manifold_facets.issues_map() :
160+
for issue in result.meshes_non_manifold_facets.issues_map():
139161
nb_issues += issue[1].nb_issues()
140-
for issue in result.brep_non_manifold_edges.issues() :
162+
for issue in result.brep_non_manifold_edges.issues():
141163
nb_issues += len(issue.component_ids)
142-
print("BRep meshes non manifolds check: ", nb_issues, " issues." )
143-
if verbose :
144-
print(result.string(), "\n" )
164+
print("BRep meshes non manifolds check: ", nb_issues, " issues.")
165+
if verbose:
166+
print(result.string(), "\n")
145167
return nb_issues
146168

169+
147170
def meshes_colocations_validity(result, verbose):
148171
nb_issues = 0
149172
for issue in result.colocated_points_groups.issues_map():
150173
nb_issues += issue[1].nb_issues()
151-
print(
152-
"BRep meshes Colocations check: ", nb_issues, " issues." )
153-
if verbose :
154-
print( result.string(), "\n" )
174+
print("BRep meshes Colocations check: ", nb_issues, " issues.")
175+
if verbose:
176+
print(result.string(), "\n")
155177
return nb_issues
156178

179+
157180
def meshes_unique_vertices_validity(result, verbose):
158181
nb_issues = 0
159-
for issue in result.colocated_unique_vertices_groups.issues() :
182+
for issue in result.colocated_unique_vertices_groups.issues():
160183
nb_issues += len(issue)
161184
nb_issues += result.unique_vertices_linked_to_different_points.nb_issues()
162-
print("BRep meshes Colocations check: ", nb_issues, " issues." )
163-
if verbose :
164-
print(result.string(), "\n" )
185+
print("BRep meshes Colocations check: ", nb_issues, " issues.")
186+
if verbose:
187+
print(result.string(), "\n")
165188
return nb_issues
166189

190+
167191
def launch_component_meshes_validity_checks(result, verbose):
168-
nb_invalids = meshes_adjacencies_validity(result.meshes_adjacencies,verbose)
169-
nb_invalids += meshes_degenerations_validity(result.meshes_degenerations,verbose)
170-
nb_invalids += meshes_intersections_validity(result.meshes_intersections,verbose)
171-
nb_invalids += meshes_manifolds_validity(result.meshes_non_manifolds,verbose)
172-
nb_invalids += meshes_colocations_validity(result.meshes_colocation,verbose)
173-
nb_invalids += meshes_unique_vertices_validity(result.unique_vertices_colocation,verbose)
192+
nb_invalids = meshes_adjacencies_validity(result.meshes_adjacencies, verbose)
193+
nb_invalids += meshes_degenerations_validity(result.meshes_degenerations, verbose)
194+
nb_invalids += meshes_intersections_validity(result.meshes_intersections, verbose)
195+
nb_invalids += meshes_manifolds_validity(result.meshes_non_manifolds, verbose)
196+
nb_invalids += meshes_colocations_validity(result.meshes_colocation, verbose)
197+
nb_invalids += meshes_unique_vertices_validity(
198+
result.unique_vertices_colocation, verbose
199+
)
174200
return nb_invalids
175201

176202

@@ -184,15 +210,17 @@ def check_a1(verbose):
184210
print("model_A1 topology is valid.")
185211
else:
186212
print("model_A1 topology is invalid.")
187-
nb_model_issues = launch_topological_validity_checks(result.topology,verbose)
213+
nb_model_issues = launch_topological_validity_checks(result.topology, verbose)
188214
if nb_model_issues != 267:
189215
raise ValueError(
190216
"[Test] model model_A1 should have 267 unique vertices with topological problems."
191217
)
192-
nb_component_meshes_issues = launch_component_meshes_validity_checks(result.meshes,verbose)
193-
if nb_component_meshes_issues != 13494:
218+
nb_component_meshes_issues = launch_component_meshes_validity_checks(
219+
result.meshes, verbose
220+
)
221+
if nb_component_meshes_issues != 13503:
194222
raise ValueError(
195-
"[Test] model model_A1_valid should have 13494 component meshes issues (pairs of component meshes triangles intersecting)."
223+
"[Test] model model_A1_valid should have 13503 component meshes issues (pairs of component meshes triangles intersecting)."
196224
)
197225

198226

@@ -206,15 +234,17 @@ def check_a1_valid(verbose):
206234
print("model_A1_valid topology is valid.")
207235
else:
208236
print("model_A1_valid topology is invalid.")
209-
nb_model_issues = launch_topological_validity_checks(result.topology,verbose)
237+
nb_model_issues = launch_topological_validity_checks(result.topology, verbose)
210238
if nb_model_issues != 267:
211239
raise ValueError(
212240
"[Test] model model_A1_valid should have 267 topological problems."
213241
)
214-
nb_component_meshes_issues = launch_component_meshes_validity_checks(result.meshes,verbose)
215-
if nb_component_meshes_issues != 13494:
242+
nb_component_meshes_issues = launch_component_meshes_validity_checks(
243+
result.meshes, verbose
244+
)
245+
if nb_component_meshes_issues != 13503:
216246
raise ValueError(
217-
"[Test] model model_A1_valid should have 13494 component meshes issues (pairs of component meshes triangles intersecting)."
247+
"[Test] model model_A1_valid should have 13503 component meshes issues (pairs of component meshes triangles intersecting)."
218248
)
219249

220250

@@ -228,12 +258,14 @@ def check_model_mss(verbose):
228258
print("model mss topology is valid.")
229259
else:
230260
print("model mss topology is invalid.")
231-
nb_model_issues = launch_topological_validity_checks(result.topology,verbose)
261+
nb_model_issues = launch_topological_validity_checks(result.topology, verbose)
232262
if nb_model_issues != 17:
233263
raise ValueError(
234264
"[Test] model mss.og_strm should have 34 topological problems."
235265
)
236-
nb_component_meshes_issues = launch_component_meshes_validity_checks(result.meshes, verbose)
266+
nb_component_meshes_issues = launch_component_meshes_validity_checks(
267+
result.meshes, verbose
268+
)
237269
if nb_component_meshes_issues != 0:
238270
raise ValueError("[Test] model mss should have no component meshes issues.")
239271

@@ -254,7 +286,9 @@ def check_model_D(verbose):
254286
raise ValueError(
255287
"[Test] model model_D.og_brep should have 5 topological problems (blocks not meshed)."
256288
)
257-
nb_component_meshes_issues = launch_component_meshes_validity_checks(result.meshes, verbose)
289+
nb_component_meshes_issues = launch_component_meshes_validity_checks(
290+
result.meshes, verbose
291+
)
258292
if nb_component_meshes_issues != 0:
259293
raise ValueError("[Test] model_D should have no component meshes issues.")
260294

include/geode/inspector/criterion/manifold/brep_meshes_manifold.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ namespace geode
4848
std::vector< uuid > component_ids;
4949
};
5050

51+
struct BRepNonManifoldFacet
52+
{
53+
std::array< index_t, 3 > facet;
54+
std::vector< uuid > component_ids;
55+
};
56+
5157
struct opengeode_inspector_inspector_api BRepMeshesManifoldInspectionResult
5258
{
5359
InspectionIssuesMap< index_t > meshes_non_manifold_vertices{
@@ -65,6 +71,10 @@ namespace geode
6571
"BRep non manifold edges"
6672
};
6773

74+
InspectionIssues< BRepNonManifoldFacet > brep_non_manifold_facets{
75+
"BRep non manifold facets"
76+
};
77+
6878
[[nodiscard]] std::string string() const;
6979

7080
[[nodiscard]] std::string inspection_type() const;

0 commit comments

Comments
 (0)