Skip to content

Commit 4a3dda3

Browse files
test: Add more tests and update some tests (#2046)
Co-authored-by: pyansys-ci-bot <[email protected]>
1 parent 9eb0921 commit 4a3dda3

File tree

8 files changed

+277
-16
lines changed

8 files changed

+277
-16
lines changed

doc/changelog.d/2046.test.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add more tests and update some tests

src/ansys/geometry/core/_grpc/_services/v0/repair_tools.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,10 +359,14 @@ def find_and_fix_stitch_faces(self, **kwargs) -> dict: # noqa: D102
359359

360360
from ansys.api.geometry.v0.repairtools_pb2 import FindStitchFacesRequest
361361

362+
from ..base.conversions import from_measurement_to_server_length
363+
362364
# Create the request - assumes all inputs are valid and of the proper type
363365
request = FindStitchFacesRequest(
364366
faces=kwargs["body_ids"],
365-
maximum_distance=DoubleValue(value=kwargs["max_distance"])
367+
maximum_distance=DoubleValue(
368+
value=from_measurement_to_server_length(kwargs["max_distance"])
369+
)
366370
if kwargs["max_distance"] is not None
367371
else None,
368372
allow_multiple_bodies=BoolValue(value=kwargs["allow_multiple_bodies"]),
64.6 KB
Binary file not shown.
58.4 KB
Binary file not shown.
-27.4 MB
Binary file not shown.
6.83 MB
Binary file not shown.

tests/integration/test_prepare_tools.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ def test_remove_rounds(modeler: Modeler):
7171
result = modeler.prepare_tools.remove_rounds(roundfaces)
7272
assert len(design.bodies[0].faces) == 6
7373
assert result is True
74+
result = modeler.prepare_tools.remove_rounds([design.bodies[0].faces[0]])
75+
# test removing a face that is not a round
76+
assert result is True # remove round always returns True for success
77+
result = modeler.prepare_tools.remove_rounds(None)
78+
assert result == []
7479

7580

7681
def test_share_topology(modeler: Modeler):
@@ -97,6 +102,8 @@ def test_share_topology(modeler: Modeler):
97102
edges += len(body.edges)
98103
assert faces == 13
99104
assert edges == 27
105+
result = modeler.prepare_tools.share_topology(None)
106+
assert result is False
100107

101108

102109
def test_enhanced_share_topology(modeler: Modeler):
@@ -113,6 +120,8 @@ def test_enhanced_share_topology(modeler: Modeler):
113120
result = modeler.prepare_tools.enhanced_share_topology(design.bodies, 0.000554167, True)
114121
assert result.found == 14
115122
assert result.repaired == 14
123+
result = modeler.prepare_tools.enhanced_share_topology(None, 0, False)
124+
assert result.found == 0
116125

117126

118127
def test_detect_logos(modeler: Modeler):
@@ -132,6 +141,12 @@ def test_detect_logos(modeler: Modeler):
132141
success = modeler.prepare_tools.find_and_remove_logos(max_height=0.005)
133142
assert success is True
134143
assert len(body.faces) == 42
144+
result = modeler.prepare_tools.find_and_remove_logos(None, min_height=0.001, max_height=0.005)
145+
assert result is False
146+
result = modeler.prepare_tools.find_and_remove_logos(
147+
design.components[0].bodies, min_height=0.001, max_height=0.005
148+
)
149+
assert result is False
135150

136151

137152
def test_detect_and_fix_logo_as_problem_area(modeler: Modeler):
@@ -155,3 +170,38 @@ def test_detect_and_fix_logo_as_problem_area(modeler: Modeler):
155170
result.fix()
156171
assert success is False
157172
assert len(design.components[0].bodies[2].faces) == 42
173+
174+
175+
def test_volume_extract_bad_faces(modeler: Modeler):
176+
"""Test a volume extract with bad faces."""
177+
design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx")
178+
179+
body = design.bodies[0]
180+
inside_faces = []
181+
sealing_faces = [body.faces[1], body.faces[4]]
182+
created_bodies = modeler.prepare_tools.extract_volume_from_faces(sealing_faces, inside_faces)
183+
assert len(created_bodies) == 0
184+
inside_faces = [body.faces[6]]
185+
sealing_faces = []
186+
created_bodies = modeler.prepare_tools.extract_volume_from_faces(sealing_faces, inside_faces)
187+
assert len(created_bodies) == 0
188+
inside_faces = [body.faces[0]]
189+
sealing_faces = [body.faces[1]]
190+
created_bodies = modeler.prepare_tools.extract_volume_from_faces(sealing_faces, inside_faces)
191+
assert len(created_bodies) == 0
192+
193+
194+
def test_volume_extract_bad_edges(modeler: Modeler):
195+
"""Test a volume extract with bad edges."""
196+
design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx")
197+
body = design.bodies[0]
198+
sealing_edges = []
199+
created_bodies = modeler.prepare_tools.extract_volume_from_edge_loops(
200+
sealing_edges,
201+
)
202+
assert len(created_bodies) == 0
203+
sealing_edges = [body.edges[0], body.edges[1]]
204+
created_bodies = modeler.prepare_tools.extract_volume_from_edge_loops(
205+
sealing_edges,
206+
)
207+
assert len(created_bodies) == 0

tests/integration/test_repair_tools.py

Lines changed: 221 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,24 @@
2121
# SOFTWARE.
2222
""" "Testing of repair tools."""
2323

24+
import pytest
25+
2426
from ansys.geometry.core.modeler import Modeler
27+
from ansys.geometry.core.tools.check_geometry import InspectResult
28+
from ansys.geometry.core.tools.problem_areas import (
29+
DuplicateFaceProblemAreas,
30+
ExtraEdgeProblemAreas,
31+
InterferenceProblemAreas,
32+
MissingFaceProblemAreas,
33+
ProblemArea,
34+
ShortEdgeProblemAreas,
35+
SmallFaceProblemAreas,
36+
SplitEdgeProblemAreas,
37+
StitchFaceProblemAreas,
38+
UnsimplifiedFaceProblemAreas,
39+
)
40+
from ansys.geometry.core.tools.repair_tool_message import RepairToolMessage
41+
from ansys.geometry.core.tools.repair_tools import RepairTools
2542

2643
from .conftest import FILES_DIR
2744

@@ -219,7 +236,7 @@ def test_fix_small_face(modeler: Modeler):
219236
def test_find_stitch_faces(modeler: Modeler):
220237
"""Test to read geometry and find it's stitch face problem areas."""
221238
design = modeler.open_file(FILES_DIR / "stitch_before.scdocx")
222-
problem_areas = modeler.repair_tools.find_stitch_faces(design.bodies)
239+
problem_areas = modeler.repair_tools.find_stitch_faces(design.bodies, 0.0001)
223240
assert len(problem_areas) == 1
224241

225242

@@ -283,28 +300,28 @@ def test_fix_interference(modeler: Modeler):
283300

284301
def test_find_and_fix_stitch_faces(modeler: Modeler):
285302
"""Test to find and fix stitch faces and validate that we get a solid."""
286-
design = modeler.open_file(FILES_DIR / "stitch_1200_bodies.dsco")
287-
assert len(design.bodies) == 3600
303+
design = modeler.open_file(FILES_DIR / "stitch_300_bodies.dsco")
304+
assert len(design.bodies) == 900
288305

289-
stitch_faces = modeler.repair_tools.find_and_fix_stitch_faces(design.bodies)
306+
stitch_faces = modeler.repair_tools.find_and_fix_stitch_faces(design.bodies, 0.0001)
290307
assert stitch_faces.found == 1
291308
assert stitch_faces.repaired == 1
292309

293-
assert len(design.bodies) == 1200
310+
assert len(design.bodies) == 300
294311

295312

296313
def test_find_and_fix_stitch_faces_comprehensive(modeler: Modeler):
297314
"""Test to find and fix stitch faces and validate that we get a solid."""
298-
design = modeler.open_file(FILES_DIR / "stitch_1200_bodies.dsco")
299-
assert len(design.bodies) == 3600
315+
design = modeler.open_file(FILES_DIR / "stitch_300_bodies.dsco")
316+
assert len(design.bodies) == 900
300317

301318
stitch_faces = modeler.repair_tools.find_and_fix_stitch_faces(
302319
design.bodies, comprehensive_result=True
303320
)
304-
assert stitch_faces.found == 1200
305-
assert stitch_faces.repaired == 1200
321+
assert stitch_faces.found == 300
322+
assert stitch_faces.repaired == 300
306323

307-
assert len(design.bodies) == 1200
324+
assert len(design.bodies) == 300
308325

309326

310327
def test_find_and_fix_duplicate_faces(modeler: Modeler):
@@ -393,14 +410,16 @@ def test_find_and_fix_missing_faces(modeler: Modeler):
393410
def test_find_and_fix_missing_faces_angle_distance(modeler: Modeler):
394411
"""Test to read geometry, find and fix missing faces specify angle and distance."""
395412
design = modeler.open_file(FILES_DIR / "MissingFaces_AngleDistance.scdocx")
396-
assert len(design.bodies) == 1
397-
assert len(design.bodies[0].faces) == 11
398-
missing_faces = modeler.repair_tools.find_missing_faces(design.bodies, 0.785398, 0.0005)
413+
assert len(design.bodies) == 4
414+
total_faces = sum(len(body.faces) for body in design.bodies)
415+
assert total_faces == 22
416+
missing_faces = modeler.repair_tools.find_missing_faces(design.bodies, 0.698131, 0.015)
399417
assert len(missing_faces) == 4
400418
for face in missing_faces:
401419
face.fix()
402-
assert len(design.bodies) == 1
403-
assert len(design.bodies[0].faces) == 15
420+
assert len(design.bodies) == 4
421+
total_faces = sum(len(body.faces) for body in design.bodies)
422+
assert total_faces == 26
404423

405424

406425
def test_find_and_fix_short_edges_problem_areas(modeler: Modeler):
@@ -560,3 +579,190 @@ def test_find_and_fix_simplify(modeler: Modeler):
560579
assert result
561580
assert result.found == 23
562581
assert result.repaired == 23 # There is a SC bug where success is always true
582+
583+
584+
def test_design_import_check_geometry(modeler: Modeler):
585+
"""Test importing a design with check geometry."""
586+
# Open the design
587+
design = modeler.open_file(FILES_DIR / "Nonmanifold_CheckGeometry.scdocx")
588+
inspect_results = modeler.repair_tools.inspect_geometry(design.bodies)
589+
590+
# Assert the number of inspect results and issues
591+
assert len(inspect_results) == 1
592+
issues = inspect_results[0].issues
593+
assert len(issues) == 5
594+
595+
# Expected messages, message IDs, and message types
596+
expected_data = [
597+
{
598+
"message": "Geometry intersects itself.",
599+
"message_id": 26,
600+
"message_type": 3,
601+
"faces": 0,
602+
"edges": 0,
603+
},
604+
{
605+
"message": "Geometry intersects itself.",
606+
"message_id": 26,
607+
"message_type": 3,
608+
"faces": 0,
609+
"edges": 0,
610+
},
611+
{
612+
"message": "Geometry intersects itself.",
613+
"message_id": 26,
614+
"message_type": 3,
615+
"faces": 0,
616+
"edges": 0,
617+
},
618+
{
619+
"message": "Geometry intersects itself.",
620+
"message_id": 26,
621+
"message_type": 3,
622+
"faces": 0,
623+
"edges": 0,
624+
},
625+
{
626+
"message": "Face illegally intersects or abuts another face.",
627+
"message_id": 25,
628+
"message_type": 3,
629+
"faces": 2,
630+
"edges": 0,
631+
},
632+
]
633+
634+
# Convert issues and expected data to sets of tuples for comparison
635+
actual_data = {
636+
(
637+
issue.message,
638+
issue.message_id,
639+
issue.message_type,
640+
len(issue.faces),
641+
len(issue.edges),
642+
)
643+
for issue in issues
644+
}
645+
646+
expected_data_set = {
647+
(
648+
item["message"],
649+
item["message_id"],
650+
item["message_type"],
651+
item["faces"],
652+
item["edges"],
653+
)
654+
for item in expected_data
655+
}
656+
657+
# Assert that the actual data matches the expected data regardless of order
658+
assert actual_data == expected_data_set
659+
660+
# Test repair functionality
661+
repair_message = inspect_results[0].repair()
662+
assert repair_message.success is True
663+
assert repair_message.created_bodies == []
664+
assert repair_message.modified_bodies == []
665+
666+
667+
def test_repair_no_body(modeler: Modeler):
668+
"""Test the repair method when body is None."""
669+
grpc_client = modeler.client
670+
# Create an instance of InspectResult with body set to None
671+
inspect_result = InspectResult(grpc_client=grpc_client, body=None, issues=[])
672+
# Call the repair method
673+
repair_message = inspect_result.repair()
674+
# Assert the returned RepairToolMessage
675+
assert isinstance(repair_message, RepairToolMessage)
676+
assert repair_message.success is False
677+
assert repair_message.created_bodies == []
678+
assert repair_message.modified_bodies == []
679+
680+
681+
def test_problem_area_fix_not_implemented(modeler: Modeler):
682+
"""Test that the fix method in the ProblemArea base class raises NotImplementedError."""
683+
grpc_client = modeler.client
684+
# Create an instance of ProblemArea
685+
problem_area = ProblemArea(id="123", grpc_client=grpc_client)
686+
# Assert that calling fix raises NotImplementedError
687+
with pytest.raises(
688+
NotImplementedError, match="Fix method is not implemented in the base class."
689+
):
690+
problem_area.fix()
691+
692+
693+
@pytest.mark.parametrize(
694+
"problem_area_class, kwargs",
695+
[
696+
(DuplicateFaceProblemAreas, {"faces": []}),
697+
(MissingFaceProblemAreas, {"edges": []}),
698+
(ExtraEdgeProblemAreas, {"edges": []}),
699+
(ShortEdgeProblemAreas, {"edges": []}),
700+
(SmallFaceProblemAreas, {"faces": []}),
701+
(SplitEdgeProblemAreas, {"edges": []}),
702+
(StitchFaceProblemAreas, {"bodies": []}),
703+
(UnsimplifiedFaceProblemAreas, {"faces": []}),
704+
(InterferenceProblemAreas, {"bodies": []}),
705+
],
706+
)
707+
def test_problem_area_fix_no_data(modeler: Modeler, problem_area_class, kwargs):
708+
"""Test the fix method for various ProblemArea subclasses when required attributes are empty."""
709+
grpc_client = modeler.client
710+
problem_area = problem_area_class(id="123", grpc_client=grpc_client, **kwargs)
711+
repair_message = problem_area.fix()
712+
assert isinstance(repair_message, RepairToolMessage)
713+
assert repair_message.success is False
714+
assert repair_message.created_bodies == []
715+
assert repair_message.modified_bodies == []
716+
717+
718+
@pytest.mark.parametrize(
719+
"method_name",
720+
[
721+
"find_split_edges",
722+
"find_extra_edges",
723+
"find_inexact_edges",
724+
"find_short_edges",
725+
"find_duplicate_faces",
726+
"find_missing_faces",
727+
"find_small_faces",
728+
"find_interferences",
729+
],
730+
)
731+
def test_repair_tools_no_bodies(modeler: Modeler, method_name):
732+
"""Test RepairTools methods when bodies is empty or None."""
733+
grpc_client = modeler.client
734+
repair_tools = RepairTools(grpc_client, modeler)
735+
method = getattr(repair_tools, method_name)
736+
737+
# Test with an empty list of bodies
738+
result = method(bodies=[])
739+
assert result == []
740+
741+
# Test with None as bodies
742+
result = method(bodies=None)
743+
assert result == []
744+
745+
746+
@pytest.mark.parametrize(
747+
"method_name",
748+
[
749+
"find_and_fix_short_edges",
750+
"find_and_fix_extra_edges",
751+
"find_and_fix_split_edges",
752+
"find_and_fix_simplify",
753+
],
754+
)
755+
def test_repair_tools_find_and_fix_no_bodies(modeler: Modeler, method_name):
756+
"""Test RepairTools find_and_fix methods when bodies is empty or None."""
757+
grpc_client = modeler.client
758+
repair_tools = RepairTools(grpc_client, modeler)
759+
method = getattr(repair_tools, method_name)
760+
761+
# Test with an empty list of bodies
762+
result = method(bodies=[])
763+
assert isinstance(result, RepairToolMessage)
764+
assert result.success is False
765+
assert result.created_bodies == []
766+
assert result.modified_bodies == []
767+
assert result.found == 0
768+
assert result.repaired == 0

0 commit comments

Comments
 (0)