Skip to content

Commit cae1170

Browse files
committed
wip: adding tesellation endpoints
1 parent 366453f commit cae1170

File tree

4 files changed

+99
-44
lines changed

4 files changed

+99
-44
lines changed

src/ansys/geometry/core/_grpc/_services/base/bodies.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,11 @@ def get_tesellation(self, **kwargs) -> dict:
194194
"""Get the tessellation of a body."""
195195
pass
196196

197+
@abstractmethod
198+
def get_tesellation_with_options(self, **kwargs) -> dict:
199+
"""Get the tessellation of a body with options."""
200+
pass
201+
197202
@abstractmethod
198203
def boolean(self, **kwargs) -> dict:
199204
"""Boolean operation."""

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

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434
from_frame_to_grpc_frame,
3535
from_grpc_material_to_material,
3636
from_grpc_point_to_point3d,
37+
from_grpc_tess_to_pd,
3738
from_plane_to_grpc_plane,
3839
from_point3d_to_grpc_point,
40+
from_tess_options_to_grpc_tess_options,
3941
from_unit_vector_to_grpc_direction,
4042
)
4143

@@ -390,7 +392,48 @@ def copy(self, **kwargs) -> dict: # noqa: D102
390392

391393
@protect_grpc
392394
def get_tesellation(self, **kwargs) -> dict: # noqa: D102
393-
raise NotImplementedError
395+
from ansys.api.geometry.v0.bodies_pb2 import GetTessellationRequest
396+
397+
tess_map = {}
398+
resp = [] # For compatibility with stream response
399+
try:
400+
resp_single = self.stub.GetTessellation(request=build_grpc_id(kwargs["id"]))
401+
resp.append(resp_single)
402+
except grpc.RpcError as err:
403+
if kwargs["backend_version"] < (25, 2, 0):
404+
raise err
405+
request = GetTessellationRequest(id=build_grpc_id(kwargs["id"]))
406+
resp = self.stub.GetTessellationStream(request=request)
407+
408+
for elem in resp:
409+
for face_id, face_tess in elem.face_tessellation.items():
410+
tess_map[face_id] = from_grpc_tess_to_pd(face_tess)
411+
412+
return {"tessellation": tess_map}
413+
414+
@protect_grpc
415+
def get_tesellation_with_options(self, **kwargs) -> dict: # noqa: D102
416+
from ansys.api.geometry.v0.bodies_pb2 import GetTessellationRequest
417+
418+
# Create the request - assumes all inputs are valid and of the proper type
419+
request = GetTessellationRequest(
420+
id=build_grpc_id(kwargs["id"]),
421+
options=from_tess_options_to_grpc_tess_options(kwargs["options"]),
422+
)
423+
424+
tess_map = {}
425+
resp = [] # For compatibility with stream response
426+
try:
427+
resp_single = self.stub.GetTessellationWithOptions(request)
428+
resp.append(resp_single)
429+
except grpc.RpcError:
430+
resp = self.stub.GetTessellationStream(request)
431+
432+
for elem in resp:
433+
for face_id, face_tess in elem.face_tessellation.items():
434+
tess_map[face_id] = from_grpc_tess_to_pd(face_tess)
435+
436+
return {"tessellation": tess_map}
394437

395438
@protect_grpc
396439
def boolean(self, **kwargs) -> dict: # noqa: D102

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
# SOFTWARE.
2222
"""Module containing v0 related conversions from PyAnsys Geometry objects to gRPC messages."""
2323

24+
from typing import TYPE_CHECKING
25+
2426
import pint
2527

2628
from ansys.api.dbu.v0.dbumodels_pb2 import EntityIdentifier
@@ -31,16 +33,23 @@
3133
MaterialProperty as GRPCMaterialProperty,
3234
Plane as GRPCPlane,
3335
Point as GRPCPoint,
36+
Tessellation,
37+
TessellationOptions as GRPCTessellationOptions,
3438
)
3539
from ansys.geometry.core.materials.material import Material
3640
from ansys.geometry.core.materials.property import MaterialProperty, MaterialPropertyType
3741
from ansys.geometry.core.math.frame import Frame
3842
from ansys.geometry.core.math.plane import Plane
3943
from ansys.geometry.core.math.point import Point3D
4044
from ansys.geometry.core.math.vector import UnitVector3D
45+
from ansys.geometry.core.misc.checks import graphics_required
4146
from ansys.geometry.core.misc.measurements import DEFAULT_UNITS
47+
from ansys.geometry.core.misc.options import TessellationOptions
4248
from ansys.geometry.core.misc.units import UNITS
4349

50+
if TYPE_CHECKING:
51+
import pyvista as pv
52+
4453

