Skip to content

Commit c40ddde

Browse files
jonahrbRobPasMue
andauthored
Cache Body Tessellation (#473)
Co-authored-by: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com>
1 parent e83e1c7 commit c40ddde

File tree

3 files changed

+46
-15
lines changed

3 files changed

+46
-15
lines changed

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

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Provides the ``Body`` class module."""
22
from abc import ABC, abstractmethod
33
from enum import Enum
4+
from functools import wraps
45

56
from ansys.api.geometry.v0.bodies_pb2 import (
67
CopyRequest,
@@ -410,6 +411,28 @@ def __init__(
410411
self._is_alive = True
411412
self._bodies_stub = BodiesStub(self._grpc_client.channel)
412413
self._commands_stub = CommandsStub(self._grpc_client.channel)
414+
self._tessellation = None
415+
416+
def reset_tessellation_cache(func):
417+
"""Decorator for ``TemplateBody`` methods that require a tessellation cache update.
418+
419+
Parameters
420+
----------
421+
func : method
422+
The method being called.
423+
424+
Returns
425+
-------
426+
Any
427+
The output of the method, if any.
428+
"""
429+
430+
@wraps(func)
431+
def wrapper(self: "TemplateBody", *args, **kwargs):
432+
self._tessellation = None
433+
return func(self, *args, **kwargs)
434+
435+
return wrapper
413436

414437
@property
415438
def _grpc_id(self) -> EntityIdentifier:
@@ -581,6 +604,7 @@ def project_curves(
581604

582605
@protect_grpc
583606
@check_input_types
607+
@reset_tessellation_cache
584608
def translate(self, direction: UnitVector3D, distance: Union[Quantity, Distance, Real]) -> None:
585609
distance = distance if isinstance(distance, Distance) else Distance(distance)
586610

@@ -635,9 +659,12 @@ def tessellate(
635659

636660
self._grpc_client.log.debug(f"Requesting tessellation for body {self.id}.")
637661

638-
resp = self._bodies_stub.GetTessellation(self._grpc_id)
662+
# cache tessellation
663+
if not self._tessellation:
664+
resp = self._bodies_stub.GetTessellation(self._grpc_id)
665+
self._tessellation = resp.face_tessellation.values()
639666

640-
pdata = [tess_to_pd(tess).transform(transform) for tess in resp.face_tessellation.values()]
667+
pdata = [tess_to_pd(tess).transform(transform) for tess in self._tessellation]
641668
comp = pv.MultiBlock(pdata)
642669
if merge:
643670
ugrid = comp.combine()

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

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""Provides the ``Component`` class module."""
22

33
from enum import Enum, unique
4-
from threading import Thread
54
import uuid # TODO: do we even need ID?, maybe use from SC?
65

76
from ansys.api.geometry.v0.bodies_pb2 import (
@@ -988,18 +987,9 @@ def tessellate(
988987
"""
989988
import pyvista as pv
990989

991-
datasets = []
992-
993-
def get_tessellation(body: Body):
994-
datasets.append(body.tessellate(merge=merge_bodies))
995-
996990
# Tessellate the bodies in this component
997-
threads = []
998-
for body in self.bodies:
999-
thread = Thread(target=get_tessellation, args=(body,))
1000-
thread.start()
1001-
threads.append(thread)
1002-
[thread.join() for thread in threads]
991+
datasets = [body.tessellate(merge_bodies) for body in self.bodies]
992+
1003993
blocks_list = [pv.MultiBlock(datasets)]
1004994

1005995
# Now, go recursively inside its subcomponents (with no arguments) and

tests/integration/test_tessellation.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import pytest
33

44
from ansys.geometry.core import Modeler
5-
from ansys.geometry.core.math import Plane, Point2D
5+
from ansys.geometry.core.math import Plane, Point2D, UnitVector3D, Vector3D
66
from ansys.geometry.core.misc.units import UNITS, Quantity
77
from ansys.geometry.core.sketch import Sketch
88

@@ -60,6 +60,20 @@ def test_body_tessellate(modeler: Modeler, skip_not_on_linux_service):
6060
assert mesh_2.n_points == 76
6161
assert mesh_2.n_arrays == 0
6262

63+
# Make sure instance body tessellation is the same as original
64+
comp_1_instance = design.add_component("Component_1_Instance", comp_1)
65+
assert comp_1_instance.bodies[0].tessellate() == comp_1.bodies[0].tessellate()
66+
67+
# After modifying placement, they should be different
68+
comp_1_instance.modify_placement(Vector3D([1, 2, 3]))
69+
assert comp_1_instance.bodies[0].tessellate() != comp_1.bodies[0].tessellate()
70+
71+
assert comp_1.bodies[0]._template._tessellation is not None
72+
73+
comp_1.bodies[0].translate(UnitVector3D([1, 0, 0]), 1)
74+
75+
assert comp_1.bodies[0]._template._tessellation is None
76+
6377

6478
def test_component_tessellate(modeler: Modeler, skip_not_on_linux_service):
6579
"""Test the component tessellation."""

0 commit comments

Comments
 (0)