From 97eb31adfd9dde4f1ecfa364d7408b09d17bfafd Mon Sep 17 00:00:00 2001 From: PyAnsys CI Bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Mon, 17 Feb 2025 15:31:37 +0100 Subject: [PATCH 01/20] chore: update CHANGELOG for v0.9.0 (#1753) --- doc/changelog.d/1258.test.md | 1 - doc/changelog.d/1706.maintenance.md | 1 - doc/changelog.d/1707.added.md | 1 - doc/changelog.d/1708.added.md | 1 - doc/changelog.d/1709.dependencies.md | 1 - doc/changelog.d/1711.fixed.md | 1 - doc/changelog.d/1712.added.md | 1 - doc/changelog.d/1713.test.md | 1 - doc/changelog.d/1714.fixed.md | 1 - doc/changelog.d/1715.fixed.md | 1 - doc/changelog.d/1716.added.md | 1 - doc/changelog.d/1717.maintenance.md | 1 - doc/changelog.d/1719.dependencies.md | 1 - doc/changelog.d/1720.dependencies.md | 1 - doc/changelog.d/1722.maintenance.md | 1 - doc/changelog.d/1723.added.md | 1 - doc/changelog.d/1725.fixed.md | 1 - doc/changelog.d/1726.dependencies.md | 1 - doc/changelog.d/1727.test.md | 1 - doc/changelog.d/1728.dependencies.md | 1 - doc/changelog.d/1729.dependencies.md | 1 - doc/changelog.d/1730.documentation.md | 1 - doc/changelog.d/1732.added.md | 1 - doc/changelog.d/1736.dependencies.md | 1 - doc/changelog.d/1737.maintenance.md | 1 - doc/changelog.d/1739.maintenance.md | 1 - doc/changelog.d/1740.added.md | 1 - doc/changelog.d/1741.added.md | 1 - doc/changelog.d/1742.dependencies.md | 1 - doc/changelog.d/1743.dependencies.md | 1 - doc/changelog.d/1744.dependencies.md | 1 - doc/changelog.d/1745.test.md | 1 - doc/changelog.d/1746.dependencies.md | 1 - doc/changelog.d/1747.dependencies.md | 1 - doc/changelog.d/1749.dependencies.md | 1 - doc/changelog.d/1750.maintenance.md | 1 - doc/changelog.d/1753.maintenance.md | 1 + doc/source/changelog.rst | 67 +++++++++++++++++++++++++++ 38 files changed, 68 insertions(+), 36 deletions(-) delete mode 100644 doc/changelog.d/1258.test.md delete mode 100644 doc/changelog.d/1706.maintenance.md delete mode 100644 doc/changelog.d/1707.added.md delete mode 100644 doc/changelog.d/1708.added.md delete mode 100644 doc/changelog.d/1709.dependencies.md delete mode 100644 doc/changelog.d/1711.fixed.md delete mode 100644 doc/changelog.d/1712.added.md delete mode 100644 doc/changelog.d/1713.test.md delete mode 100644 doc/changelog.d/1714.fixed.md delete mode 100644 doc/changelog.d/1715.fixed.md delete mode 100644 doc/changelog.d/1716.added.md delete mode 100644 doc/changelog.d/1717.maintenance.md delete mode 100644 doc/changelog.d/1719.dependencies.md delete mode 100644 doc/changelog.d/1720.dependencies.md delete mode 100644 doc/changelog.d/1722.maintenance.md delete mode 100644 doc/changelog.d/1723.added.md delete mode 100644 doc/changelog.d/1725.fixed.md delete mode 100644 doc/changelog.d/1726.dependencies.md delete mode 100644 doc/changelog.d/1727.test.md delete mode 100644 doc/changelog.d/1728.dependencies.md delete mode 100644 doc/changelog.d/1729.dependencies.md delete mode 100644 doc/changelog.d/1730.documentation.md delete mode 100644 doc/changelog.d/1732.added.md delete mode 100644 doc/changelog.d/1736.dependencies.md delete mode 100644 doc/changelog.d/1737.maintenance.md delete mode 100644 doc/changelog.d/1739.maintenance.md delete mode 100644 doc/changelog.d/1740.added.md delete mode 100644 doc/changelog.d/1741.added.md delete mode 100644 doc/changelog.d/1742.dependencies.md delete mode 100644 doc/changelog.d/1743.dependencies.md delete mode 100644 doc/changelog.d/1744.dependencies.md delete mode 100644 doc/changelog.d/1745.test.md delete mode 100644 doc/changelog.d/1746.dependencies.md delete mode 100644 doc/changelog.d/1747.dependencies.md delete mode 100644 doc/changelog.d/1749.dependencies.md delete mode 100644 doc/changelog.d/1750.maintenance.md create mode 100644 doc/changelog.d/1753.maintenance.md diff --git a/doc/changelog.d/1258.test.md b/doc/changelog.d/1258.test.md deleted file mode 100644 index 7cde69eb55..0000000000 --- a/doc/changelog.d/1258.test.md +++ /dev/null @@ -1 +0,0 @@ -verifying issue with empty intersect and temporal body creation \ No newline at end of file diff --git a/doc/changelog.d/1706.maintenance.md b/doc/changelog.d/1706.maintenance.md deleted file mode 100644 index 6f4c1c0089..0000000000 --- a/doc/changelog.d/1706.maintenance.md +++ /dev/null @@ -1 +0,0 @@ -update CHANGELOG for v0.8.2 \ No newline at end of file diff --git a/doc/changelog.d/1707.added.md b/doc/changelog.d/1707.added.md deleted file mode 100644 index 2602f1720f..0000000000 --- a/doc/changelog.d/1707.added.md +++ /dev/null @@ -1 +0,0 @@ -design activation changes \ No newline at end of file diff --git a/doc/changelog.d/1708.added.md b/doc/changelog.d/1708.added.md deleted file mode 100644 index 52cde5ead5..0000000000 --- a/doc/changelog.d/1708.added.md +++ /dev/null @@ -1 +0,0 @@ -add contributors \ No newline at end of file diff --git a/doc/changelog.d/1709.dependencies.md b/doc/changelog.d/1709.dependencies.md deleted file mode 100644 index 3c05c97bf8..0000000000 --- a/doc/changelog.d/1709.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump ansys-api-geometry from 0.4.33 to 0.4.34 \ No newline at end of file diff --git a/doc/changelog.d/1711.fixed.md b/doc/changelog.d/1711.fixed.md deleted file mode 100644 index 277af98686..0000000000 --- a/doc/changelog.d/1711.fixed.md +++ /dev/null @@ -1 +0,0 @@ -re enable fmd tests \ No newline at end of file diff --git a/doc/changelog.d/1712.added.md b/doc/changelog.d/1712.added.md deleted file mode 100644 index 0d2f01063a..0000000000 --- a/doc/changelog.d/1712.added.md +++ /dev/null @@ -1 +0,0 @@ -Implementation of inspect & repair geometry \ No newline at end of file diff --git a/doc/changelog.d/1713.test.md b/doc/changelog.d/1713.test.md deleted file mode 100644 index 4c10d27211..0000000000 --- a/doc/changelog.d/1713.test.md +++ /dev/null @@ -1 +0,0 @@ -Expand pattern tests \ No newline at end of file diff --git a/doc/changelog.d/1714.fixed.md b/doc/changelog.d/1714.fixed.md deleted file mode 100644 index e58c41f4d9..0000000000 --- a/doc/changelog.d/1714.fixed.md +++ /dev/null @@ -1 +0,0 @@ -support body mirror on linux \ No newline at end of file diff --git a/doc/changelog.d/1715.fixed.md b/doc/changelog.d/1715.fixed.md deleted file mode 100644 index 9af9372ee1..0000000000 --- a/doc/changelog.d/1715.fixed.md +++ /dev/null @@ -1 +0,0 @@ -use sketch plane for imprint/project curves \ No newline at end of file diff --git a/doc/changelog.d/1716.added.md b/doc/changelog.d/1716.added.md deleted file mode 100644 index e90bde071a..0000000000 --- a/doc/changelog.d/1716.added.md +++ /dev/null @@ -1 +0,0 @@ -launch core service from envar \ No newline at end of file diff --git a/doc/changelog.d/1717.maintenance.md b/doc/changelog.d/1717.maintenance.md deleted file mode 100644 index c655a0905a..0000000000 --- a/doc/changelog.d/1717.maintenance.md +++ /dev/null @@ -1 +0,0 @@ -pre-commit automatic update \ No newline at end of file diff --git a/doc/changelog.d/1719.dependencies.md b/doc/changelog.d/1719.dependencies.md deleted file mode 100644 index 883bfafc7c..0000000000 --- a/doc/changelog.d/1719.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump ansys-sphinx-theme[autoapi] from 1.2.6 to 1.2.7 in the docs-deps group \ No newline at end of file diff --git a/doc/changelog.d/1720.dependencies.md b/doc/changelog.d/1720.dependencies.md deleted file mode 100644 index 0f3ca21a1e..0000000000 --- a/doc/changelog.d/1720.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump ansys-api-geometry from 0.4.34 to 0.4.35 \ No newline at end of file diff --git a/doc/changelog.d/1722.maintenance.md b/doc/changelog.d/1722.maintenance.md deleted file mode 100644 index 61a75a0ef5..0000000000 --- a/doc/changelog.d/1722.maintenance.md +++ /dev/null @@ -1 +0,0 @@ -update SECURITY.md versions supported \ No newline at end of file diff --git a/doc/changelog.d/1723.added.md b/doc/changelog.d/1723.added.md deleted file mode 100644 index 27a925f003..0000000000 --- a/doc/changelog.d/1723.added.md +++ /dev/null @@ -1 +0,0 @@ -workflow enhancements for better tool results \ No newline at end of file diff --git a/doc/changelog.d/1725.fixed.md b/doc/changelog.d/1725.fixed.md deleted file mode 100644 index 5bec5d4ba9..0000000000 --- a/doc/changelog.d/1725.fixed.md +++ /dev/null @@ -1 +0,0 @@ -revert boolean ops logic and hold-off on commands-based implementation (temporarily) \ No newline at end of file diff --git a/doc/changelog.d/1726.dependencies.md b/doc/changelog.d/1726.dependencies.md deleted file mode 100644 index aae2364dc8..0000000000 --- a/doc/changelog.d/1726.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump ansys-sphinx-theme[autoapi] from 1.2.7 to 1.3.0 in the docs-deps group \ No newline at end of file diff --git a/doc/changelog.d/1727.test.md b/doc/changelog.d/1727.test.md deleted file mode 100644 index d4caa81efc..0000000000 --- a/doc/changelog.d/1727.test.md +++ /dev/null @@ -1 +0,0 @@ -set body name \ No newline at end of file diff --git a/doc/changelog.d/1728.dependencies.md b/doc/changelog.d/1728.dependencies.md deleted file mode 100644 index 16cad54f2c..0000000000 --- a/doc/changelog.d/1728.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump ansys-sphinx-theme[autoapi] from 1.3.0 to 1.3.1 in the docs-deps group \ No newline at end of file diff --git a/doc/changelog.d/1729.dependencies.md b/doc/changelog.d/1729.dependencies.md deleted file mode 100644 index 7cfa83a813..0000000000 --- a/doc/changelog.d/1729.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump ansys-api-geometry from 0.4.35 to 0.4.36 \ No newline at end of file diff --git a/doc/changelog.d/1730.documentation.md b/doc/changelog.d/1730.documentation.md deleted file mode 100644 index deb88451eb..0000000000 --- a/doc/changelog.d/1730.documentation.md +++ /dev/null @@ -1 +0,0 @@ -update CONTRIBUTING.md \ No newline at end of file diff --git a/doc/changelog.d/1732.added.md b/doc/changelog.d/1732.added.md deleted file mode 100644 index 07b49458c3..0000000000 --- a/doc/changelog.d/1732.added.md +++ /dev/null @@ -1 +0,0 @@ -add face color, round info, bring measure tools to linux \ No newline at end of file diff --git a/doc/changelog.d/1736.dependencies.md b/doc/changelog.d/1736.dependencies.md deleted file mode 100644 index 5c12517a19..0000000000 --- a/doc/changelog.d/1736.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump trame-vtk from 2.8.14 to 2.8.15 \ No newline at end of file diff --git a/doc/changelog.d/1737.maintenance.md b/doc/changelog.d/1737.maintenance.md deleted file mode 100644 index c655a0905a..0000000000 --- a/doc/changelog.d/1737.maintenance.md +++ /dev/null @@ -1 +0,0 @@ -pre-commit automatic update \ No newline at end of file diff --git a/doc/changelog.d/1739.maintenance.md b/doc/changelog.d/1739.maintenance.md deleted file mode 100644 index 9e32bd93f9..0000000000 --- a/doc/changelog.d/1739.maintenance.md +++ /dev/null @@ -1 +0,0 @@ -keep simba-plugin-geometry tag \ No newline at end of file diff --git a/doc/changelog.d/1740.added.md b/doc/changelog.d/1740.added.md deleted file mode 100644 index c7191a660d..0000000000 --- a/doc/changelog.d/1740.added.md +++ /dev/null @@ -1 +0,0 @@ -conservative approach to single design per modeler \ No newline at end of file diff --git a/doc/changelog.d/1741.added.md b/doc/changelog.d/1741.added.md deleted file mode 100644 index bdcedd10cd..0000000000 --- a/doc/changelog.d/1741.added.md +++ /dev/null @@ -1 +0,0 @@ -export glb \ No newline at end of file diff --git a/doc/changelog.d/1742.dependencies.md b/doc/changelog.d/1742.dependencies.md deleted file mode 100644 index 14c7ab84ee..0000000000 --- a/doc/changelog.d/1742.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump jupytext from 1.16.6 to 1.16.7 in the docs-deps group \ No newline at end of file diff --git a/doc/changelog.d/1743.dependencies.md b/doc/changelog.d/1743.dependencies.md deleted file mode 100644 index d499e54ae5..0000000000 --- a/doc/changelog.d/1743.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump ansys-api-geometry from 0.4.36 to 0.4.37 \ No newline at end of file diff --git a/doc/changelog.d/1744.dependencies.md b/doc/changelog.d/1744.dependencies.md deleted file mode 100644 index 184bfb5bf9..0000000000 --- a/doc/changelog.d/1744.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump myst-parser from 4.0.0 to 4.0.1 in the docs-deps group \ No newline at end of file diff --git a/doc/changelog.d/1745.test.md b/doc/changelog.d/1745.test.md deleted file mode 100644 index 5a737e92ac..0000000000 --- a/doc/changelog.d/1745.test.md +++ /dev/null @@ -1 +0,0 @@ -activate 8 linux tests \ No newline at end of file diff --git a/doc/changelog.d/1746.dependencies.md b/doc/changelog.d/1746.dependencies.md deleted file mode 100644 index d9c564d265..0000000000 --- a/doc/changelog.d/1746.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump ansys-api-geometry from 0.4.37 to 0.4.38 \ No newline at end of file diff --git a/doc/changelog.d/1747.dependencies.md b/doc/changelog.d/1747.dependencies.md deleted file mode 100644 index 186365ae6f..0000000000 --- a/doc/changelog.d/1747.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump numpy from 2.2.2 to 2.2.3 \ No newline at end of file diff --git a/doc/changelog.d/1749.dependencies.md b/doc/changelog.d/1749.dependencies.md deleted file mode 100644 index daaa01a760..0000000000 --- a/doc/changelog.d/1749.dependencies.md +++ /dev/null @@ -1 +0,0 @@ -bump panel from 1.6.0 to 1.6.1 \ No newline at end of file diff --git a/doc/changelog.d/1750.maintenance.md b/doc/changelog.d/1750.maintenance.md deleted file mode 100644 index ed0a9ae502..0000000000 --- a/doc/changelog.d/1750.maintenance.md +++ /dev/null @@ -1 +0,0 @@ -enhancements to GLB export and object ``plot()`` methods \ No newline at end of file diff --git a/doc/changelog.d/1753.maintenance.md b/doc/changelog.d/1753.maintenance.md new file mode 100644 index 0000000000..97e5671828 --- /dev/null +++ b/doc/changelog.d/1753.maintenance.md @@ -0,0 +1 @@ +update CHANGELOG for v0.9.0 \ No newline at end of file diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 3583da64d4..cabf5ee6b2 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -9,6 +9,73 @@ This document contains the release notes for the PyAnsys Geometry project. .. towncrier release notes start +`0.9.0 `_ - 2025-02-17 +===================================================================================== + +Added +^^^^^ + +- design activation changes `#1707 `_ +- add contributors `#1708 `_ +- Implementation of inspect & repair geometry `#1712 `_ +- launch core service from envar `#1716 `_ +- workflow enhancements for better tool results `#1723 `_ +- add face color, round info, bring measure tools to linux `#1732 `_ +- conservative approach to single design per modeler `#1740 `_ +- export glb `#1741 `_ + + +Dependencies +^^^^^^^^^^^^ + +- bump ansys-api-geometry from 0.4.33 to 0.4.34 `#1709 `_ +- bump ansys-sphinx-theme[autoapi] from 1.2.6 to 1.2.7 in the docs-deps group `#1719 `_ +- bump ansys-api-geometry from 0.4.34 to 0.4.35 `#1720 `_ +- bump ansys-sphinx-theme[autoapi] from 1.2.7 to 1.3.0 in the docs-deps group `#1726 `_ +- bump ansys-sphinx-theme[autoapi] from 1.3.0 to 1.3.1 in the docs-deps group `#1728 `_ +- bump ansys-api-geometry from 0.4.35 to 0.4.36 `#1729 `_ +- bump trame-vtk from 2.8.14 to 2.8.15 `#1736 `_ +- bump jupytext from 1.16.6 to 1.16.7 in the docs-deps group `#1742 `_ +- bump ansys-api-geometry from 0.4.36 to 0.4.37 `#1743 `_ +- bump myst-parser from 4.0.0 to 4.0.1 in the docs-deps group `#1744 `_ +- bump ansys-api-geometry from 0.4.37 to 0.4.38 `#1746 `_ +- bump numpy from 2.2.2 to 2.2.3 `#1747 `_ +- bump panel from 1.6.0 to 1.6.1 `#1749 `_ + + +Documentation +^^^^^^^^^^^^^ + +- update CONTRIBUTING.md `#1730 `_ + + +Fixed +^^^^^ + +- re enable fmd tests `#1711 `_ +- support body mirror on linux `#1714 `_ +- use sketch plane for imprint/project curves `#1715 `_ +- revert boolean ops logic and hold-off on commands-based implementation (temporarily) `#1725 `_ + + +Maintenance +^^^^^^^^^^^ + +- update CHANGELOG for v0.8.2 `#1706 `_ +- pre-commit automatic update `#1717 `_, `#1737 `_ +- update SECURITY.md versions supported `#1722 `_ +- keep simba-plugin-geometry tag `#1739 `_ +- enhancements to GLB export and object ``plot()`` methods `#1750 `_ + + +Test +^^^^ + +- verifying issue with empty intersect and temporal body creation `#1258 `_ +- Expand pattern tests `#1713 `_ +- set body name `#1727 `_ +- activate 8 linux tests `#1745 `_ + `0.8.2 `_ - 2025-01-29 ===================================================================================== From 864a5375189671dcccde9680f746ba6410dea3a6 Mon Sep 17 00:00:00 2001 From: smereu Date: Tue, 18 Nov 2025 13:28:37 -0600 Subject: [PATCH 02/20] Exposure of enclosure APIs The PR exposes 3 separate APIs for the creation of Box, Cylinder and Sphere enclosure. Enclosure options are common to the 3 cases. Specific argument are given to each method and grpc request --- .../_grpc/_services/base/prepare_tools.py | 14 + .../core/_grpc/_services/v0/prepare_tools.py | 106 +++++++- .../core/_grpc/_services/v1/prepare_tools.py | 12 + .../geometry/core/tools/prepare_tools.py | 243 ++++++++++++++++++ tests/integration/test_prepare_tools.py | 63 ++++- 5 files changed, 436 insertions(+), 2 deletions(-) diff --git a/src/ansys/geometry/core/_grpc/_services/base/prepare_tools.py b/src/ansys/geometry/core/_grpc/_services/base/prepare_tools.py index 04d31db962..97bbc04485 100644 --- a/src/ansys/geometry/core/_grpc/_services/base/prepare_tools.py +++ b/src/ansys/geometry/core/_grpc/_services/base/prepare_tools.py @@ -83,3 +83,17 @@ def remove_logo(self, **kwargs) -> dict: def detect_helixes(self, **kwargs) -> dict: """Detect helixes in geometry.""" pass + + @abstractmethod + def create_box_enclosure(self, **kwargs) -> dict: + """Create a box enclosure around bodies.""" + pass + + @abstractmethod + def create_cylinder_enclosure(self, **kwargs) -> dict: + """Create a cylinder enclosure around bodies.""" + pass + + @abstractmethod + def create_sphere_enclosure(self, **kwargs) -> dict: + """Create a sphere enclosure around bodies.""" diff --git a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py index b783b952c4..d482746901 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py @@ -23,11 +23,20 @@ import grpc +from ansys.api.geometry.v0.preparetools_pb2 import ( + CreateEnclosureBoxRequest, + CreateEnclosureCylinderRequest, + CreateEnclosureSphereRequest, +) +from ansys.api.geometry.v0.models_pb2 import Body +from ansys.api.geometry.v0.preparetools_pb2 import EnclosureOptions as GRPCEnclosureOptions + from ansys.geometry.core.errors import protect_grpc +from ansys.geometry.core.tools.prepare_tools import EnclosureOptions from ..base.conversions import from_measurement_to_server_length from ..base.prepare_tools import GRPCPrepareToolsService -from .conversions import build_grpc_id +from .conversions import build_grpc_id, from_frame_to_grpc_frame, serialize_tracker_command_response class GRPCPrepareToolsServiceV0(GRPCPrepareToolsService): @@ -295,3 +304,98 @@ def detect_helixes(self, **kwargs) -> dict: # noqa: D102 for helix in response.helixes ] } + + @protect_grpc + def create_box_enclosure(self, **kwargs) -> dict: # noqa: D102 + enclosure_options = kwargs["enclosure_options"] + frame = enclosure_options.frame + grpc_enclosure_options = GRPCEnclosureOptions( + create_shared_topology=enclosure_options.create_shared_topology, + subtract_bodies=enclosure_options.subtract_bodies, + frame=from_frame_to_grpc_frame(frame) if frame is not None else None, + ) + # Create the request - assumes all inputs are valid and of the proper type + request = CreateEnclosureBoxRequest( + bodies=[Body(id=body.id) for body in kwargs["bodies"]], + x_low=kwargs["x_low"], + x_high=kwargs["x_high"], + y_low=kwargs["y_low"], + y_high=kwargs["y_high"], + z_low=kwargs["z_low"], + z_high=kwargs["z_high"], + enclosure_options=grpc_enclosure_options, + ) + + # Call the gRPC service + response = self.stub.CreateEnclosureBox(request) + + # Return the response - formatted as a dictionary + serialized_tracker_response = serialize_tracker_command_response( + response=response.command_response + ) + return { + "success": response.success, + "created_bodies": [body.id for body in response.created_bodies], + "tracker_response": serialized_tracker_response, + } + + @protect_grpc + def create_cylinder_enclosure(self, **kwargs) -> dict: # noqa: D102 + enclosure_options = kwargs["enclosure_options"] + frame = enclosure_options.frame + grpc_enclosure_options = GRPCEnclosureOptions( + create_shared_topology=enclosure_options.create_shared_topology, + subtract_bodies=enclosure_options.subtract_bodies, + frame=from_frame_to_grpc_frame(frame) if frame is not None else None, + ) + # Create the request - assumes all inputs are valid and of the proper type + request = CreateEnclosureCylinderRequest( + bodies=[Body(id=body.id) for body in kwargs["bodies"]], + axial_distance_low=kwargs["axial_distance_low"], + axial_distance_high=kwargs["axial_distance_high"], + radial_distance=kwargs["radial_distance"], + enclosure_options=grpc_enclosure_options, + ) + + # Call the gRPC service + response = self.stub.CreateEnclosureCylinder(request) + + # Return the response - formatted as a dictionary + serialized_tracker_response = serialize_tracker_command_response( + response=response.command_response + ) + return { + "success": response.success, + "created_bodies": [body.id for body in response.created_bodies], + "tracker_response": serialized_tracker_response, + } + + @protect_grpc + def create_sphere_enclosure(self, **kwargs) -> dict: # noqa: D102 + enclosure_options = kwargs["enclosure_options"] + frame = enclosure_options.frame + grpc_enclosure_options = GRPCEnclosureOptions( + create_shared_topology=enclosure_options.create_shared_topology, + subtract_bodies=enclosure_options.subtract_bodies, + frame=from_frame_to_grpc_frame(frame) if frame is not None else None, + ) + # Create the request - assumes all inputs are valid and of the proper type + + request = CreateEnclosureSphereRequest( + bodies=[Body(id=body.id) for body in kwargs["bodies"]], + radial_distance=kwargs["radial_distance"], + enclosure_options=grpc_enclosure_options, + ) + + # Call the gRPC service + response = self.stub.CreateEnclosureSphere(request) + + # Return the response - formatted as a dictionary + serialized_tracker_response = serialize_tracker_command_response( + response=response.command_response + ) + return { + "success": response.success, + "created_bodies": [body.id for body in response.created_bodies], + "tracker_response": serialized_tracker_response, + } diff --git a/src/ansys/geometry/core/_grpc/_services/v1/prepare_tools.py b/src/ansys/geometry/core/_grpc/_services/v1/prepare_tools.py index cadd8c3984..3ad0170b45 100644 --- a/src/ansys/geometry/core/_grpc/_services/v1/prepare_tools.py +++ b/src/ansys/geometry/core/_grpc/_services/v1/prepare_tools.py @@ -82,3 +82,15 @@ def remove_logo(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def detect_helixes(self, **kwargs) -> dict: # noqa: D102 raise NotImplementedError + + @protect_grpc + def create_box_enclosure(self, **kwargs) -> dict: # noqa: D102 + raise NotImplementedError + + @protect_grpc + def create_cylinder_enclosure(self, **kwargs) -> dict: # noqa: D102 + raise NotImplementedError + + @protect_grpc + def create_sphere_enclosure(self, **kwargs) -> dict: # noqa: D102 + raise NotImplementedError diff --git a/src/ansys/geometry/core/tools/prepare_tools.py b/src/ansys/geometry/core/tools/prepare_tools.py index b6723641fe..1a9a368f7c 100644 --- a/src/ansys/geometry/core/tools/prepare_tools.py +++ b/src/ansys/geometry/core/tools/prepare_tools.py @@ -26,10 +26,12 @@ from beartype import beartype as check_input_types from pint import Quantity +import ansys.geometry.core as pyansys_geom from ansys.geometry.core.connection import GrpcClient from ansys.geometry.core.connection.backend import BackendType from ansys.geometry.core.errors import GeometryRuntimeError from ansys.geometry.core.logger import LOG +from ansys.geometry.core.math.frame import Frame from ansys.geometry.core.misc.auxiliary import ( get_bodies_from_ids, get_design_from_body, @@ -49,6 +51,48 @@ from ansys.geometry.core.designer.face import Face +class EnclosureOptions: + """Provides options related to enclosure creation. + + Options allow control on how the enclosure is inserted in the design. + + Parameters + ---------- + create_shared_topology : bool + Whether shared topology should be applied after enclosure creation. + subtract_bodies : bool + Whether the specified bodies for enclosure creation should be subtracted from the enclosure. + frame : Frame + Frame used to orient the enclosure. + """ + + def __init__( + self, + create_shared_topology: bool = False, + subtract_bodies: bool = True, + frame: Frame = None, + ): + """Initialize a new instance of the enclosure options.""" + self._create_shared_topology = create_shared_topology + self._subtract_bodies = subtract_bodies + self._frame = frame + + @property + def create_shared_topology(self) -> bool: + """Whether shared topology should be applied after enclosure creation.""" + return self._create_shared_topology + + @property + def subtract_bodies(self) -> bool: + """Whether the bodies should be subtracted from the enclosure.""" + return self._subtract_bodies + + @property + def frame(self) -> Frame: + """TFrame used to orient the enclosure.""" + return self._frame + + class PrepareTools: """Prepare tools for PyAnsys Geometry. @@ -527,3 +571,202 @@ def detect_helixes( for helix in response.get("helixes") ] } + + @min_backend_version(26, 1, 0) + def create_box_enclosure( + self, + bodies: list["Body"], + x_low: Distance | Quantity | Real, + x_high: Distance | Quantity | Real, + y_low: Distance | Quantity | Real, + y_high: Distance | Quantity | Real, + z_low: Distance | Quantity | Real, + z_high: Distance | Quantity | Real, + enclosure_options: EnclosureOptions, + ) -> list["Body"]: + """Create box enclosure around the given bodies. + + Parameters + ---------- + bodies : list[Body] + List of bodies to create enclosure around. + x_low : Distance, Quantity, or Real + The lowest distance from the bodies in the x direction. + x_high : Distance, Quantity, or Real + The highest distance from the bodies in the x direction. + y_low : Distance, Quantity, or Real + The lowest distance from the bodies in the y direction. + y_high : Distance, Quantity, or Real + The highest distance from the bodies in the y direction. + z_low : Distance, Quantity, or Real + The lowest distance from the bodies in the z direction. + z_high : Distance, Quantity, or Real + The highest distance from the bodies in the z direction. + enclosure_options : EnclosureOptions + Options that define how the enclosure is included in the design. + + Returns + ------- + dict + Dictionary with key "created_bodies", + containing a list of bodies created for the enclosure. + + Warnings + -------- + This method is only available starting on Ansys release 26R1. + """ + from ansys.geometry.core.designer.body import Body + + if not bodies: + self._grpc_client.log.info("No bodies provided for enclosure...") + return [] + + # Verify inputs + check_type_all_elements_in_iterable(bodies, Body) + + parent_design = get_design_from_body(bodies[0]) + + response = self._grpc_client._services.prepare_tools.create_box_enclosure( + bodies=bodies, + x_low=x_low, + x_high=x_high, + y_low=y_low, + y_high=y_high, + z_low=z_low, + z_high=z_high, + enclosure_options=enclosure_options, + ) + + if response.get("success"): + bodies_ids = response.get("created_bodies") + if len(bodies_ids) > 0: + if not pyansys_geom.USE_TRACKER_TO_UPDATE_DESIGN: + parent_design._update_design_inplace() + else: + parent_design._update_from_tracker(response.get("tracker_response")) + return get_bodies_from_ids(parent_design, bodies_ids) + else: + self._grpc_client.log.info("Failed to create enclosure...") + return [] + + @min_backend_version(26, 1, 0) + def create_cylinder_enclosure( + self, + bodies: list["Body"], + axial_distance_low: Distance | Quantity | Real, + axial_distance_high: Distance | Quantity | Real, + radial_distance: Distance | Quantity | Real, + enclosure_options: EnclosureOptions, + ) -> list["Body"]: + """Create cylinder enclosure around the given bodies. + + Parameters + ---------- + bodies : list[Body] + List of bodies to create enclosure around. + axial_distance_low : Distance, Quantity, or Real + The lowest axial distance from the bodies. + axial_distance_high : Distance, Quantity, or Real + The highest axial distance from the bodies. + radial_distance : Distance, Quantity, or Real + The radial distance from the bodies. + enclosure_options : EnclosureOptions + Options that define how the enclosure is included in the design. + + Returns + ------- + dict + Dictionary with key "created_bodies", + containing a list of bodies created for the enclosure. + + Warnings + -------- + This method is only available starting on Ansys release 26R1. + """ + from ansys.geometry.core.designer.body import Body + + if not bodies: + self._grpc_client.log.info("No bodies provided for enclosure...") + return [] + + # Verify inputs + check_type_all_elements_in_iterable(bodies, Body) + + parent_design = get_design_from_body(bodies[0]) + + response = self._grpc_client._services.prepare_tools.create_cylinder_enclosure( + bodies=bodies, + axial_distance_low=axial_distance_low, + axial_distance_high=axial_distance_high, + radial_distance=radial_distance, + enclosure_options=enclosure_options, + ) + + if response.get("success"): + bodies_ids = response.get("created_bodies") + if len(bodies_ids) > 0: + if not pyansys_geom.USE_TRACKER_TO_UPDATE_DESIGN: + parent_design._update_design_inplace() + else: + parent_design._update_from_tracker(response.get("tracker_response")) + return get_bodies_from_ids(parent_design, bodies_ids) + else: + self._grpc_client.log.info("Failed to create enclosure...") + return [] + + @min_backend_version(26, 1, 0) + def create_sphere_enclosure( + self, + bodies: list["Body"], + radial_distance: Distance | Quantity | Real, + enclosure_options: EnclosureOptions, + ) -> list["Body"]: + """Create sphere enclosure around the given bodies. + + Parameters + ---------- + bodies : list[Body] + List of bodies to create enclosure around. + radial_distance : Distance, Quantity, or Real + The radial distance from the bodies. + enclosure_options : EnclosureOptions + Options that define how the enclosure is included in the design. + + Returns + ------- + dict + Dictionary with key "created_bodies", + containing a list of bodies created for the enclosure. + + Warnings + -------- + This method is only available starting on Ansys release 26R1. + """ + from ansys.geometry.core.designer.body import Body + + if not bodies: + self._grpc_client.log.info("No bodies provided for enclosure...") + return [] + + # Verify inputs + check_type_all_elements_in_iterable(bodies, Body) + + parent_design = get_design_from_body(bodies[0]) + + response = self._grpc_client._services.prepare_tools.create_sphere_enclosure( + bodies=bodies, + radial_distance=radial_distance, + enclosure_options=enclosure_options, + ) + + if response.get("success"): + bodies_ids = response.get("created_bodies") + if len(bodies_ids) > 0: + if not pyansys_geom.USE_TRACKER_TO_UPDATE_DESIGN: + parent_design._update_design_inplace() + else: + parent_design._update_from_tracker(response.get("tracker_response")) + return get_bodies_from_ids(parent_design, bodies_ids) + else: + self._grpc_client.log.info("Failed to create enclosure...") + return [] diff --git a/tests/integration/test_prepare_tools.py b/tests/integration/test_prepare_tools.py index d7aebe6de6..164a0843fe 100644 --- a/tests/integration/test_prepare_tools.py +++ b/tests/integration/test_prepare_tools.py @@ -21,12 +21,16 @@ # SOFTWARE. """Testing of prepare tools.""" +import numpy as np from pint import Quantity -from ansys.geometry.core.math.point import Point2D +from ansys.geometry.core.math.frame import Frame +from ansys.geometry.core.math.point import Point2D, Point3D +from ansys.geometry.core.math.vector import UnitVector3D, Vector3D from ansys.geometry.core.misc.measurements import UNITS from ansys.geometry.core.modeler import Modeler from ansys.geometry.core.sketch import Sketch +from ansys.geometry.core.tools.prepare_tools import EnclosureOptions from .conftest import FILES_DIR @@ -234,3 +238,60 @@ def test_helix_detection(modeler: Modeler): # Test with multiple bodies result = modeler.prepare_tools.detect_helixes(bodies) assert len(result["helixes"]) == 2 + + # Test with multiple bodies + result = modeler.prepare_tools.detect_helixes(bodies) + assert len(result["helixes"]) == 2 + + +def test_box_enclosure(modeler): + design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx") + bodies = [design.bodies[0]] + enclosure_options = EnclosureOptions() + modeler.prepare_tools.create_box_enclosure( + bodies, 0.005, 0.01, 0.01, 0.005, 0.10, 0.10, enclosure_options + ) + assert len(design.components) == 1 + assert len(design.components[0].bodies) == 1 + # verify that a body is created in a new component + volume_when_subtracting = design.components[0].bodies[0].volume + enclosure_options = EnclosureOptions(subtract_bodies=False) + modeler.prepare_tools.create_box_enclosure( + bodies, 0.005, 0.01, 0.01, 0.005, 0.10, 0.10, enclosure_options + ) + assert len(design.components) == 2 + assert len(design.components[1].bodies) == 1 + volume_without_subtracting = design.components[1].bodies[0].volume + # verify that the volume without subtracting is greater than the one with subtraction + assert volume_without_subtracting > volume_when_subtracting + # verify that an enclosure can be created with zero cushion + modeler.prepare_tools.create_box_enclosure( + bodies, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, enclosure_options + ) + assert len(design.components) == 3 + assert len(design.components[2].bodies) == 1 + + +def test_cylinder_enclosure(modeler): + design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx") + bodies = [design.bodies[0]] + origin = Vector3D([0.0, 0.0, 0.0]) + direction_x = UnitVector3D([0, 1, 0]) + direction_y = UnitVector3D([0, 0, 1]) + frame = Frame(origin, direction_x, direction_y) + enclosure_options = EnclosureOptions(frame=frame) + modeler.prepare_tools.create_cylinder_enclosure(bodies, 0.1, 0.1, 0.1, enclosure_options) + assert len(design.components) == 1 + assert len(design.components[0].bodies) == 1 + bounding_box = design.components[0].bodies[0].bounding_box + # check that the cylinder has been placed in the appropriate position based upon the frame + assert np.allclose(bounding_box.center, Point3D([0.0, 0.0, 0.01])) + + +def test_sphere_enclosure(modeler): + design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx") + bodies = [design.bodies[0]] + enclosure_options = EnclosureOptions() + modeler.prepare_tools.create_sphere_enclosure(bodies, 0.1, enclosure_options) + assert len(design.components) == 1 + assert len(design.components[0].bodies) == 1 From d73f2e4bcff691b0d41a0b0b82ab03b0d227c760 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 18 Nov 2025 19:36:28 +0000 Subject: [PATCH 03/20] chore: auto fixes from pre-commit hooks --- .../geometry/core/_grpc/_services/v0/prepare_tools.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py index d482746901..09a7f6287c 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py @@ -21,18 +21,16 @@ # SOFTWARE. """Module containing the Prepare Tools service implementation for v0.""" -import grpc - +from ansys.api.geometry.v0.models_pb2 import Body from ansys.api.geometry.v0.preparetools_pb2 import ( CreateEnclosureBoxRequest, CreateEnclosureCylinderRequest, CreateEnclosureSphereRequest, + EnclosureOptions as GRPCEnclosureOptions, ) -from ansys.api.geometry.v0.models_pb2 import Body -from ansys.api.geometry.v0.preparetools_pb2 import EnclosureOptions as GRPCEnclosureOptions +import grpc from ansys.geometry.core.errors import protect_grpc -from ansys.geometry.core.tools.prepare_tools import EnclosureOptions from ..base.conversions import from_measurement_to_server_length from ..base.prepare_tools import GRPCPrepareToolsService @@ -385,7 +383,7 @@ def create_sphere_enclosure(self, **kwargs) -> dict: # noqa: D102 bodies=[Body(id=body.id) for body in kwargs["bodies"]], radial_distance=kwargs["radial_distance"], enclosure_options=grpc_enclosure_options, - ) + ) # Call the gRPC service response = self.stub.CreateEnclosureSphere(request) From 50274abd4054c85c49067aac048e14dc84adda01 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Tue, 18 Nov 2025 19:37:30 +0000 Subject: [PATCH 04/20] chore: adding changelog file 2383.added.md [dependabot-skip] --- doc/changelog.d/2383.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/2383.added.md diff --git a/doc/changelog.d/2383.added.md b/doc/changelog.d/2383.added.md new file mode 100644 index 0000000000..c13400b524 --- /dev/null +++ b/doc/changelog.d/2383.added.md @@ -0,0 +1 @@ +Expose enclosure methods From 1b3aa8b0e31f238e104334eaa3c95e8c5e3d77af Mon Sep 17 00:00:00 2001 From: smereu Date: Tue, 18 Nov 2025 16:31:54 -0600 Subject: [PATCH 05/20] fix use of distance + misc. fixes Fix use of distance and other misc. changes in response to code review --- .../_grpc/_services/base/prepare_tools.py | 1 + .../core/_grpc/_services/v0/prepare_tools.py | 23 ++++--- .../geometry/core/tools/prepare_tools.py | 66 +++++++++---------- 3 files changed, 44 insertions(+), 46 deletions(-) diff --git a/src/ansys/geometry/core/_grpc/_services/base/prepare_tools.py b/src/ansys/geometry/core/_grpc/_services/base/prepare_tools.py index 97bbc04485..da1b5fdfb7 100644 --- a/src/ansys/geometry/core/_grpc/_services/base/prepare_tools.py +++ b/src/ansys/geometry/core/_grpc/_services/base/prepare_tools.py @@ -97,3 +97,4 @@ def create_cylinder_enclosure(self, **kwargs) -> dict: @abstractmethod def create_sphere_enclosure(self, **kwargs) -> dict: """Create a sphere enclosure around bodies.""" + pass diff --git a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py index d482746901..6f61213cdf 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py @@ -313,16 +313,17 @@ def create_box_enclosure(self, **kwargs) -> dict: # noqa: D102 create_shared_topology=enclosure_options.create_shared_topology, subtract_bodies=enclosure_options.subtract_bodies, frame=from_frame_to_grpc_frame(frame) if frame is not None else None, + cushion_proportion=enclosure_options.cushion_proportion, ) # Create the request - assumes all inputs are valid and of the proper type request = CreateEnclosureBoxRequest( bodies=[Body(id=body.id) for body in kwargs["bodies"]], - x_low=kwargs["x_low"], - x_high=kwargs["x_high"], - y_low=kwargs["y_low"], - y_high=kwargs["y_high"], - z_low=kwargs["z_low"], - z_high=kwargs["z_high"], + x_low=from_measurement_to_server_length(kwargs["x_low"]), + x_high=from_measurement_to_server_length(kwargs["x_high"]), + y_low=from_measurement_to_server_length(kwargs["y_low"]), + y_high=from_measurement_to_server_length(kwargs["y_high"]), + z_low=from_measurement_to_server_length(kwargs["z_low"]), + z_high=from_measurement_to_server_length(kwargs["z_high"]), enclosure_options=grpc_enclosure_options, ) @@ -347,13 +348,14 @@ def create_cylinder_enclosure(self, **kwargs) -> dict: # noqa: D102 create_shared_topology=enclosure_options.create_shared_topology, subtract_bodies=enclosure_options.subtract_bodies, frame=from_frame_to_grpc_frame(frame) if frame is not None else None, + cushion_proportion=enclosure_options.cushion_proportion, ) # Create the request - assumes all inputs are valid and of the proper type request = CreateEnclosureCylinderRequest( bodies=[Body(id=body.id) for body in kwargs["bodies"]], - axial_distance_low=kwargs["axial_distance_low"], - axial_distance_high=kwargs["axial_distance_high"], - radial_distance=kwargs["radial_distance"], + axial_distance_low=from_measurement_to_server_length(kwargs["axial_distance_low"]), + axial_distance_high=from_measurement_to_server_length(kwargs["axial_distance_high"]), + radial_distance=from_measurement_to_server_length(kwargs["radial_distance"]), enclosure_options=grpc_enclosure_options, ) @@ -378,12 +380,13 @@ def create_sphere_enclosure(self, **kwargs) -> dict: # noqa: D102 create_shared_topology=enclosure_options.create_shared_topology, subtract_bodies=enclosure_options.subtract_bodies, frame=from_frame_to_grpc_frame(frame) if frame is not None else None, + cushion_proportion=enclosure_options.cushion_proportion, ) # Create the request - assumes all inputs are valid and of the proper type request = CreateEnclosureSphereRequest( bodies=[Body(id=body.id) for body in kwargs["bodies"]], - radial_distance=kwargs["radial_distance"], + radial_distance=from_measurement_to_server_length(kwargs["radial_distance"]), enclosure_options=grpc_enclosure_options, ) diff --git a/src/ansys/geometry/core/tools/prepare_tools.py b/src/ansys/geometry/core/tools/prepare_tools.py index 1a9a368f7c..31553a2ada 100644 --- a/src/ansys/geometry/core/tools/prepare_tools.py +++ b/src/ansys/geometry/core/tools/prepare_tools.py @@ -23,10 +23,10 @@ from typing import TYPE_CHECKING +from dataclasses import dataclass from beartype import beartype as check_input_types from pint import Quantity -import ansys.geometry.core as pyansys_geom from ansys.geometry.core.connection import GrpcClient from ansys.geometry.core.connection.backend import BackendType from ansys.geometry.core.errors import GeometryRuntimeError @@ -44,6 +44,7 @@ from ansys.geometry.core.tools.problem_areas import LogoProblemArea from ansys.geometry.core.tools.repair_tool_message import RepairToolMessage from ansys.geometry.core.typing import Real +import ansys.geometry.core as pyansys_geom if TYPE_CHECKING: # pragma: no cover from ansys.geometry.core.designer.body import Body @@ -51,6 +52,7 @@ from ansys.geometry.core.designer.face import Face +@dataclass class EnclosureOptions: """Provides options related to enclosure creation. @@ -64,34 +66,16 @@ class EnclosureOptions: Whether the specified bodies for enclosure creation should be subtracted from the enclosure. frame : Frame Frame used to orient the enclosure. + cushion_proportion : Real + A percentage of the minimum enclosure size. + Determines the initial distance between the enclosed objects + and the closest point of the enclosure to the objects. """ - def __init__( - self, - create_shared_topology: bool = False, - subtract_bodies: bool = True, - frame: Frame = None, - ): - """Initialize a new instance of the enclosure options.""" - self._create_shared_topology = create_shared_topology - self._subtract_bodies = subtract_bodies - self._frame = frame - - @property - def create_shared_topology(self) -> bool: - """Whether shared topology should be applied after enclosure creation.""" - return self._create_shared_topology - - @property - def subtract_bodies(self) -> bool: - """Whether the bodies should be subtracted from the enclosure.""" - return self._subtract_bodies - - @property - def frame(self) -> Frame: - """TFrame used to orient the enclosure.""" - return self._frame - + create_shared_topology: bool = False + subtract_bodies: bool = True + frame: Frame = None + cushion_proportion: Real = 0.25 class PrepareTools: """Prepare tools for PyAnsys Geometry. @@ -607,9 +591,8 @@ def create_box_enclosure( Returns ------- - dict - Dictionary with key "created_bodies", - containing a list of bodies created for the enclosure. + list[Body] + List of created bodies. Warnings -------- @@ -624,6 +607,13 @@ def create_box_enclosure( # Verify inputs check_type_all_elements_in_iterable(bodies, Body) + x_low = x_low if isinstance(x_low, Distance) else Distance(x_low) + x_high = x_high if isinstance(x_high, Distance) else Distance(x_high) + y_low = x_low if isinstance(y_low, Distance) else Distance(y_low) + y_high = y_high if isinstance(y_high, Distance) else Distance(y_high) + z_low = z_low if isinstance(z_low, Distance) else Distance(z_low) + z_high = z_high if isinstance(z_high, Distance) else Distance(z_high) + parent_design = get_design_from_body(bodies[0]) response = self._grpc_client._services.prepare_tools.create_box_enclosure( @@ -675,9 +665,8 @@ def create_cylinder_enclosure( Returns ------- - dict - Dictionary with key "created_bodies", - containing a list of bodies created for the enclosure. + list[Body] + List of created bodies. Warnings -------- @@ -692,6 +681,10 @@ def create_cylinder_enclosure( # Verify inputs check_type_all_elements_in_iterable(bodies, Body) + axial_distance_low = axial_distance_low if isinstance(axial_distance_low, Distance) else Distance(axial_distance_low) + axial_distance_high = axial_distance_high if isinstance(axial_distance_high, Distance) else Distance(axial_distance_high) + radial_distance = axial_distance_low if isinstance(radial_distance, Distance) else Distance(radial_distance) + parent_design = get_design_from_body(bodies[0]) response = self._grpc_client._services.prepare_tools.create_cylinder_enclosure( @@ -734,9 +727,8 @@ def create_sphere_enclosure( Returns ------- - dict - Dictionary with key "created_bodies", - containing a list of bodies created for the enclosure. + list[Body] + List of created bodies. Warnings -------- @@ -753,6 +745,8 @@ def create_sphere_enclosure( parent_design = get_design_from_body(bodies[0]) + radial_distance = radial_distance if isinstance(radial_distance, Distance) else Distance(radial_distance) + response = self._grpc_client._services.prepare_tools.create_sphere_enclosure( bodies=bodies, radial_distance=radial_distance, From 78131d442b75dcfc4ad1a149c0c38352fd722217 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 13:47:27 +0000 Subject: [PATCH 06/20] chore: auto fixes from pre-commit hooks --- .../geometry/core/tools/prepare_tools.py | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/ansys/geometry/core/tools/prepare_tools.py b/src/ansys/geometry/core/tools/prepare_tools.py index 31553a2ada..1982ebffae 100644 --- a/src/ansys/geometry/core/tools/prepare_tools.py +++ b/src/ansys/geometry/core/tools/prepare_tools.py @@ -21,12 +21,13 @@ # SOFTWARE. """Provides tools for preparing geometry for use with simulation.""" +from dataclasses import dataclass from typing import TYPE_CHECKING -from dataclasses import dataclass from beartype import beartype as check_input_types from pint import Quantity +import ansys.geometry.core as pyansys_geom from ansys.geometry.core.connection import GrpcClient from ansys.geometry.core.connection.backend import BackendType from ansys.geometry.core.errors import GeometryRuntimeError @@ -44,7 +45,6 @@ from ansys.geometry.core.tools.problem_areas import LogoProblemArea from ansys.geometry.core.tools.repair_tool_message import RepairToolMessage from ansys.geometry.core.typing import Real -import ansys.geometry.core as pyansys_geom if TYPE_CHECKING: # pragma: no cover from ansys.geometry.core.designer.body import Body @@ -77,6 +77,7 @@ class EnclosureOptions: frame: Frame = None cushion_proportion: Real = 0.25 + class PrepareTools: """Prepare tools for PyAnsys Geometry. @@ -681,9 +682,21 @@ def create_cylinder_enclosure( # Verify inputs check_type_all_elements_in_iterable(bodies, Body) - axial_distance_low = axial_distance_low if isinstance(axial_distance_low, Distance) else Distance(axial_distance_low) - axial_distance_high = axial_distance_high if isinstance(axial_distance_high, Distance) else Distance(axial_distance_high) - radial_distance = axial_distance_low if isinstance(radial_distance, Distance) else Distance(radial_distance) + axial_distance_low = ( + axial_distance_low + if isinstance(axial_distance_low, Distance) + else Distance(axial_distance_low) + ) + axial_distance_high = ( + axial_distance_high + if isinstance(axial_distance_high, Distance) + else Distance(axial_distance_high) + ) + radial_distance = ( + axial_distance_low + if isinstance(radial_distance, Distance) + else Distance(radial_distance) + ) parent_design = get_design_from_body(bodies[0]) @@ -745,7 +758,9 @@ def create_sphere_enclosure( parent_design = get_design_from_body(bodies[0]) - radial_distance = radial_distance if isinstance(radial_distance, Distance) else Distance(radial_distance) + radial_distance = ( + radial_distance if isinstance(radial_distance, Distance) else Distance(radial_distance) + ) response = self._grpc_client._services.prepare_tools.create_sphere_enclosure( bodies=bodies, From 26685e612140e8043eb6b8f24a551b79eca96fee Mon Sep 17 00:00:00 2001 From: smereu Date: Wed, 19 Nov 2025 07:51:56 -0600 Subject: [PATCH 07/20] Update prepare_tools.py clean-up import statements --- src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py index ebe1c7789e..d2576ba067 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py @@ -23,9 +23,6 @@ from ansys.api.geometry.v0.models_pb2 import Body from ansys.api.geometry.v0.preparetools_pb2 import ( - CreateEnclosureBoxRequest, - CreateEnclosureCylinderRequest, - CreateEnclosureSphereRequest, EnclosureOptions as GRPCEnclosureOptions, ) import grpc @@ -305,6 +302,7 @@ def detect_helixes(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_box_enclosure(self, **kwargs) -> dict: # noqa: D102 + from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureBoxRequest enclosure_options = kwargs["enclosure_options"] frame = enclosure_options.frame grpc_enclosure_options = GRPCEnclosureOptions( @@ -340,6 +338,7 @@ def create_box_enclosure(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_cylinder_enclosure(self, **kwargs) -> dict: # noqa: D102 + from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureCylinderRequest enclosure_options = kwargs["enclosure_options"] frame = enclosure_options.frame grpc_enclosure_options = GRPCEnclosureOptions( @@ -372,6 +371,7 @@ def create_cylinder_enclosure(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_sphere_enclosure(self, **kwargs) -> dict: # noqa: D102 + from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureSphereRequest enclosure_options = kwargs["enclosure_options"] frame = enclosure_options.frame grpc_enclosure_options = GRPCEnclosureOptions( From 3a197f26b84f117e54d6cdeafec7cdd203c88bf3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 13:52:31 +0000 Subject: [PATCH 08/20] chore: auto fixes from pre-commit hooks --- src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py index d2576ba067..a4617ef06e 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py @@ -303,6 +303,7 @@ def detect_helixes(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_box_enclosure(self, **kwargs) -> dict: # noqa: D102 from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureBoxRequest + enclosure_options = kwargs["enclosure_options"] frame = enclosure_options.frame grpc_enclosure_options = GRPCEnclosureOptions( @@ -339,6 +340,7 @@ def create_box_enclosure(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_cylinder_enclosure(self, **kwargs) -> dict: # noqa: D102 from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureCylinderRequest + enclosure_options = kwargs["enclosure_options"] frame = enclosure_options.frame grpc_enclosure_options = GRPCEnclosureOptions( @@ -372,6 +374,7 @@ def create_cylinder_enclosure(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_sphere_enclosure(self, **kwargs) -> dict: # noqa: D102 from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureSphereRequest + enclosure_options = kwargs["enclosure_options"] frame = enclosure_options.frame grpc_enclosure_options = GRPCEnclosureOptions( From b2e516bf48e4c477079472e286b816493a8f8cf8 Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Wed, 19 Nov 2025 14:59:49 +0100 Subject: [PATCH 09/20] Delete doc/changelog.d/1753.maintenance.md --- doc/changelog.d/1753.maintenance.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 doc/changelog.d/1753.maintenance.md diff --git a/doc/changelog.d/1753.maintenance.md b/doc/changelog.d/1753.maintenance.md deleted file mode 100644 index 97e5671828..0000000000 --- a/doc/changelog.d/1753.maintenance.md +++ /dev/null @@ -1 +0,0 @@ -update CHANGELOG for v0.9.0 \ No newline at end of file From e56f6f7c6c24a6675f64cfcef8539cd86ad88ff7 Mon Sep 17 00:00:00 2001 From: smereu <39596710+smereu@users.noreply.github.com> Date: Wed, 19 Nov 2025 10:21:43 -0600 Subject: [PATCH 10/20] Update src/ansys/geometry/core/tools/prepare_tools.py Co-authored-by: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> --- src/ansys/geometry/core/tools/prepare_tools.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/geometry/core/tools/prepare_tools.py b/src/ansys/geometry/core/tools/prepare_tools.py index 1982ebffae..8d1dcbab0f 100644 --- a/src/ansys/geometry/core/tools/prepare_tools.py +++ b/src/ansys/geometry/core/tools/prepare_tools.py @@ -67,9 +67,9 @@ class EnclosureOptions: frame : Frame Frame used to orient the enclosure. cushion_proportion : Real - A percentage of the minimum enclosure size. - Determines the initial distance between the enclosed objects - and the closest point of the enclosure to the objects. + A percentage of the minimum enclosure size. + Determines the initial distance between the enclosed objects + and the closest point of the enclosure to the objects. """ create_shared_topology: bool = False From d84cbabf320ada03a93a17f1fd2f39e2a2ce8c95 Mon Sep 17 00:00:00 2001 From: smereu <39596710+smereu@users.noreply.github.com> Date: Wed, 19 Nov 2025 10:21:58 -0600 Subject: [PATCH 11/20] Update src/ansys/geometry/core/tools/prepare_tools.py Co-authored-by: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> --- src/ansys/geometry/core/tools/prepare_tools.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ansys/geometry/core/tools/prepare_tools.py b/src/ansys/geometry/core/tools/prepare_tools.py index 8d1dcbab0f..ef73be815d 100644 --- a/src/ansys/geometry/core/tools/prepare_tools.py +++ b/src/ansys/geometry/core/tools/prepare_tools.py @@ -575,17 +575,17 @@ def create_box_enclosure( ---------- bodies : list[Body] List of bodies to create enclosure around. - x_low : Distance, Quantity, or Real + x_low : Distance | Quantity | Real The lowest distance from the bodies in the x direction. - x_high : Distance, Quantity, or Real + x_high : Distance | Quantity | Real The highest distance from the bodies in the x direction. - y_low : Distance, Quantity, or Real + y_low : Distance | Quantity | Real The lowest distance from the bodies in the y direction. - y_high : Distance, Quantity, or Real + y_high : Distance | Quantity | Real The highest distance from the bodies in the y direction. - z_low : Distance, Quantity, or Real + z_low : Distance | Quantity | Real The lowest distance from the bodies in the z direction. - z_high : Distance, Quantity, or Real + z_high : Distance | Quantity | Real The highest distance from the bodies in the z direction. enclosure_options : EnclosureOptions Options that define how the enclosure is included in the design. From 16fb69ed4c60f2ad008f6eb1cb52475b8eb9802b Mon Sep 17 00:00:00 2001 From: smereu <39596710+smereu@users.noreply.github.com> Date: Wed, 19 Nov 2025 10:22:47 -0600 Subject: [PATCH 12/20] Update src/ansys/geometry/core/tools/prepare_tools.py Co-authored-by: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> --- src/ansys/geometry/core/tools/prepare_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/tools/prepare_tools.py b/src/ansys/geometry/core/tools/prepare_tools.py index ef73be815d..959fe30923 100644 --- a/src/ansys/geometry/core/tools/prepare_tools.py +++ b/src/ansys/geometry/core/tools/prepare_tools.py @@ -733,7 +733,7 @@ def create_sphere_enclosure( ---------- bodies : list[Body] List of bodies to create enclosure around. - radial_distance : Distance, Quantity, or Real + radial_distance : Distance | Quantity | Real The radial distance from the bodies. enclosure_options : EnclosureOptions Options that define how the enclosure is included in the design. From aae9c92eb54cf45c3971ba9172ccbb9773c2b7b8 Mon Sep 17 00:00:00 2001 From: smereu <39596710+smereu@users.noreply.github.com> Date: Wed, 19 Nov 2025 10:23:03 -0600 Subject: [PATCH 13/20] Update src/ansys/geometry/core/tools/prepare_tools.py Co-authored-by: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> --- src/ansys/geometry/core/tools/prepare_tools.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/geometry/core/tools/prepare_tools.py b/src/ansys/geometry/core/tools/prepare_tools.py index 959fe30923..b5f8050f72 100644 --- a/src/ansys/geometry/core/tools/prepare_tools.py +++ b/src/ansys/geometry/core/tools/prepare_tools.py @@ -655,11 +655,11 @@ def create_cylinder_enclosure( ---------- bodies : list[Body] List of bodies to create enclosure around. - axial_distance_low : Distance, Quantity, or Real + axial_distance_low : Distance | Quantity | Real The lowest axial distance from the bodies. - axial_distance_high : Distance, Quantity, or Real + axial_distance_high : Distance | Quantity | Real The highest axial distance from the bodies. - radial_distance : Distance, Quantity, or Real + radial_distance : Distance | Quantity | Real The radial distance from the bodies. enclosure_options : EnclosureOptions Options that define how the enclosure is included in the design. From e0bc94b3d05721d5a669dc9e887a439702604495 Mon Sep 17 00:00:00 2001 From: smereu Date: Wed, 19 Nov 2025 11:47:00 -0600 Subject: [PATCH 14/20] add conversion method + misc. clean-up --- .../core/_grpc/_services/v0/conversions.py | 27 ++++++++++- .../core/_grpc/_services/v0/prepare_tools.py | 46 ++++++------------- tests/integration/test_prepare_tools.py | 3 ++ 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/ansys/geometry/core/_grpc/_services/v0/conversions.py b/src/ansys/geometry/core/_grpc/_services/v0/conversions.py index 2d7f8fd82c..98a97da8da 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/conversions.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/conversions.py @@ -29,6 +29,9 @@ EntityIdentifier, PartExportFormat as GRPCPartExportFormat, ) +from ansys.api.geometry.v0.preparetools_pb2 import ( + EnclosureOptions as GRPCEnclosureOptions + ) from ansys.api.dbu.v0.drivingdimensions_pb2 import UpdateStatus as GRPCUpdateStatus from ansys.api.geometry.v0.models_pb2 import ( Arc as GRPCArc, @@ -81,6 +84,7 @@ Parameter, ParameterUpdateStatus, ) + from ansys.geometry.core.tools.prepare_tools import EnclosureOptions from ansys.geometry.core.shapes.curves.curve import Curve from ansys.geometry.core.shapes.curves.line import Line from ansys.geometry.core.shapes.curves.nurbs import NURBSCurve @@ -96,7 +100,6 @@ from ansys.geometry.core.sketch.polygon import Polygon from ansys.geometry.core.sketch.segment import SketchSegment - def from_point3d_to_grpc_point(point: "Point3D") -> GRPCPoint: """Convert a ``Point3D`` class to a point gRPC message. @@ -1410,3 +1413,25 @@ def serialize_entity_identifier(entity): for entity in getattr(response, "deleted_bodies", []) ], } + +def from_enclosure_options_to_grpc_enclosure_options(enclosure_options: "EnclosureOptions") -> GRPCEnclosureOptions: + """Convert enclosure_options to grpc definition. + + Parameters + ---------- + enclosure_options : EnclosureOptions + Definition of the enclosure options. + + Returns + ------- + GRPCEnclosureOptions + Grpc converted definition. + """ + + frame = enclosure_options.frame + return GRPCEnclosureOptions( + create_shared_topology=enclosure_options.create_shared_topology, + subtract_bodies=enclosure_options.subtract_bodies, + frame=from_frame_to_grpc_frame(frame) if frame is not None else None, + cushion_proportion=enclosure_options.cushion_proportion, + ) diff --git a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py index d2576ba067..9920160590 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py @@ -21,17 +21,13 @@ # SOFTWARE. """Module containing the Prepare Tools service implementation for v0.""" -from ansys.api.geometry.v0.models_pb2 import Body -from ansys.api.geometry.v0.preparetools_pb2 import ( - EnclosureOptions as GRPCEnclosureOptions, -) import grpc from ansys.geometry.core.errors import protect_grpc from ..base.conversions import from_measurement_to_server_length from ..base.prepare_tools import GRPCPrepareToolsService -from .conversions import build_grpc_id, from_frame_to_grpc_frame, serialize_tracker_command_response +from .conversions import build_grpc_id, from_enclosure_options_to_grpc_enclosure_options, from_frame_to_grpc_frame, serialize_tracker_command_response class GRPCPrepareToolsServiceV0(GRPCPrepareToolsService): @@ -303,17 +299,12 @@ def detect_helixes(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_box_enclosure(self, **kwargs) -> dict: # noqa: D102 from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureBoxRequest - enclosure_options = kwargs["enclosure_options"] - frame = enclosure_options.frame - grpc_enclosure_options = GRPCEnclosureOptions( - create_shared_topology=enclosure_options.create_shared_topology, - subtract_bodies=enclosure_options.subtract_bodies, - frame=from_frame_to_grpc_frame(frame) if frame is not None else None, - cushion_proportion=enclosure_options.cushion_proportion, - ) + from ansys.api.geometry.v0.models_pb2 import Body as GRPCBody + grpc_enclosure_options = from_enclosure_options_to_grpc_enclosure_options(kwargs["enclosure_options"]) + # Create the request - assumes all inputs are valid and of the proper type request = CreateEnclosureBoxRequest( - bodies=[Body(id=body.id) for body in kwargs["bodies"]], + bodies=[GRPCBody(id=body.id) for body in kwargs["bodies"]], x_low=from_measurement_to_server_length(kwargs["x_low"]), x_high=from_measurement_to_server_length(kwargs["x_high"]), y_low=from_measurement_to_server_length(kwargs["y_low"]), @@ -339,17 +330,12 @@ def create_box_enclosure(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_cylinder_enclosure(self, **kwargs) -> dict: # noqa: D102 from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureCylinderRequest - enclosure_options = kwargs["enclosure_options"] - frame = enclosure_options.frame - grpc_enclosure_options = GRPCEnclosureOptions( - create_shared_topology=enclosure_options.create_shared_topology, - subtract_bodies=enclosure_options.subtract_bodies, - frame=from_frame_to_grpc_frame(frame) if frame is not None else None, - cushion_proportion=enclosure_options.cushion_proportion, - ) + from ansys.api.geometry.v0.models_pb2 import Body as GRPCBody + grpc_enclosure_options = from_enclosure_options_to_grpc_enclosure_options(kwargs["enclosure_options"]) + # Create the request - assumes all inputs are valid and of the proper type request = CreateEnclosureCylinderRequest( - bodies=[Body(id=body.id) for body in kwargs["bodies"]], + bodies=[GRPCBody(id=body.id) for body in kwargs["bodies"]], axial_distance_low=from_measurement_to_server_length(kwargs["axial_distance_low"]), axial_distance_high=from_measurement_to_server_length(kwargs["axial_distance_high"]), radial_distance=from_measurement_to_server_length(kwargs["radial_distance"]), @@ -372,18 +358,14 @@ def create_cylinder_enclosure(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_sphere_enclosure(self, **kwargs) -> dict: # noqa: D102 from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureSphereRequest - enclosure_options = kwargs["enclosure_options"] - frame = enclosure_options.frame - grpc_enclosure_options = GRPCEnclosureOptions( - create_shared_topology=enclosure_options.create_shared_topology, - subtract_bodies=enclosure_options.subtract_bodies, - frame=from_frame_to_grpc_frame(frame) if frame is not None else None, - cushion_proportion=enclosure_options.cushion_proportion, - ) + from ansys.api.geometry.v0.models_pb2 import Body as GRPCBody + + grpc_enclosure_options = from_enclosure_options_to_grpc_enclosure_options(kwargs["enclosure_options"]) + # Create the request - assumes all inputs are valid and of the proper type request = CreateEnclosureSphereRequest( - bodies=[Body(id=body.id) for body in kwargs["bodies"]], + bodies=[GRPCBody(id=body.id) for body in kwargs["bodies"]], radial_distance=from_measurement_to_server_length(kwargs["radial_distance"]), enclosure_options=grpc_enclosure_options, ) diff --git a/tests/integration/test_prepare_tools.py b/tests/integration/test_prepare_tools.py index 164a0843fe..c719f61e9d 100644 --- a/tests/integration/test_prepare_tools.py +++ b/tests/integration/test_prepare_tools.py @@ -245,6 +245,7 @@ def test_helix_detection(modeler: Modeler): def test_box_enclosure(modeler): + """Tests creation of a box enclosure. """ design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx") bodies = [design.bodies[0]] enclosure_options = EnclosureOptions() @@ -273,6 +274,7 @@ def test_box_enclosure(modeler): def test_cylinder_enclosure(modeler): + """Tests creation of a cylinder enclosure. """ design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx") bodies = [design.bodies[0]] origin = Vector3D([0.0, 0.0, 0.0]) @@ -289,6 +291,7 @@ def test_cylinder_enclosure(modeler): def test_sphere_enclosure(modeler): + """Tests creation of a sphere enclosure. """ design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx") bodies = [design.bodies[0]] enclosure_options = EnclosureOptions() From 0b86c1dfcdd1b4df03dd7e621fe7a704a33b93a2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 17:49:18 +0000 Subject: [PATCH 15/20] chore: auto fixes from pre-commit hooks --- .../core/_grpc/_services/v0/conversions.py | 25 +++++++------- .../core/_grpc/_services/v0/prepare_tools.py | 33 +++++++++++++------ tests/integration/test_prepare_tools.py | 6 ++-- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/ansys/geometry/core/_grpc/_services/v0/conversions.py b/src/ansys/geometry/core/_grpc/_services/v0/conversions.py index 98a97da8da..601f564696 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/conversions.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/conversions.py @@ -29,9 +29,6 @@ EntityIdentifier, PartExportFormat as GRPCPartExportFormat, ) -from ansys.api.geometry.v0.preparetools_pb2 import ( - EnclosureOptions as GRPCEnclosureOptions - ) from ansys.api.dbu.v0.drivingdimensions_pb2 import UpdateStatus as GRPCUpdateStatus from ansys.api.geometry.v0.models_pb2 import ( Arc as GRPCArc, @@ -59,6 +56,7 @@ TrimmedCurve as GRPCTrimmedCurve, TrimmedSurface as GRPCTrimmedSurface, ) +from ansys.api.geometry.v0.preparetools_pb2 import EnclosureOptions as GRPCEnclosureOptions import pint from ansys.geometry.core.errors import GeometryRuntimeError @@ -84,7 +82,6 @@ Parameter, ParameterUpdateStatus, ) - from ansys.geometry.core.tools.prepare_tools import EnclosureOptions from ansys.geometry.core.shapes.curves.curve import Curve from ansys.geometry.core.shapes.curves.line import Line from ansys.geometry.core.shapes.curves.nurbs import NURBSCurve @@ -99,6 +96,8 @@ from ansys.geometry.core.sketch.nurbs import SketchNurbs from ansys.geometry.core.sketch.polygon import Polygon from ansys.geometry.core.sketch.segment import SketchSegment + from ansys.geometry.core.tools.prepare_tools import EnclosureOptions + def from_point3d_to_grpc_point(point: "Point3D") -> GRPCPoint: """Convert a ``Point3D`` class to a point gRPC message. @@ -1414,7 +1413,10 @@ def serialize_entity_identifier(entity): ], } -def from_enclosure_options_to_grpc_enclosure_options(enclosure_options: "EnclosureOptions") -> GRPCEnclosureOptions: + +def from_enclosure_options_to_grpc_enclosure_options( + enclosure_options: "EnclosureOptions", +) -> GRPCEnclosureOptions: """Convert enclosure_options to grpc definition. Parameters @@ -1427,11 +1429,10 @@ def from_enclosure_options_to_grpc_enclosure_options(enclosure_options: "Enclosu GRPCEnclosureOptions Grpc converted definition. """ - frame = enclosure_options.frame - return GRPCEnclosureOptions( - create_shared_topology=enclosure_options.create_shared_topology, - subtract_bodies=enclosure_options.subtract_bodies, - frame=from_frame_to_grpc_frame(frame) if frame is not None else None, - cushion_proportion=enclosure_options.cushion_proportion, - ) + return GRPCEnclosureOptions( + create_shared_topology=enclosure_options.create_shared_topology, + subtract_bodies=enclosure_options.subtract_bodies, + frame=from_frame_to_grpc_frame(frame) if frame is not None else None, + cushion_proportion=enclosure_options.cushion_proportion, + ) diff --git a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py index f61b28dddd..38435f85b5 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py @@ -27,7 +27,11 @@ from ..base.conversions import from_measurement_to_server_length from ..base.prepare_tools import GRPCPrepareToolsService -from .conversions import build_grpc_id, from_enclosure_options_to_grpc_enclosure_options, from_frame_to_grpc_frame, serialize_tracker_command_response +from .conversions import ( + build_grpc_id, + from_enclosure_options_to_grpc_enclosure_options, + serialize_tracker_command_response, +) class GRPCPrepareToolsServiceV0(GRPCPrepareToolsService): @@ -298,10 +302,13 @@ def detect_helixes(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_box_enclosure(self, **kwargs) -> dict: # noqa: D102 - from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureBoxRequest from ansys.api.geometry.v0.models_pb2 import Body as GRPCBody - grpc_enclosure_options = from_enclosure_options_to_grpc_enclosure_options(kwargs["enclosure_options"]) - + from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureBoxRequest + + grpc_enclosure_options = from_enclosure_options_to_grpc_enclosure_options( + kwargs["enclosure_options"] + ) + # Create the request - assumes all inputs are valid and of the proper type request = CreateEnclosureBoxRequest( bodies=[GRPCBody(id=body.id) for body in kwargs["bodies"]], @@ -329,10 +336,13 @@ def create_box_enclosure(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_cylinder_enclosure(self, **kwargs) -> dict: # noqa: D102 - from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureCylinderRequest from ansys.api.geometry.v0.models_pb2 import Body as GRPCBody - grpc_enclosure_options = from_enclosure_options_to_grpc_enclosure_options(kwargs["enclosure_options"]) - + from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureCylinderRequest + + grpc_enclosure_options = from_enclosure_options_to_grpc_enclosure_options( + kwargs["enclosure_options"] + ) + # Create the request - assumes all inputs are valid and of the proper type request = CreateEnclosureCylinderRequest( bodies=[GRPCBody(id=body.id) for body in kwargs["bodies"]], @@ -357,10 +367,13 @@ def create_cylinder_enclosure(self, **kwargs) -> dict: # noqa: D102 @protect_grpc def create_sphere_enclosure(self, **kwargs) -> dict: # noqa: D102 - from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureSphereRequest from ansys.api.geometry.v0.models_pb2 import Body as GRPCBody - grpc_enclosure_options = from_enclosure_options_to_grpc_enclosure_options(kwargs["enclosure_options"]) - + from ansys.api.geometry.v0.preparetools_pb2 import CreateEnclosureSphereRequest + + grpc_enclosure_options = from_enclosure_options_to_grpc_enclosure_options( + kwargs["enclosure_options"] + ) + # Create the request - assumes all inputs are valid and of the proper type request = CreateEnclosureSphereRequest( bodies=[GRPCBody(id=body.id) for body in kwargs["bodies"]], diff --git a/tests/integration/test_prepare_tools.py b/tests/integration/test_prepare_tools.py index c719f61e9d..740ee455e0 100644 --- a/tests/integration/test_prepare_tools.py +++ b/tests/integration/test_prepare_tools.py @@ -245,7 +245,7 @@ def test_helix_detection(modeler: Modeler): def test_box_enclosure(modeler): - """Tests creation of a box enclosure. """ + """Tests creation of a box enclosure.""" design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx") bodies = [design.bodies[0]] enclosure_options = EnclosureOptions() @@ -274,7 +274,7 @@ def test_box_enclosure(modeler): def test_cylinder_enclosure(modeler): - """Tests creation of a cylinder enclosure. """ + """Tests creation of a cylinder enclosure.""" design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx") bodies = [design.bodies[0]] origin = Vector3D([0.0, 0.0, 0.0]) @@ -291,7 +291,7 @@ def test_cylinder_enclosure(modeler): def test_sphere_enclosure(modeler): - """Tests creation of a sphere enclosure. """ + """Tests creation of a sphere enclosure.""" design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx") bodies = [design.bodies[0]] enclosure_options = EnclosureOptions() From ef762a28db712adae96b07897af778c7b744df60 Mon Sep 17 00:00:00 2001 From: smereu Date: Wed, 19 Nov 2025 14:21:37 -0600 Subject: [PATCH 16/20] Update _incompatible_tests.yml model used was too new for 24.2 and before 25.1 & 25.2 work fine --- tests/_incompatible_tests.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/_incompatible_tests.yml b/tests/_incompatible_tests.yml index ae4c4a61c3..4007348b77 100644 --- a/tests/_incompatible_tests.yml +++ b/tests/_incompatible_tests.yml @@ -29,6 +29,9 @@ backends: - tests/integration/test_prepare_tools.py::test_volume_extract_bad_edges - tests/integration/test_prepare_tools.py::test_volume_extract_bad_edges - tests/integration/test_prepare_tools.py::test_helix_detection + - tests/integration/test_prepare_tools.py::test_box_enclosure + - tests/integration/test_prepare_tools.py::test_cylinder_enclosure + - tests/integration/test_prepare_tools.py::test_sphere_enclosure - tests/integration/test_repair_tools.py::test_fix_small_face - tests/integration/test_repair_tools.py::test_find_interference - tests/integration/test_repair_tools.py::test_fix_interference @@ -148,6 +151,9 @@ backends: - tests/integration/test_prepare_tools.py::test_volume_extract_bad_edges - tests/integration/test_prepare_tools.py::test_volume_extract_bad_edges - tests/integration/test_prepare_tools.py::test_helix_detection + - tests/integration/test_prepare_tools.py::test_box_enclosure + - tests/integration/test_prepare_tools.py::test_cylinder_enclosure + - tests/integration/test_prepare_tools.py::test_sphere_enclosure - tests/integration/test_repair_tools.py::test_fix_small_face - tests/integration/test_repair_tools.py::test_find_interference - tests/integration/test_repair_tools.py::test_fix_interference From 1f231446aff1c5f4e4b6865a2099f4d1e7b0be78 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 20:21:59 +0000 Subject: [PATCH 17/20] chore: auto fixes from pre-commit hooks --- tests/_incompatible_tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/_incompatible_tests.yml b/tests/_incompatible_tests.yml index 4007348b77..1e1ee37df8 100644 --- a/tests/_incompatible_tests.yml +++ b/tests/_incompatible_tests.yml @@ -31,7 +31,7 @@ backends: - tests/integration/test_prepare_tools.py::test_helix_detection - tests/integration/test_prepare_tools.py::test_box_enclosure - tests/integration/test_prepare_tools.py::test_cylinder_enclosure - - tests/integration/test_prepare_tools.py::test_sphere_enclosure + - tests/integration/test_prepare_tools.py::test_sphere_enclosure - tests/integration/test_repair_tools.py::test_fix_small_face - tests/integration/test_repair_tools.py::test_find_interference - tests/integration/test_repair_tools.py::test_fix_interference @@ -153,7 +153,7 @@ backends: - tests/integration/test_prepare_tools.py::test_helix_detection - tests/integration/test_prepare_tools.py::test_box_enclosure - tests/integration/test_prepare_tools.py::test_cylinder_enclosure - - tests/integration/test_prepare_tools.py::test_sphere_enclosure + - tests/integration/test_prepare_tools.py::test_sphere_enclosure - tests/integration/test_repair_tools.py::test_fix_small_face - tests/integration/test_repair_tools.py::test_find_interference - tests/integration/test_repair_tools.py::test_fix_interference From 1ad54c3650cf6aec77ddba307c85171d170e0885 Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Thu, 20 Nov 2025 07:54:41 +0100 Subject: [PATCH 18/20] Update src/ansys/geometry/core/tools/prepare_tools.py --- src/ansys/geometry/core/tools/prepare_tools.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ansys/geometry/core/tools/prepare_tools.py b/src/ansys/geometry/core/tools/prepare_tools.py index b5f8050f72..2b712205e1 100644 --- a/src/ansys/geometry/core/tools/prepare_tools.py +++ b/src/ansys/geometry/core/tools/prepare_tools.py @@ -60,13 +60,13 @@ class EnclosureOptions: Parameters ---------- - create_shared_topology : bool + create_shared_topology : bool, default: False Whether shared topology should be applied after enclosure creation. - subtract_bodies : bool + subtract_bodies : bool, default: True Whether the specified bodies for enclosure creation should be subtracted from the enclosure. - frame : Frame + frame : Frame, default: None Frame used to orient the enclosure. - cushion_proportion : Real + cushion_proportion : Real, default: 0.25 A percentage of the minimum enclosure size. Determines the initial distance between the enclosed objects and the closest point of the enclosure to the objects. From 141022b2a147746240e7c821e320bd0a4a7ccc90 Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Thu, 20 Nov 2025 07:56:48 +0100 Subject: [PATCH 19/20] Update tests/integration/test_prepare_tools.py --- tests/integration/test_prepare_tools.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/integration/test_prepare_tools.py b/tests/integration/test_prepare_tools.py index 740ee455e0..4372643458 100644 --- a/tests/integration/test_prepare_tools.py +++ b/tests/integration/test_prepare_tools.py @@ -239,11 +239,6 @@ def test_helix_detection(modeler: Modeler): result = modeler.prepare_tools.detect_helixes(bodies) assert len(result["helixes"]) == 2 - # Test with multiple bodies - result = modeler.prepare_tools.detect_helixes(bodies) - assert len(result["helixes"]) == 2 - - def test_box_enclosure(modeler): """Tests creation of a box enclosure.""" design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx") From 395363a66f3ca963ffdb0ba93d70607cfccd3ad6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 20 Nov 2025 06:57:02 +0000 Subject: [PATCH 20/20] chore: auto fixes from pre-commit hooks --- tests/integration/test_prepare_tools.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/test_prepare_tools.py b/tests/integration/test_prepare_tools.py index 4372643458..05cbadd04f 100644 --- a/tests/integration/test_prepare_tools.py +++ b/tests/integration/test_prepare_tools.py @@ -239,6 +239,7 @@ def test_helix_detection(modeler: Modeler): result = modeler.prepare_tools.detect_helixes(bodies) assert len(result["helixes"]) == 2 + def test_box_enclosure(modeler): """Tests creation of a box enclosure.""" design = modeler.open_file(FILES_DIR / "BoxWithRound.scdocx")