Skip to content

Commit 2952b14

Browse files
committed
finalize tracker changes for boolean and update from response
This PR contains the following changes - Client side change for boolean to remove delete on the python side (now done in the SC API) and update from response - Changes to add and delete body logic for proper dealing with @cached_property implementation of the function that get bodies - Small refactoring to avoid multiple definition of the function _serialize_tracker_command_response
1 parent 40c19c1 commit 2952b14

File tree

7 files changed

+156
-108
lines changed

7 files changed

+156
-108
lines changed

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

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
import grpc
2525
import pint
2626

27+
from ansys.geometry.core import USE_TRACKER_TO_UPDATE_DESIGN
2728
from ansys.geometry.core.errors import protect_grpc
29+
from ansys.geometry.core.misc.auxiliary import get_design_from_body
2830
from ansys.geometry.core.misc.measurements import DEFAULT_UNITS
2931

3032
from ..base.bodies import GRPCBodyService
@@ -658,14 +660,21 @@ def boolean(self, **kwargs) -> dict: # noqa: D102
658660

659661
# Call the gRPC service and build the requests accordingly
660662
resp = 0
663+
serialized_tracker_response = {}
661664
try:
662-
resp = self.stub.Boolean(
663-
request=BooleanRequest(
664-
body1=kwargs["target"].id,
665-
tool_bodies=[other.id for other in kwargs["other"]],
666-
method=kwargs["method"],
665+
request = BooleanRequest(
666+
body1=kwargs["target"].id,
667+
tool_bodies=[other.id for other in kwargs["other"]],
668+
method=kwargs["method"],
669+
)
670+
if USE_TRACKER_TO_UPDATE_DESIGN:
671+
request.keep_other = kwargs["keep_other"]
672+
resp = self.stub.Boolean(request=request)
673+
if USE_TRACKER_TO_UPDATE_DESIGN:
674+
parent_design = get_design_from_body(kwargs["target"])
675+
serialized_tracker_response = parent_design._serialize_tracker_command_response(
676+
resp.response
667677
)
668-
).empty_result
669678
except grpc.RpcError as err: # pragma: no cover
670679
# TODO: to be deleted - old versions did not have "tool_bodies" in the request
671680
# This is a temporary fix to support old versions of the server - should be deleted
@@ -692,15 +701,15 @@ def boolean(self, **kwargs) -> dict: # noqa: D102
692701
body2=kwargs["other"][0].id,
693702
method=kwargs["method"],
694703
)
695-
).empty_result
704+
)
696705
else:
697706
raise err
698707

699-
if resp == 1:
708+
if resp.empty_result == 1:
700709
raise ValueError(
701710
f"Boolean operation of type '{kwargs['method']}' failed: {kwargs['err_msg']}.\n"
702711
f"Involving bodies:{kwargs['target']}, {kwargs['other']}"
703712
)
704713

705714
# Return the response - formatted as a dictionary
706-
return {}
715+
return {"complete_command_response": serialized_tracker_response}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ def find_and_fix_simplify(self, **kwargs) -> dict: # noqa: D102
344344
# Call the gRPC service
345345
response = self.stub.FindAndSimplify(request)
346346