4554
def from_point3d_to_grpc_point(point: Point3D) -> GRPCPoint:
4655
"""Convert a ``Point3D`` class to a point gRPC message.
@@ -227,3 +236,35 @@ def from_plane_to_grpc_plane(plane: Plane) -> GRPCPlane:
227236
dir_y=from_unit_vector_to_grpc_direction(plane.direction_y),
228237
)
229238
)
239+
240+
241+
@graphics_required
242+
def from_grpc_tess_to_pd(tess: Tessellation) -> "pv.PolyData":
243+
"""Convert an ``ansys.api.geometry.Tessellation`` to ``pyvista.PolyData``."""
244+
# lazy imports here to improve initial load
245+
import numpy as np
246+
import pyvista as pv
247+
248+
return pv.PolyData(var_inp=np.array(tess.vertices).reshape(-1, 3), faces=tess.faces)
249+
250+
251+
def from_tess_options_to_grpc_tess_options(options: TessellationOptions) -> GRPCTessellationOptions:
252+
"""Convert a ``TessellationOptions`` class to a tessellation options gRPC message.
253+
254+
Parameters
255+
----------
256+
options : TessellationOptions
257+
Source tessellation options data.
258+
259+
Returns
260+
-------
261+
GRPCTessellationOptions
262+
Geometry service gRPC tessellation options message.
263+
"""
264+
return GRPCTessellationOptions(
265+
surface_deviation=options.surface_deviation,
266+
angle_deviation=options.angle_deviation,
267+
maximum_aspect_ratio=options.max_aspect_ratio,
268+
maximum_edge_length=options.max_edge_length,
269+
watertight=options.watertight,
270+
)

src/ansys/geometry/core/designer/body.py

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
from ansys.api.dbu.v0.dbumodels_pb2 import EntityIdentifier
3535
from ansys.api.geometry.v0.bodies_pb2 import (
3636
BooleanRequest,
37-
GetTessellationRequest,
3837
)
3938
from ansys.api.geometry.v0.bodies_pb2_grpc import BodiesStub
4039
from ansys.api.geometry.v0.commands_pb2 import (
@@ -48,12 +47,10 @@
4847
ShellRequest,
4948
)
5049
from ansys.api.geometry.v0.commands_pb2_grpc import CommandsStub
51-
from ansys.api.geometry.v0.models_pb2 import TessellationOptions as GRPCTessellationOptions
5250
from ansys.geometry.core.connection.client import GrpcClient
5351
from ansys.geometry.core.connection.conversions import (
5452
plane_to_grpc_plane,
5553
sketch_shapes_to_grpc_geometries,
56-
tess_to_pd,
5754
trimmed_curve_to_grpc_trimmed_curve,
5855
unit_vector_to_grpc_direction,
5956
)
@@ -1220,48 +1217,17 @@ def tessellate( # noqa: D102
12201217
# cache tessellation
12211218
if not self._tessellation:
12221219
if tess_options is not None:
1223-
request = GetTessellationRequest(
1224-
id=self._grpc_id,
1225-
options=GRPCTessellationOptions(
1226-
surface_deviation=tess_options.surface_deviation,
1227-
angle_deviation=tess_options.angle_deviation,
1228-
maximum_aspect_ratio=tess_options.max_aspect_ratio,
1229-
maximum_edge_length=tess_options.max_edge_length,
1230-
watertight=tess_options.watertight,
1231-
),
1220+
resp = self._grpc_client.services.body_service.get_tesellation_with_options(
1221+
id=self.id,
1222+
options=tess_options,
12321223
)
1233-
try:
1234-
resp = self._bodies_stub.GetTessellationWithOptions(request)
1235-
self._tessellation = {
1236-
str(face_id): tess_to_pd(face_tess)
1237-
for face_id, face_tess in resp.face_tessellation.items()
1238-
}
1239-
except Exception:
1240-
tessellation_map = {}
1241-
for response in self._bodies_stub.GetTessellationStream(request):
1242-
for key, value in response.face_tessellation.items():
1243-
tessellation_map[key] = tess_to_pd(value)
1244-
1245-
self._tessellation = tessellation_map
12461224
else:
1247-
try:
1248-
resp = self._bodies_stub.GetTessellation(self._grpc_id)
1249-
self._tessellation = {
1250-
str(face_id): tess_to_pd(face_tess)
1251-
for face_id, face_tess in resp.face_tessellation.items()
1252-
}
1253-
except Exception as err:
1254-
# Streaming is not supported in older versions...
1255-
if self._grpc_client.backend_version < (25, 2, 0):
1256-
raise err
1257-
1258-
tessellation_map = {}
1259-
request = GetTessellationRequest(self._grpc_id)
1260-
for response in self._bodies_stub.GetTessellationStream(request):
1261-
for key, value in response.face_tessellation.items():
1262-
tessellation_map[key] = tess_to_pd(value)
1263-
1264-
self._tessellation = tessellation_map
1225+
resp = self._grpc_client.services.body_service.get_tesellation(
1226+
id=self.id,
1227+
backend_version=self._grpc_client.backend_version,
1228+
)
1229+
1230+
self._tessellation = resp.get("tessellation")
12651231

12661232
pdata = [tess.transform(transform, inplace=False) for tess in self._tessellation.values()]
12671233
comp = pv.MultiBlock(pdata)

0 commit comments

Comments
 (0)