Skip to content

Commit 6feed75

Browse files
Merge branch 'feat/measurement_tools_relocation' of https://github.com/ansys/pyansys-geometry into feat/prepare_tools_migration
# Conflicts: # src/ansys/geometry/core/_grpc/_services/_service.py
2 parents e8a0019 + fb526ec commit 6feed75

File tree

6 files changed

+212
-22
lines changed

6 files changed

+212
-22
lines changed

doc/changelog.d/1909.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
grpc measurement tools stub implementation

src/ansys/geometry/core/_grpc/_services/_service.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from .base.admin import GRPCAdminService
2727
from .base.bodies import GRPCBodyService
2828
from .base.dbuapplication import GRPCDbuApplicationService
29+
from .base.measurement_tools import GRPCMeasurementToolsService
2930
from .base.named_selection import GRPCNamedSelectionService
3031
from .base.prepare_tools import GRPCPrepareToolsService
3132

@@ -72,7 +73,8 @@ def __init__(self, channel: grpc.Channel, version: GeometryApiProtos | str | Non
7273
self._bodies = None
7374
self._dbu_application = None
7475
self._named_selection = None
75-
self._prepare_tools = None
76+
self._measurement_tools = None
77+
self._prepare_tools = None
7678

7779
@property
7880
def bodies(self) -> GRPCBodyService:
@@ -178,7 +180,33 @@ def named_selection(self) -> GRPCNamedSelectionService:
178180

179181
return self._named_selection
180182

181-
@property
183+
@property
184+
def measurement_tools(self) -> GRPCMeasurementToolsService:
185+
"""
186+
Get the measurement tools service for the specified version.
187+
188+
Returns
189+
-------
190+
MeasurementToolsServiceBase
191+
The measurement tools service for the specified version.
192+
"""
193+
if not self._measurement_tools:
194+
# Import the appropriate measurement tools service based on the version
195+
from .v0.measurement_tools import GRPCMeasurementToolsServiceV0
196+
from .v1.measurement_tools import GRPCMeasurementToolsServiceV1
197+
198+
if self.version == GeometryApiProtos.V0:
199+
self._measurement_tools = GRPCMeasurementToolsServiceV0(self.channel)
200+
elif self.version == GeometryApiProtos.V1: # pragma: no cover
201+
# V1 is not implemented yet
202+
self._measurement_tools = GRPCMeasurementToolsServiceV1(self.channel)
203+
else: # pragma: no cover
204+
# This should never happen as the version is set in the constructor
205+
raise ValueError(f"Unsupported version: {self.version}")
206+
207+
return self._measurement_tools
208+
209+
@property
182210
def prepare_tools(self) -> GRPCPrepareToolsService:
183211
"""
184212
Get the prepare tools service for the specified version.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
2+
# SPDX-License-Identifier: MIT
3+
#
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in all
13+
# copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
"""Module containing the measurement tools service implementation (abstraction layer)."""
23+
24+
from abc import ABC, abstractmethod
25+
26+
import grpc
27+
28+
29+
class GRPCMeasurementToolsService(ABC):
30+
"""Measurement tools service for gRPC communication with the Geometry server.
31+
32+
Parameters
33+
----------
34+
channel : grpc.Channel
35+
The gRPC channel to the server.
36+
"""
37+
38+
def __init__(self, channel: grpc.Channel):
39+
"""Initialize the MeasurementToolsService class."""
40+
pass # pragma: no cover
41+
42+
@abstractmethod
43+
def min_distance_between_objects(self, **kwargs) -> dict:
44+
"""Calculate the minimum distance between two objects."""
45+
pass # pragma: no cover
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
2+
# SPDX-License-Identifier: MIT
3+
#
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in all
13+
# copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
"""Module containing the measurement tools service implementation for v0."""
23+
24+
import grpc
25+
26+
from ansys.geometry.core.errors import protect_grpc
27+
28+
from ..base.measurement_tools import GRPCMeasurementToolsService
29+
30+
31+
class GRPCMeasurementToolsServiceV0(GRPCMeasurementToolsService):
32+
"""Measurement tools service for gRPC communication with the Geometry server.
33+
34+
This class provides methods to interact with the Geometry server's
35+
measurement tools service. It is specifically designed for the v0 version of the
36+
Geometry API.
37+
38+
Parameters
39+
----------
40+
channel : grpc.Channel
41+
The gRPC channel to the server.
42+
"""
43+
44+
@protect_grpc
45+
def __init__(self, channel: grpc.Channel): # noqa: D102
46+
from ansys.api.geometry.v0.measuretools_pb2_grpc import MeasureToolsStub
47+
48+
self.stub = MeasureToolsStub(channel)
49+
50+
@protect_grpc
51+
def min_distance_between_objects(self, **kwargs) -> dict: # noqa: D102
52+
from ansys.api.geometry.v0.measuretools_pb2 import MinDistanceBetweenObjectsRequest
53+
54+
bodies = kwargs["bodies"]
55+
selection = kwargs["selection"]
56+
backend_version = kwargs["backend_version"]
57+
58+
# Create the request - assumes all inputs are valid and of the proper type
59+
# Request is different based on backend_version (25.2 vs. earlier)
60+
if backend_version < (25, 2, 0):
61+
request = MinDistanceBetweenObjectsRequest(bodies=bodies)
62+
else:
63+
from ansys.api.dbu.v0.dbumodels_pb2 import EntityIdentifier
64+
65+
request = MinDistanceBetweenObjectsRequest(
66+
selection=[EntityIdentifier(id=selection[0]), EntityIdentifier(id=selection[1])]
67+
)
68+
69+
# Call the gRPC service
70+
response = self.stub.MinDistanceBetweenSelectionObjects(request)
71+
72+
# Return the response - formatted as a dictionary
73+
return {
74+
"distance": response.gap.distance,
75+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
2+
# SPDX-License-Identifier: MIT
3+
#
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in all
13+
# copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
"""Module containing the measurement tools service implementation for v0."""
23+
24+
import grpc
25+
26+
from ansys.geometry.core.errors import protect_grpc
27+
28+
from ..base.measurement_tools import GRPCMeasurementToolsService
29+
30+
31+
class GRPCMeasurementToolsServiceV1(GRPCMeasurementToolsService):
32+
"""Measurement tools service for gRPC communication with the Geometry server.
33+
34+
This class provides methods to interact with the Geometry server's
35+
measurement tools service. It is specifically designed for the v0 version of the
36+
Geometry API.
37+
38+
Parameters
39+
----------
40+
channel : grpc.Channel
41+
The gRPC channel to the server.
42+
"""
43+
44+
@protect_grpc
45+
def __init__(self, channel: grpc.Channel): # noqa: D102
46+
from ansys.api.geometry.v0.measuretools_pb2_grpc import MeasureToolsStub
47+
48+
self.stub = MeasureToolsStub(channel)
49+
50+
@protect_grpc
51+
def min_distance_between_objects(self, **kwargs): # noqa: D102
52+
raise NotImplementedError

src/ansys/geometry/core/tools/measurement_tools.py

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,10 @@
2323

2424
from typing import TYPE_CHECKING, Union
2525

26-
from ansys.api.geometry.v0.measuretools_pb2 import (
27-
MinDistanceBetweenObjectsRequest,
28-
MinDistanceBetweenObjectsResponse,
29-
)
30-
from ansys.api.geometry.v0.measuretools_pb2_grpc import MeasureToolsStub
3126
from ansys.geometry.core.connection import GrpcClient
32-
from ansys.geometry.core.errors import protect_grpc
3327
from ansys.geometry.core.misc.checks import min_backend_version
3428
from ansys.geometry.core.misc.measurements import DEFAULT_UNITS, Distance
29+
from ansys.geometry.core.typing import Real
3530

3631
if TYPE_CHECKING: # pragma: no cover
3732
from ansys.geometry.core.designer.body import Body
@@ -58,7 +53,7 @@ def distance(self) -> Distance:
5853
return self._distance
5954

6055
@classmethod
61-
def _from_distance_response(cls, response: MinDistanceBetweenObjectsResponse) -> "Gap":
56+
def _from_distance_response(cls, distance: Real) -> "Gap":
6257
"""Construct ``Gap`` object from distance response.
6358
6459
Parameters
@@ -71,7 +66,7 @@ def _from_distance_response(cls, response: MinDistanceBetweenObjectsResponse) ->
7166
This method is used internally to construct a ``Gap`` object from a
7267
gRPC response.
7368
"""
74-
distance = Distance(response.gap.distance, unit=DEFAULT_UNITS.LENGTH)
69+
distance = Distance(distance, unit=DEFAULT_UNITS.LENGTH)
7570
return cls(distance)
7671

7772

@@ -84,13 +79,10 @@ class MeasurementTools:
8479
gRPC client to use for the measurement tools.
8580
"""
8681

87-
@protect_grpc
8882
def __init__(self, grpc_client: GrpcClient):
8983
"""Initialize measurement tools class."""
9084
self._grpc_client = grpc_client
91-
self._measure_stub = MeasureToolsStub(self._grpc_client.channel)
9285

93-
@protect_grpc
9486
@min_backend_version(24, 2, 0)
9587
def min_distance_between_objects(
9688
self, object1: Union["Body", "Face", "Edge"], object2: Union["Body", "Face", "Edge"]
@@ -109,12 +101,9 @@ def min_distance_between_objects(
109101
Gap
110102
Gap between two bodies.
111103
"""
112-
if self._grpc_client.backend_version < (25, 2, 0):
113-
response = self._measure_stub.MinDistanceBetweenObjects(
114-
MinDistanceBetweenObjectsRequest(bodies=[object1.id, object2.id])
115-
)
116-
else:
117-
response = self._measure_stub.MinDistanceBetweenSelectionObjects(
118-
MinDistanceBetweenObjectsRequest(selection=[object1._grpc_id, object2._grpc_id])
119-
)
120-
return Gap._from_distance_response(response)
104+
response = self._grpc_client.services.measurement_tools.min_distance_between_objects(
105+
bodies=[object1.id, object2.id],
106+
selection=[object1.id, object2.id],
107+
backend_version=self._grpc_client.backend_version,
108+
)
109+
return Gap._from_distance_response(response["distance"])

0 commit comments

Comments
 (0)