347-
serialized_tracker_response = self._serialize_tracker_command_response(
347+
serialized_tracker_response = kwargs["parent_design"]._serialize_tracker_command_response(
348348
response.complete_command_response
349349
)
350350

@@ -383,7 +383,7 @@ def find_and_fix_stitch_faces(self, **kwargs) -> dict: # noqa: D102
383383
# Call the gRPC service
384384
response = self.stub.FindAndFixStitchFaces(request)
385385

386-
serialized_tracker_response = self._serialize_tracker_command_response(
386+
serialized_tracker_response = kwargs["parent_design"]._serialize_tracker_command_response(
387387
response.complete_command_response
388388
)
389389

@@ -467,7 +467,7 @@ def find_and_fix_short_edges(self, **kwargs): # noqa: D102
467467
# Call the gRPC service
468468
response = self.stub.FindAndFixShortEdges(request)
469469

470-
serialized_tracker_response = self._serialize_tracker_command_response(
470+
serialized_tracker_response = kwargs["parent_design"]._serialize_tracker_command_response(
471471
response.complete_command_response
472472
)
473473

@@ -494,7 +494,7 @@ def find_and_fix_extra_edges(self, **kwargs) -> dict: # noqa: D102
494494
# Call the gRPC service
495495
response = self.stub.FindAndFixExtraEdges(request)
496496

497-
serialized_tracker_response = self._serialize_tracker_command_response(
497+
serialized_tracker_response = kwargs["parent_design"]._serialize_tracker_command_response(
498498
response.complete_command_response
499499
)
500500

@@ -525,7 +525,7 @@ def find_and_fix_split_edges(self, **kwargs) -> dict: # noqa: D102
525525
# Call the gRPC service
526526
response = self.stub.FindAndFixSplitEdges(request)
527527

528-
serialized_tracker_response = self._serialize_tracker_command_response(
528+
serialized_tracker_response = kwargs["parent_design"]._serialize_tracker_command_response(
529529
response.complete_command_response
530530
)
531531

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

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
ShellRequest,
4444
)
4545
from ansys.api.geometry.v0.commands_pb2_grpc import CommandsStub
46+
from ansys.geometry.core import USE_TRACKER_TO_UPDATE_DESIGN
4647
from ansys.geometry.core.connection.client import GrpcClient
4748
from ansys.geometry.core.connection.conversions import (
4849
plane_to_grpc_plane,
@@ -1948,7 +1949,9 @@ def __generic_boolean_command(
19481949
# If USE_TRACKER_TO_UPDATE_DESIGN is True, we serialize the response
19491950
# and update the parent design with the serialized response.
19501951
tracker_response = response.result.complete_command_response
1951-
serialized_response = self._serialize_tracker_command_response(tracker_response)
1952+
serialized_response = parent_design._serialize_tracker_command_response(
1953+
tracker_response
1954+
)
19521955
parent_design._update_from_tracker(serialized_response)
19531956

19541957
@reset_tessellation_cache
@@ -1962,20 +1965,26 @@ def __generic_boolean_op(
19621965
err_msg: str,
19631966
) -> None:
19641967
grpc_other = other if isinstance(other, Iterable) else [other]
1965-
if keep_other:
1966-
# Make a copy of the other body to keep it...
1967-
# stored temporarily in the parent component - since it will be deleted
1968-
grpc_other = [b.copy(self.parent_component, f"BoolOpCopy_{b.name}") for b in grpc_other]
1969-
1970-
self._template._grpc_client.services.bodies.boolean(
1971-
target=self,
1972-
other=grpc_other,
1973-
method=method,
1974-
err_msg=err_msg,
1968+
if not USE_TRACKER_TO_UPDATE_DESIGN:
1969+
if keep_other:
1970+
# Make a copy of the other body to keep it...
1971+
# stored temporarily in the parent component - since it will be deleted
1972+
grpc_other = [
1973+
b.copy(self.parent_component, f"BoolOpCopy_{b.name}") for b in grpc_other
1974+
]
1975+
1976+
response = self._template._grpc_client.services.bodies.boolean(
1977+
target=self, other=grpc_other, method=method, err_msg=err_msg, keep_other=keep_other
19751978
)
19761979

1977-
for b in grpc_other:
1978-
b.parent_component.delete_body(b)
1980+
if not USE_TRACKER_TO_UPDATE_DESIGN:
1981+
for b in grpc_other:
1982+
b.parent_component.delete_body(b)
1983+
else:
1984+
# If USE_TRACKER_TO_UPDATE_DESIGN is True, we serialize the response
1985+
# and update the parent design with the serialized response.
1986+
parent_design = get_design_from_body(self)
1987+
parent_design._update_from_tracker(response["complete_command_response"])
19791988

19801989
def __repr__(self) -> str:
19811990
"""Represent the ``Body`` as a string."""

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ def __init__(
216216
self._name = new_component.component.name
217217
self._instance_name = new_component.component.instance_name
218218
else:
219+
new_component = None
219220
self._name = name
220221
self._id = None
221222
self._instance_name = instance_name
@@ -248,8 +249,14 @@ def __init__(
248249

249250
elif not read_existing_comp:
250251
# This is an independent Component - Create new Part and MasterComponent
251-
p = Part(uuid.uuid4(), f"p_{name}", [], [])
252-
master = MasterComponent(uuid.uuid4(), f"master_{name}", p)
252+
p = Part(
253+
uuid.uuid4() if not new_component else new_component.template, f"p_{name}", [], []
254+
)
255+
master = MasterComponent(
256+
uuid.uuid4() if not new_component else new_component.component.master_id,
257+
f"master_{name}",
258+
p,
259+
)
253260
self._master_component = master
254261

255262
self._master_component.occurrences.append(self)

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

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,55 @@ def __repr__(self) -> str:
10001000
lines.append(f" N Design Points : {len(self.design_points)}")
10011001
return "\n".join(lines)
10021002

1003+
def _serialize_tracker_command_response(self, response) -> dict:
1004+
"""Serialize a TrackerCommandResponse object into a dictionary.
1005+
1006+
Parameters
1007+
----------
1008+
response : TrackerCommandResponse
1009+
The gRPC TrackerCommandResponse object to serialize.
1010+
1011+
Returns
1012+
-------
1013+
dict
1014+
A dictionary representation of the TrackerCommandResponse object.
1015+
"""
1016+
1017+
def serialize_body(body):
1018+
return {
1019+
"id": body.id,
1020+
"name": body.name,
1021+
"can_suppress": body.can_suppress,
1022+
"transform_to_master": {
1023+
"m00": body.transform_to_master.m00,
1024+
"m11": body.transform_to_master.m11,
1025+
"m22": body.transform_to_master.m22,
1026+
"m33": body.transform_to_master.m33,
1027+
},
1028+
"master_id": body.master_id,
1029+
"parent_id": body.parent_id,
1030+
}
1031+
1032+
def serialize_entity_identifier(entity):
1033+
"""Serialize an EntityIdentifier object into a dictionary."""
1034+
return {
1035+
"id": entity.id,
1036+
}
1037+
1038+
return {
1039+
"success": response.success,
1040+
"created_bodies": [
1041+
serialize_body(body) for body in getattr(response, "created_bodies", [])
1042+
],
1043+
"modified_bodies": [
1044+
serialize_body(body) for body in getattr(response, "modified_bodies", [])
1045+
],
1046+
"deleted_bodies": [
1047+
serialize_entity_identifier(entity)
1048+
for entity in getattr(response, "deleted_bodies", [])
1049+
],
1050+
}
1051+
10031052
def __read_existing_design(self) -> None:
10041053
"""Read an existing ``Design`` located on the server."""
10051054
#
@@ -1298,7 +1347,12 @@ def _handle_deleted_bodies(self, deleted_bodies):
12981347
for body in self.bodies:
12991348
if body.id == body_id:
13001349
body._is_alive = False
1301-
self.bodies.remove(body)
1350+
# self.bodies.remove(body)
1351+
for bd in self._master_component.part.bodies:
1352+
if bd.id == body_id:
1353+
self._master_component.part.bodies.remove(bd)
1354+
break
1355+
self._clear_cached_bodies()
13021356
removed = True
13031357
self._grpc_client.log.info(
13041358
f"Deleted body (ID: {body_id}) removed from root level."
@@ -1325,10 +1379,12 @@ def _handle_created_bodies(self, created_bodies):
13251379
)
13261380
continue
13271381

1328-
added = any(self._find_and_add_body(body_info, self.components))
1382+
added = self._find_and_add_body(body_info, self.components)
13291383
if not added:
13301384
new_body = MasterBody(body_id, body_name, self._grpc_client, is_surface=is_surface)
1331-
self.bodies.append(new_body)
1385+
# self.bodies.append(new_body)
1386+
self._master_component.part.bodies.append(new_body)
1387+
self._clear_cached_bodies()
13321388
self._grpc_client.log.debug(
13331389
f"Added new body '{body_name}' (ID: {body_id}) to root level."
13341390
)
@@ -1343,14 +1399,17 @@ def _update_body(self, existing_body, body_info):
13431399

13441400
def _find_and_add_body(self, body_info, components):
13451401
for component in components:
1346-
if component.id == body_info["parent_id"]:
1402+
parent_id_for_body = component._master_component.part.id
1403+
if parent_id_for_body == body_info["parent_id"]:
13471404
new_body = MasterBody(
13481405
body_info["id"],
13491406
body_info["name"],
13501407
self._grpc_client,
13511408
is_surface=body_info.get("is_surface", False),
13521409
)
1353-
component.bodies.append(new_body)
1410+
# component.bodies.append(new_body)
1411+
component._master_component.part.bodies.append(new_body)
1412+
component._clear_cached_bodies()
13541413
self._grpc_client.log.debug(
13551414
f"Added new body '{new_body.name}' (ID: {new_body.id}) "
13561415
f"to component '{component.name}' (ID: {component.id})"
@@ -1380,11 +1439,17 @@ def _find_and_update_body(self, body_info, component):
13801439

13811440
def _find_and_remove_body(self, body_info, component):
13821441
for body in component.bodies:
1383-
if body.id == body_info["id"]:
1442+
body_info_id = body_info["id"]
1443+
if body.id == f"{component.id}/{body_info_id}":
13841444
body._is_alive = False
1385-
component.bodies.remove(body)
1445+
# component.bodies.remove(body)
1446+
for bd in component._master_component.part.bodies:
1447+
if bd.id == body_info_id:
1448+
component._master_component.part.bodies.remove(bd)
1449+
break
1450+
component._clear_cached_bodies()
13861451
self._grpc_client.log.debug(
1387-
f"Removed body '{body_info['name']}' (ID: {body_info['id']}) from component "
1452+
f"Removed body (ID: {body_info['id']}) from component "
13881453
f"'{component.name}' (ID: {component.id})"
13891454
)
13901455
return True

0 commit comments

Comments
 (0)