|
26 | 26 | from google.protobuf.wrappers_pb2 import BoolValue, DoubleValue
|
27 | 27 |
|
28 | 28 | from ansys.api.geometry.v0.bodies_pb2_grpc import BodiesStub
|
| 29 | +from ansys.api.geometry.v0.models_pb2 import ( |
| 30 | + InspectGeometryMessageId, |
| 31 | + InspectGeometryMessageType, |
| 32 | + InspectGeometryResult, |
| 33 | + InspectGeometryResultIssue, |
| 34 | +) |
29 | 35 | from ansys.api.geometry.v0.repairtools_pb2 import (
|
30 | 36 | FindAdjustSimplifyRequest,
|
31 | 37 | FindDuplicateFacesRequest,
|
|
37 | 43 | FindSmallFacesRequest,
|
38 | 44 | FindSplitEdgesRequest,
|
39 | 45 | FindStitchFacesRequest,
|
| 46 | + InspectGeometryRequest, |
| 47 | + RepairGeometryRequest, |
40 | 48 | )
|
41 | 49 | from ansys.api.geometry.v0.repairtools_pb2_grpc import RepairToolsStub
|
42 | 50 | from ansys.geometry.core.connection import GrpcClient
|
|
52 | 60 | check_type_all_elements_in_iterable,
|
53 | 61 | min_backend_version,
|
54 | 62 | )
|
| 63 | +from ansys.geometry.core.tools.check_geometry import GeometryIssue, InspectResult |
55 | 64 | from ansys.geometry.core.tools.problem_areas import (
|
56 | 65 | DuplicateFaceProblemAreas,
|
57 | 66 | ExtraEdgeProblemAreas,
|
|
69 | 78 |
|
70 | 79 | if TYPE_CHECKING: # pragma: no cover
|
71 | 80 | from ansys.geometry.core.designer.body import Body
|
| 81 | + from ansys.geometry.core.modeler import Modeler |
72 | 82 |
|
73 | 83 |
|
74 | 84 | class RepairTools:
|
75 | 85 | """Repair tools for PyAnsys Geometry."""
|
76 | 86 |
|
77 |
| - def __init__(self, grpc_client: GrpcClient): |
| 87 | + def __init__(self, grpc_client: GrpcClient, modeler: "Modeler"): |
78 | 88 | """Initialize a new instance of the ``RepairTools`` class."""
|
79 | 89 | self._grpc_client = grpc_client
|
80 | 90 | self._repair_stub = RepairToolsStub(self._grpc_client.channel)
|
81 | 91 | self._bodies_stub = BodiesStub(self._grpc_client.channel)
|
| 92 | + self._modeler = modeler |
82 | 93 |
|
83 | 94 | @protect_grpc
|
84 | 95 | def find_split_edges(
|
@@ -598,3 +609,91 @@ def find_and_fix_split_edges(
|
598 | 609 | response.modified_bodies_monikers,
|
599 | 610 | )
|
600 | 611 | return message
|
| 612 | + |
| 613 | + @protect_grpc |
| 614 | + @min_backend_version(25, 2, 0) |
| 615 | + def inspect_geometry(self, bodies: list["Body"] = None) -> list[InspectResult]: |
| 616 | + """Return a list of geometry issues organized by body. |
| 617 | +
|
| 618 | + This method inspects the geometry and returns a list of the issues grouped by |
| 619 | + the body where they are found. |
| 620 | +
|
| 621 | + Parameters |
| 622 | + ---------- |
| 623 | + bodies : list[Body] |
| 624 | + List of bodies to inspect the geometry for. |
| 625 | + All bodies are inspected if the argument is not given. |
| 626 | +
|
| 627 | + Returns |
| 628 | + ------- |
| 629 | + list[IssuesByBody] |
| 630 | + List of objects representing geometry issues and the bodies where issues are found. |
| 631 | + """ |
| 632 | + parent_design = self._modeler.get_active_design() |
| 633 | + body_ids = [] if bodies is None else [body._grpc_id for body in bodies] |
| 634 | + inspect_result_response = self._repair_stub.InspectGeometry( |
| 635 | + InspectGeometryRequest(bodies=body_ids) |
| 636 | + ) |
| 637 | + return self.__create_inspect_result_from_response( |
| 638 | + parent_design, inspect_result_response.issues_by_body |
| 639 | + ) |
| 640 | + |
| 641 | + def __create_inspect_result_from_response( |
| 642 | + self, design, inspect_geometry_results: list[InspectGeometryResult] |
| 643 | + ) -> list[InspectResult]: |
| 644 | + inspect_results = [] |
| 645 | + for inspect_geometry_result in inspect_geometry_results: |
| 646 | + body = get_bodies_from_ids(design, [inspect_geometry_result.body.id]) |
| 647 | + issues = self.__create_issues_from_response(inspect_geometry_result.issues) |
| 648 | + inspect_result = InspectResult( |
| 649 | + grpc_client=self._grpc_client, body=body[0], issues=issues |
| 650 | + ) |
| 651 | + inspect_results.append(inspect_result) |
| 652 | + |
| 653 | + return inspect_results |
| 654 | + |
| 655 | + def __create_issues_from_response( |
| 656 | + self, |
| 657 | + inspect_geometry_result_issues: list[InspectGeometryResultIssue], |
| 658 | + ) -> list[GeometryIssue]: |
| 659 | + issues = [] |
| 660 | + for inspect_result_issue in inspect_geometry_result_issues: |
| 661 | + message_type = InspectGeometryMessageType.Name(inspect_result_issue.message_type) |
| 662 | + message_id = InspectGeometryMessageId.Name(inspect_result_issue.message_id) |
| 663 | + message = inspect_result_issue.message |
| 664 | + |
| 665 | + issue = GeometryIssue( |
| 666 | + message_type=message_type, |
| 667 | + message_id=message_id, |
| 668 | + message=message, |
| 669 | + faces=[face.id for face in inspect_result_issue.faces], |
| 670 | + edges=[edge.id for edge in inspect_result_issue.edges], |
| 671 | + ) |
| 672 | + issues.append(issue) |
| 673 | + return issues |
| 674 | + |
| 675 | + @protect_grpc |
| 676 | + @min_backend_version(25, 2, 0) |
| 677 | + def repair_geometry(self, bodies: list["Body"] = None) -> RepairToolMessage: |
| 678 | + """Attempt to repair the geometry for the given bodies. |
| 679 | +
|
| 680 | + This method inspects the geometry for the given bodies and attempts to repair them. |
| 681 | +
|
| 682 | + Parameters |
| 683 | + ---------- |
| 684 | + bodies : list[Body] |
| 685 | + List of bodies where to attempt to repair the geometry. |
| 686 | + All bodies are repaired if the argument is not given. |
| 687 | +
|
| 688 | + Returns |
| 689 | + ------- |
| 690 | + RepairToolMessage |
| 691 | + Message containing success of the operation. |
| 692 | + """ |
| 693 | + body_ids = [] if bodies is None else [body._grpc_id for body in bodies] |
| 694 | + repair_result_response = self._repair_stub.RepairGeometry( |
| 695 | + RepairGeometryRequest(bodies=body_ids) |
| 696 | + ) |
| 697 | + |
| 698 | + message = RepairToolMessage(repair_result_response.result.success, [], []) |
| 699 | + return message |
0 commit comments