diff --git a/doc/changelog.d/1806.added.md b/doc/changelog.d/1806.added.md new file mode 100644 index 0000000000..c1bd214626 --- /dev/null +++ b/doc/changelog.d/1806.added.md @@ -0,0 +1 @@ +matrix helper methods \ No newline at end of file diff --git a/doc/changelog.d/1808.fixed.md b/doc/changelog.d/1808.fixed.md new file mode 100644 index 0000000000..be95a47cab --- /dev/null +++ b/doc/changelog.d/1808.fixed.md @@ -0,0 +1 @@ +translating sketch issues when using a custom default unit \ No newline at end of file diff --git a/doc/changelog.d/1922.added.md b/doc/changelog.d/1922.added.md new file mode 100644 index 0000000000..b150ea1e50 --- /dev/null +++ b/doc/changelog.d/1922.added.md @@ -0,0 +1 @@ +update with delta \ No newline at end of file diff --git a/src/ansys/geometry/core/_grpc/_services/v0/repair_tools.py b/src/ansys/geometry/core/_grpc/_services/v0/repair_tools.py index 5b7000e990..e75e2cf37f 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/repair_tools.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/repair_tools.py @@ -258,6 +258,7 @@ def find_and_fix_simplify(self, **kwargs) -> dict: # noqa: D102 "repaired": response.repaired, "created_bodies_monikers": [], "modified_bodies_monikers": [], + "complete_command_response": response.complete_command_response, } @protect_grpc @@ -333,6 +334,7 @@ def find_and_fix_short_edges(self, **kwargs): # noqa: D102 "repaired": response.repaired, "created_bodies_monikers": [], "modified_bodies_monikers": [], + "complete_command_response": response.complete_command_response, } @protect_grpc @@ -353,6 +355,7 @@ def find_and_fix_extra_edges(self, **kwargs) -> dict: # noqa: D102 "repaired": response.repaired, "created_bodies_monikers": response.created_bodies_monikers, "modified_bodies_monikers": response.modified_bodies_monikers, + "complete_command_response": response.complete_command_response, } @protect_grpc @@ -378,6 +381,7 @@ def find_and_fix_split_edges(self, **kwargs) -> dict: # noqa: D102 "repaired": response.repaired, "created_bodies_monikers": [], "modified_bodies_monikers": [], + "complete_command_response": response.complete_command_response, } @staticmethod diff --git a/src/ansys/geometry/core/designer/design.py b/src/ansys/geometry/core/designer/design.py index 17f1a6f409..256b9ea9be 100644 --- a/src/ansys/geometry/core/designer/design.py +++ b/src/ansys/geometry/core/designer/design.py @@ -1266,3 +1266,137 @@ def _update_design_inplace(self) -> None: # Read the existing design self.__read_existing_design() + + def update_from_tracker(self, tracker_response): + """ + Update the design with the changed bodies while preserving unchanged ones. + + Parameters + ---------- + changed_bodies : list[dict] + A list of dictionaries representing changed body information. Each dictionary + should contain 'id', 'name', and 'is_surface' keys. + """ + print("Updating design using the tracker...") + + # Function to update a body if it exists + def update_body(existing_body, body_info): + existing_body.name = body_info.name + existing_body._template._is_surface = body_info.is_surface + print(f"Updated body: {body_info.name} (ID: {body_info.id})") + + # Function to find and add bodies within components recursively + def find_and_add_body(body_info, component): + for component in component: + if component.id == body_info["parent_id"]: + new_body = MasterBody( + body_info["id"], + body_info["name"], + self._grpc_client, + is_surface=body_info["is_surface"], + ) + component.bodies.append(new_body) + print(f"Added new body: {body_info['name']} (ID: {body_info['id']})") + return True # Found and added + + # Recursively search in subcomponents + if find_and_add_body(body_info, component.components): + return True + + return False # Not found + + # Function to find and update bodies within components recursively + def find_and_update_body(body_info, component): + if component == []: + return False + for body in component.bodies: + if body.id == body_info.id: + update_body(body, body_info) + return True # Found and updated + + # Recursively search in subcomponents + if find_and_update_body(body_info, component.components): + return True + + return False # Not found + + # Function to find and remove bodies within components recursively + + def find_and_remove_body(body_info, component): + if component == []: + return False + for body in component.bodies: + if body.id == body_info.id: + component.bodies.remove(body) + print(f"Removed body: {body_info.id}") + return True # Found and removed + + # Recursively search in subcomponents + if find_and_remove_body(body_info, component.components): + return True + + return False # Not found + + # Loop through all changed bodies from the tracker + for body_info in tracker_response.modified_bodies: + body_id = body_info.id + body_name = body_info.name + is_surface = body_info.is_surface + + updated = False # Track if a body was updated + + # First, check bodies at the root level + for body in self.bodies: + if body.id == body_id: + update_body(body, body_info) + updated = True + break + + # If not found in root, search within components + if not updated: + for component in self.components: + updated = find_and_update_body(body_info, component) + + # Loop through all deleted bodies from the tracker + for body_info in tracker_response.deleted_bodies: + body_id = body_info.id + + removed = False # Track if a body was removed + + # First, check bodies at the root level + for body in self.bodies: + if body.id == body_id: + self.bodies.remove(body) + print(f"Removed body: {body_id}") + removed = True + break + + # If not found in root, search within components + if not removed: + removed = find_and_remove_body(body_info, self.components) + + # Loop through all added bodies from the tracker + for body_info in tracker_response.created_bodies: + body_id = body_info["id"] + body_name = body_info["name"] + is_surface = body_info["is_surface"] + + added = False # Track if a body was added + + # First, check if the body already exists at the root level + for body in self.bodies: + if body.id == body_id: + added = True + break + + # If not found in root, search within components + if not added: + added = find_and_add_body(body_info, self.components) + + # If still not found, add it as a new body at the root level + if not added: + new_body = MasterBody(body_id, body_name, self._grpc_client, is_surface=is_surface) + self.bodies.append(new_body) + print(f"Added new body: {body_name} (ID: {body_id})") + + print("Design update completed.") diff --git a/src/ansys/geometry/core/tools/prepare_tools.py b/src/ansys/geometry/core/tools/prepare_tools.py index 241d47ad37..ad613442bc 100644 --- a/src/ansys/geometry/core/tools/prepare_tools.py +++ b/src/ansys/geometry/core/tools/prepare_tools.py @@ -266,11 +266,11 @@ def enhanced_share_topology( ) message = RepairToolMessage( - response.get("success"), - response.get("created_bodies_monikers"), - response.get("modified_bodies_monikers"), - response.get("found"), - response.get("repaired"), + success=response.get("success"), + created_bodies=response.get("created_bodies_monikers"), + modified_bodies=response.get("modified_bodies_monikers"), + found=response.get("found"), + repaired=response.get("repaired"), ) return message diff --git a/src/ansys/geometry/core/tools/problem_areas.py b/src/ansys/geometry/core/tools/problem_areas.py index 2b769f149d..fdbdf29c13 100644 --- a/src/ansys/geometry/core/tools/problem_areas.py +++ b/src/ansys/geometry/core/tools/problem_areas.py @@ -131,13 +131,15 @@ def fix(self) -> RepairToolMessage: response = self._repair_stub.FixDuplicateFaces( FixDuplicateFacesRequest(duplicate_face_problem_area_id=self._grpc_id) ) - parent_design._update_design_inplace() + # parent_design._update_design_inplace() message = RepairToolMessage( - response.result.success, - response.result.created_bodies_monikers, - response.result.modified_bodies_monikers, + success=response.result.success, + created_bodies=response.result.created_bodies_monikers, + modified_bodies=response.result.modified_bodies_monikers, ) + parent_design.update_from_tracker(response.result.complete_command_response) + return message @@ -188,10 +190,11 @@ def fix(self) -> RepairToolMessage: ) parent_design._update_design_inplace() message = RepairToolMessage( - response.result.success, - response.result.created_bodies_monikers, - response.result.modified_bodies_monikers, + success=response.result.success, + created_bodies=response.result.created_bodies_monikers, + modified_bodies=response.result.modified_bodies_monikers, ) + # parent_design.update_from_tracker(response.result.complete_command_response) return message @@ -242,9 +245,9 @@ def fix(self) -> RepairToolMessage: ) parent_design._update_design_inplace() message = RepairToolMessage( - response.result.success, - response.result.created_bodies_monikers, - response.result.modified_bodies_monikers, + success=response.result.success, + created_bodies=response.result.created_bodies_monikers, + modified_bodies=response.result.modified_bodies_monikers, ) return message @@ -293,12 +296,12 @@ def fix(self) -> RepairToolMessage: parent_design = get_design_from_edge(self.edges[0]) request = FixExtraEdgesRequest(extra_edge_problem_area_id=self._grpc_id) response = self._repair_stub.FixExtraEdges(request) - parent_design._update_design_inplace() message = RepairToolMessage( - response.result.success, - response.result.created_bodies_monikers, - response.result.modified_bodies_monikers, + success=response.result.success, + created_bodies=response.result.created_bodies_monikers, + modified_bodies=response.result.modified_bodies_monikers, ) + parent_design.update_from_tracker(response.result.complete_command_response) return message @@ -348,12 +351,13 @@ def fix(self) -> RepairToolMessage: response = self._repair_stub.FixShortEdges( FixShortEdgesRequest(short_edge_problem_area_id=self._grpc_id) ) - parent_design._update_design_inplace() + # parent_design._update_design_inplace() message = RepairToolMessage( - response.result.success, - response.result.created_bodies_monikers, - response.result.modified_bodies_monikers, + success=response.result.success, + created_bodies=response.result.created_bodies_monikers, + modified_bodies=response.result.modified_bodies_monikers, ) + parent_design.update_from_tracker(response.result.complete_command_response) return message @@ -403,12 +407,15 @@ def fix(self) -> RepairToolMessage: response = self._repair_stub.FixSmallFaces( FixSmallFacesRequest(small_face_problem_area_id=self._grpc_id) ) - parent_design._update_design_inplace() + # parent_design._update_design_inplace() message = RepairToolMessage( - response.result.success, - response.result.created_bodies_monikers, - response.result.modified_bodies_monikers, + success=response.result.success, + created_bodies=response.result.created_bodies_monikers, + modified_bodies=response.result.modified_bodies_monikers, ) + + parent_design.update_from_tracker(response.result.complete_command_response) + return message @@ -457,12 +464,14 @@ def fix(self) -> RepairToolMessage: response = self._repair_stub.FixSplitEdges( FixSplitEdgesRequest(split_edge_problem_area_id=self._grpc_id) ) - parent_design._update_design_inplace() + # parent_design._update_design_inplace() message = RepairToolMessage( - response.result.success, - response.result.created_bodies_monikers, - response.result.modified_bodies_monikers, + success=response.result.success, + created_bodies=response.result.created_bodies_monikers, + modified_bodies=response.result.modified_bodies_monikers, ) + parent_design.update_from_tracker(response.result.complete_command_response) + return message @@ -511,12 +520,13 @@ def fix(self) -> RepairToolMessage: response = self._repair_stub.FixStitchFaces( FixStitchFacesRequest(stitch_face_problem_area_id=self._grpc_id) ) - parent_design._update_design_inplace() + # parent_design._update_design_inplace() message = RepairToolMessage( - response.result.success, - response.result.created_bodies_monikers, - response.result.modified_bodies_monikers, + success=response.result.success, + created_bodies=response.result.created_bodies_monikers, + modified_bodies=response.result.modified_bodies_monikers, ) + parent_design.update_from_tracker(response.result.complete_command_response) return message @@ -560,12 +570,13 @@ def fix(self) -> RepairToolMessage: response = self._repair_stub.FixAdjustSimplify( FixAdjustSimplifyRequest(adjust_simplify_problem_area_id=self._grpc_id) ) - parent_design._update_design_inplace() + # parent_design._update_design_inplace() message = RepairToolMessage( - response.result.success, - response.result.created_bodies_monikers, - response.result.modified_bodies_monikers, + success=response.result.success, + created_bodies=response.result.created_bodies_monikers, + modified_bodies=response.result.modified_bodies_monikers, ) + parent_design.update_from_tracker(response.result.complete_command_response) return message diff --git a/src/ansys/geometry/core/tools/repair_tool_message.py b/src/ansys/geometry/core/tools/repair_tool_message.py index 4329c7d7f7..45ef82c33e 100644 --- a/src/ansys/geometry/core/tools/repair_tool_message.py +++ b/src/ansys/geometry/core/tools/repair_tool_message.py @@ -30,6 +30,10 @@ def __init__( success: bool, created_bodies: list[str], modified_bodies: list[str], + deleted_bodies: list[str] = None, + craeted_components: list[str] = None, + modified_components: list[str] = None, + deleted_components: list[str] = None, found: int = -1, repaired: int = -1, ): diff --git a/src/ansys/geometry/core/tools/repair_tools.py b/src/ansys/geometry/core/tools/repair_tools.py index a0d468a70b..d38ff5c2fb 100644 --- a/src/ansys/geometry/core/tools/repair_tools.py +++ b/src/ansys/geometry/core/tools/repair_tools.py @@ -479,7 +479,7 @@ def find_and_fix_short_edges( ) parent_design = get_design_from_body(bodies[0]) - parent_design._update_design_inplace() + # parent_design._update_design_inplace() message = RepairToolMessage( success=response["success"], found=response["found"], @@ -487,6 +487,7 @@ def find_and_fix_short_edges( created_bodies=[], modified_bodies=[], ) + parent_design.update_from_tracker(response.complete_command_response) return message @protect_grpc @@ -530,7 +531,7 @@ def find_and_fix_extra_edges( ) parent_design = get_design_from_body(bodies[0]) - parent_design._update_design_inplace() + # parent_design._update_design_inplace() message = RepairToolMessage( response["success"], response["created_bodies_monikers"], @@ -538,6 +539,7 @@ def find_and_fix_extra_edges( response["found"], response["repaired"], ) + parent_design.update_from_tracker(response.complete_command_response) return message @protect_grpc @@ -592,7 +594,7 @@ def find_and_fix_split_edges( ) parent_design = get_design_from_body(bodies[0]) - parent_design._update_design_inplace() + # parent_design._update_design_inplace() message = RepairToolMessage( response["success"], response["created_bodies_monikers"], @@ -600,6 +602,8 @@ def find_and_fix_split_edges( response["found"], response["repaired"], ) + parent_design.update_from_tracker(response.complete_command_response) + return message @protect_grpc @@ -642,7 +646,7 @@ def find_and_fix_simplify( ) parent_design = get_design_from_body(bodies[0]) - parent_design._update_design_inplace() + # parent_design._update_design_inplace() message = RepairToolMessage( response["success"], response["created_bodies_monikers"], @@ -650,6 +654,7 @@ def find_and_fix_simplify( response["found"], response["repaired"], ) + parent_design.update_from_tracker(response.complete_command_response) return message def inspect_geometry(self, bodies: list["Body"] = None) -> list[InspectResult]: diff --git a/tests/integration/test_repair_tools.py b/tests/integration/test_repair_tools.py index 4317691149..4ce84e5730 100644 --- a/tests/integration/test_repair_tools.py +++ b/tests/integration/test_repair_tools.py @@ -154,6 +154,7 @@ def test_find_duplicate_faces(modeler: Modeler): design = modeler.open_file(FILES_DIR / "DuplicateFacesDesignBefore.scdocx") problem_areas = modeler.repair_tools.find_duplicate_faces(design.bodies) assert len(problem_areas) == 1 + design.close() def test_duplicate_face_id(modeler: Modeler): @@ -161,6 +162,7 @@ def test_duplicate_face_id(modeler: Modeler): design = modeler.open_file(FILES_DIR / "DuplicateFacesDesignBefore.scdocx") problem_areas = modeler.repair_tools.find_duplicate_faces(design.bodies) assert problem_areas[0].id != "0" + design.close() def test_duplicate_face_faces(modeler: Modeler): @@ -170,6 +172,7 @@ def test_duplicate_face_faces(modeler: Modeler): design = modeler.open_file(FILES_DIR / "DuplicateFacesDesignBefore.scdocx") problem_areas = modeler.repair_tools.find_duplicate_faces(design.bodies) assert len(problem_areas[0].faces) > 0 + design.close() def test_fix_duplicate_face(modeler: Modeler): @@ -179,6 +182,7 @@ def test_fix_duplicate_face(modeler: Modeler): design = modeler.open_file(FILES_DIR / "DuplicateFacesDesignBefore.scdocx") problem_areas = modeler.repair_tools.find_duplicate_faces(design.bodies) assert problem_areas[0].fix().success is True + design.close() def test_find_small_faces(modeler: Modeler): @@ -294,6 +298,7 @@ def test_find_and_fix_duplicate_faces(modeler: Modeler): for area in areas: area.fix() assert len(design.bodies) == 1 + design.close() def test_find_and_fix_extra_edges_problem_areas(modeler: Modeler):