--- jupytext: text_representation: extension: .mystnb format_name: myst format_version: 0.13 jupytext_version: 1.19.1 kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 --- # Tools: Using RepairTools to inspect and fix geometry This example demonstrates how to use the ``RepairTools`` class to inspect and repair common geometry issues. The ``RepairTools`` class provides methods for finding and fixing problems such as split edges, extra edges, inexact edges, short edges, duplicate faces, missing faces, small faces, and stitchable faces. The ``RepairTools`` instance is accessible through ``modeler.repair_tools``. It should not be instantiated directly by the user. +++ ## Perform required imports Perform the required imports. ```{code-cell} ipython3 from pathlib import Path import requests from ansys.geometry.core import launch_modeler ``` ## Download example files Download example geometry files that contain known problem areas from the PyAnsys Geometry repository. These files are used to demonstrate how the ``RepairTools`` methods detect and fix real geometry issues. ```{code-cell} ipython3 BASE_URL = ( "https://raw.githubusercontent.com/ansys/pyansys-geometry/main/tests/integration/files/" ) FILES = { "split_edges": "SplitEdgeDesignTest.scdocx", "extra_edges": "ExtraEdgesDesignBefore.scdocx", "inexact_edges": "InExactEdgesBefore.scdocx", "short_edges": "ShortEdgesBefore.scdocx", "duplicate_faces": "DuplicateFacesDesignBefore.scdocx", "missing_faces": "MissingFacesDesignBefore.scdocx", "small_faces": "SmallFaces.scdocx", "stitch_faces": "stitch_before.scdocx", "inspect_repair": "InspectAndRepair01.scdocx", } def download_file(filename): """Download a file from the PyAnsys Geometry repository.""" url = BASE_URL + filename local_path = Path.cwd() / filename response = requests.get(url) response.raise_for_status() local_path.write_bytes(response.content) print(f"Downloaded: {filename}") return local_path file_paths = {key: download_file(name) for key, name in FILES.items()} ``` ## Initialize the modeler ```{code-cell} ipython3 modeler = launch_modeler() print(modeler) ``` ## Find split edges Split edges are edges that are unnecessarily divided into multiple segments. ``find_split_edges()`` detects them. Optional ``angle`` and ``length`` parameters control the detection thresholds. ```{code-cell} ipython3 design = modeler.open_file(file_paths["split_edges"]) split_edge_problems = modeler.repair_tools.find_split_edges(design.bodies) print(f"Number of split edge problem areas found: {len(split_edge_problems)}") ``` ## Fix split edge problem areas Each problem area object returned by the ``find_*`` methods exposes a ``fix()`` method that resolves that specific issue. ```{code-cell} ipython3 for problem in split_edge_problems: result = problem.fix() print(f"Split edge fix successful: {result.success}") # Verify the problem areas are resolved split_edge_problems_after = modeler.repair_tools.find_split_edges(design.bodies) print(f"Split edge problem areas remaining: {len(split_edge_problems_after)}") ``` ## Find extra edges Extra edges are edges that exist inside a face but do not contribute to defining the face boundary. ``find_extra_edges()`` detects them. ```{code-cell} ipython3 design = modeler.open_file(file_paths["extra_edges"]) extra_edge_problems = modeler.repair_tools.find_extra_edges(design.bodies) print(f"Number of extra edge problem areas found: {len(extra_edge_problems)}") ``` ## Fix extra edge problem areas ```{code-cell} ipython3 for problem in extra_edge_problems: result = problem.fix() print(f"Extra edge fix successful: {result.success}") extra_edge_problems_after = modeler.repair_tools.find_extra_edges(design.bodies) print(f"Extra edge problem areas remaining: {len(extra_edge_problems_after)}") ``` ## Find inexact edges Inexact edges are edges whose geometry does not precisely match the underlying surface geometry. ``find_inexact_edges()`` detects them. ```{code-cell} ipython3 design = modeler.open_file(file_paths["inexact_edges"]) inexact_edge_problems = modeler.repair_tools.find_inexact_edges(design.bodies) print(f"Number of inexact edge problem areas found: {len(inexact_edge_problems)}") ``` ## Fix inexact edge problem areas ```{code-cell} ipython3 for problem in inexact_edge_problems: result = problem.fix() print(f"Inexact edge fix successful: {result.success}") inexact_edge_problems_after = modeler.repair_tools.find_inexact_edges(design.bodies) print(f"Inexact edge problem areas remaining: {len(inexact_edge_problems_after)}") ``` ## Find short edges Short edges are edges that are shorter than a given threshold length. ``find_short_edges()`` detects them. Provide a length threshold to control which edges are flagged. ```{code-cell} ipython3 design = modeler.open_file(file_paths["short_edges"]) short_edge_problems = modeler.repair_tools.find_short_edges(design.bodies, 10) print(f"Number of short edge problem areas found: {len(short_edge_problems)}") ``` ## Fix short edge problem areas ```{code-cell} ipython3 for problem in short_edge_problems: result = problem.fix() print(f"Short edge fix successful: {result.success}") short_edge_problems_after = modeler.repair_tools.find_short_edges(design.bodies, 10) print(f"Short edge problem areas remaining: {len(short_edge_problems_after)}") ``` Even though all of the ``fix()`` calls were successful, some designs are unable to fix all problem areas simultaneously. +++ ## Find duplicate faces Duplicate faces are faces that occupy the same region of space. ``find_duplicate_faces()`` detects them. ```{code-cell} ipython3 design = modeler.open_file(file_paths["duplicate_faces"]) duplicate_face_problems = modeler.repair_tools.find_duplicate_faces(design.bodies) print(f"Number of duplicate face problem areas found: {len(duplicate_face_problems)}") ``` ## Fix duplicate face problem areas ```{code-cell} ipython3 for problem in duplicate_face_problems: result = problem.fix() print(f"Duplicate face fix successful: {result.success}") duplicate_face_problems_after = modeler.repair_tools.find_duplicate_faces(design.bodies) print(f"Duplicate face problem areas remaining: {len(duplicate_face_problems_after)}") ``` ## Find missing faces Missing faces represent openings in an otherwise closed solid body. ``find_missing_faces()`` detects them. ```{code-cell} ipython3 design = modeler.open_file(file_paths["missing_faces"]) design.plot() missing_face_problems = modeler.repair_tools.find_missing_faces(design.bodies) print(f"Number of missing face problem areas found: {len(missing_face_problems)}") ``` ## Fix missing face problem areas ```{code-cell} ipython3 for problem in missing_face_problems: result = problem.fix() print(f"Missing face fix successful: {result.success}") missing_face_problems_after = modeler.repair_tools.find_missing_faces(design.bodies) print(f"Missing face problem areas remaining: {len(missing_face_problems_after)}") design.plot() ``` ## Find small faces Small faces are faces that fall below a given area or width threshold. ``find_small_faces()`` detects them. ```{code-cell} ipython3 design = modeler.open_file(file_paths["small_faces"]) design.plot() small_face_problems = modeler.repair_tools.find_small_faces(design.bodies) print(f"Number of small face problem areas found: {len(small_face_problems)}") ``` ## Fix small face problem areas ```{code-cell} ipython3 for problem in small_face_problems: result = problem.fix() print(f"Small face fix successful: {result.success}") small_face_problems_after = modeler.repair_tools.find_small_faces(design.bodies) print(f"Small face problem areas remaining: {len(small_face_problems_after)}") ``` ```{code-cell} ipython3 # Fix the remaining issue small_face_problems_after[0].fix() small_face_problems_after = modeler.repair_tools.find_small_faces(design.bodies) print(f"Small face problem areas remaining: {len(small_face_problems_after)}") design.plot() ``` ## Find stitchable faces Stitchable faces are faces that can be joined together at a shared boundary. ``find_stitch_faces()`` detects them. An optional ``max_distance`` parameter sets the tolerance for coincident boundaries. ```{code-cell} ipython3 design = modeler.open_file(file_paths["stitch_faces"]) stitch_face_problems = modeler.repair_tools.find_stitch_faces(design.bodies) print(f"Number of stitch face problem areas found: {len(stitch_face_problems)}") ``` ## Fix stitch face problem areas ```{code-cell} ipython3 for problem in stitch_face_problems: result = problem.fix() print(f"Stitch face fix successful: {result.success}") print(f" Bodies modified: {len(result.modified_bodies)}") stitch_face_problems_after = modeler.repair_tools.find_stitch_faces(design.bodies) print(f"Stitch face problem areas remaining: {len(stitch_face_problems_after)}") ``` ## Find and fix short edges in one step The ``find_and_fix_*`` convenience methods combine detection and repair into a single call and return a ``RepairToolMessage`` summarizing the outcome. ```{code-cell} ipython3 design = modeler.open_file(file_paths["short_edges"]) result = modeler.repair_tools.find_and_fix_short_edges(design.bodies, 10) print(f"Find-and-fix short edges successful: {result.success}") print(f" Problem areas found: {result.found}") print(f" Problem areas repaired: {result.repaired}") ``` ## Find and fix extra edges in one step ```{code-cell} ipython3 design = modeler.open_file(file_paths["extra_edges"]) result = modeler.repair_tools.find_and_fix_extra_edges(design.bodies) print(f"Find-and-fix extra edges successful: {result.success}") print(f" Problem areas found: {result.found}") print(f" Problem areas repaired: {result.repaired}") ``` ## Find and fix split edges in one step ```{code-cell} ipython3 design = modeler.open_file(file_paths["split_edges"]) result = modeler.repair_tools.find_and_fix_split_edges(design.bodies) print(f"Find-and-fix split edges successful: {result.success}") print(f" Problem areas found: {result.found}") print(f" Problem areas repaired: {result.repaired}") ``` ## Inspect and repair all geometry issues The ``inspect_geometry()`` method returns a detailed list of all detected issues grouped by body. Each entry in the list exposes a ``repair()`` method for fixing that specific issue. The ``repair_geometry()`` method attempts to fix all detected issues automatically with a single call. ```{code-cell} ipython3 design = modeler.open_file(file_paths["inspect_repair"]) # Inspect all geometry issues in the design inspect_results = modeler.repair_tools.inspect_geometry(design.bodies) print(f"Number of bodies with issues: {len(inspect_results)}") for result in inspect_results: print(f" Body: {result.body.name if result.body else 'N/A'}") for issue in result.issues: print(f" [{issue.message_type}] {issue.message}") ``` ```{code-cell} ipython3 # Repair all geometry issues automatically repair_result = modeler.repair_tools.repair_geometry(design.bodies) print(f"Repair geometry successful: {repair_result.success}") # Verify all issues have been resolved inspect_results_after = modeler.repair_tools.inspect_geometry(design.bodies) print(f"Bodies with issues remaining: {len(inspect_results_after)}") ``` ## Close the modeler Close the modeler to free up resources and release the connection. ```{code-cell} ipython3 modeler.close() ```