2424from typing import TYPE_CHECKING
2525
2626from ansys .geometry .core .connection import GrpcClient
27- from ansys .geometry .core .errors import protect_grpc
2827from ansys .geometry .core .misc .auxiliary import (
2928 get_bodies_from_ids ,
3029 get_design_from_body ,
3635 check_type_all_elements_in_iterable ,
3736 min_backend_version ,
3837)
38+ from ansys .geometry .core .misc .measurements import Angle , Distance
3939from ansys .geometry .core .tools .check_geometry import GeometryIssue , InspectResult
4040from ansys .geometry .core .tools .problem_areas import (
4141 DuplicateFaceProblemAreas ,
@@ -65,7 +65,6 @@ def __init__(self, grpc_client: GrpcClient, modeler: "Modeler"):
6565 self ._modeler = modeler
6666 self ._grpc_client = grpc_client
6767
68- @protect_grpc
6968 def find_split_edges (
7069 self , bodies : list ["Body" ], angle : Real = 0.0 , length : Real = 0.0
7170 ) -> list [SplitEdgeProblemAreas ]:
@@ -107,7 +106,6 @@ def find_split_edges(
107106 for res in problem_areas_response ["problems" ]
108107 ]
109108
110- @protect_grpc
111109 def find_extra_edges (self , bodies : list ["Body" ]) -> list [ExtraEdgeProblemAreas ]:
112110 """Find the extra edges in the given list of bodies.
113111
@@ -142,7 +140,6 @@ def find_extra_edges(self, bodies: list["Body"]) -> list[ExtraEdgeProblemAreas]:
142140 for res in problem_areas_response ["problems" ]
143141 ]
144142
145- @protect_grpc
146143 def find_inexact_edges (self , bodies : list ["Body" ]) -> list [InexactEdgeProblemAreas ]:
147144 """Find inexact edges in the given list of bodies.
148145
@@ -178,7 +175,6 @@ def find_inexact_edges(self, bodies: list["Body"]) -> list[InexactEdgeProblemAre
178175 for res in problem_areas_response ["problems" ]
179176 ]
180177
181- @protect_grpc
182178 def find_short_edges (
183179 self , bodies : list ["Body" ], length : Real = 0.0
184180 ) -> list [ShortEdgeProblemAreas ]:
@@ -216,7 +212,6 @@ def find_short_edges(
216212 for res in problem_areas_response ["problems" ]
217213 ]
218214
219- @protect_grpc
220215 def find_duplicate_faces (self , bodies : list ["Body" ]) -> list [DuplicateFaceProblemAreas ]:
221216 """Find the duplicate face problem areas.
222217
@@ -251,8 +246,12 @@ def find_duplicate_faces(self, bodies: list["Body"]) -> list[DuplicateFaceProble
251246 for res in problem_areas_response ["problems" ]
252247 ]
253248
254- @protect_grpc
255- def find_missing_faces (self , bodies : list ["Body" ]) -> list [MissingFaceProblemAreas ]:
249+ def find_missing_faces (
250+ self ,
251+ bodies : list ["Body" ],
252+ angle : Angle = None ,
253+ distance : Distance = None ,
254+ )-> list [MissingFaceProblemAreas ]:
256255 """Find the missing faces.
257256
258257 This method find the missing face problem areas and returns a list of missing
@@ -262,6 +261,10 @@ def find_missing_faces(self, bodies: list["Body"]) -> list[MissingFaceProblemAre
262261 ----------
263262 bodies : list[Body]
264263 List of bodies that missing faces are investigated on.
264+ angle : Angle, optional
265+ The minimum angle between faces. By default, None.
266+ distance : Distance, optional
267+ The minimum distance between faces. By default, None.
265268
266269 Returns
267270 -------
@@ -272,7 +275,9 @@ def find_missing_faces(self, bodies: list["Body"]) -> list[MissingFaceProblemAre
272275 return []
273276 body_ids = [body .id for body in bodies ]
274277 problem_areas_response = self ._grpc_client .services .repair_tools .find_missing_faces (
275- faces = body_ids
278+ faces = body_ids ,
279+ angle = angle .value if angle is not None else None ,
280+ distance = distance .value if distance is not None else None ,
276281 )
277282 parent_design = get_design_from_body (bodies [0 ])
278283
@@ -285,7 +290,6 @@ def find_missing_faces(self, bodies: list["Body"]) -> list[MissingFaceProblemAre
285290 for res in problem_areas_response ["problems" ]
286291 ]
287292
288- @protect_grpc
289293 def find_small_faces (self , bodies : list ["Body" ]) -> list [SmallFaceProblemAreas ]:
290294 """Find the small face problem areas.
291295
@@ -320,8 +324,11 @@ def find_small_faces(self, bodies: list["Body"]) -> list[SmallFaceProblemAreas]:
320324 for res in problem_areas_response ["problems" ]
321325 ]
322326
323- @protect_grpc
324- def find_stitch_faces (self , bodies : list ["Body" ]) -> list [StitchFaceProblemAreas ]:
327+ def find_stitch_faces (
328+ self ,
329+ bodies : list ["Body" ],
330+ max_distance : Distance = None ,
331+ ) -> list [StitchFaceProblemAreas ]:
325332 """Return the list of stitch face problem areas.
326333
327334 This method find the stitch face problem areas and returns a list of ids of stitch face
@@ -331,6 +338,8 @@ def find_stitch_faces(self, bodies: list["Body"]) -> list[StitchFaceProblemAreas
331338 ----------
332339 bodies : list[Body]
333340 List of bodies that stitchable faces are investigated on.
341+ max_distance : Distance, optional
342+ Maximum distance between faces. By default, None.
334343
335344 Returns
336345 -------
@@ -339,7 +348,8 @@ def find_stitch_faces(self, bodies: list["Body"]) -> list[StitchFaceProblemAreas
339348 """
340349 body_ids = [body .id for body in bodies ]
341350 problem_areas_response = self ._grpc_client .services .repair_tools .find_stitch_faces (
342- faces = body_ids
351+ faces = body_ids ,
352+ distance = max_distance .value if max_distance is not None else None ,
343353 )
344354 parent_design = get_design_from_body (bodies [0 ])
345355 return [
@@ -351,7 +361,6 @@ def find_stitch_faces(self, bodies: list["Body"]) -> list[StitchFaceProblemAreas
351361 for res in problem_areas_response ["problems" ]
352362 ]
353363
354- @protect_grpc
355364 @min_backend_version (25 , 2 , 0 )
356365 def find_simplify (self , bodies : list ["Body" ]) -> list [UnsimplifiedFaceProblemAreas ]:
357366 """Detect faces in a body that can be simplified.
@@ -385,7 +394,6 @@ def find_simplify(self, bodies: list["Body"]) -> list[UnsimplifiedFaceProblemAre
385394 for res in problem_areas_response ["problems" ]
386395 ]
387396
388- @protect_grpc
389397 @min_backend_version (25 , 2 , 0 )
390398 def find_interferences (
391399 self , bodies : list ["Body" ], cut_smaller_body : bool = False
@@ -435,7 +443,6 @@ def find_interferences(
435443 for res in problem_areas_response ["problems" ]
436444 ]
437445
438- @protect_grpc
439446 @min_backend_version (25 , 2 , 0 )
440447 def find_and_fix_short_edges (
441448 self , bodies : list ["Body" ], length : Real = 0.0 , comprehensive_result : bool = False
@@ -489,7 +496,6 @@ def find_and_fix_short_edges(
489496 )
490497 return message
491498
492- @protect_grpc
493499 @min_backend_version (25 , 2 , 0 )
494500 def find_and_fix_extra_edges (
495501 self , bodies : list ["Body" ], comprehensive_result : bool = False
@@ -540,7 +546,6 @@ def find_and_fix_extra_edges(
540546 )
541547 return message
542548
543- @protect_grpc
544549 @min_backend_version (25 , 2 , 0 )
545550 def find_and_fix_split_edges (
546551 self ,
@@ -602,7 +607,6 @@ def find_and_fix_split_edges(
602607 )
603608 return message
604609
605- @protect_grpc
606610 @min_backend_version (25 , 2 , 0 )
607611 def find_and_fix_simplify (
608612 self , bodies : list ["Body" ], comprehensive_result : bool = False
@@ -652,6 +656,73 @@ def find_and_fix_simplify(
652656 )
653657 return message
654658
659+ @min_backend_version (25 , 2 , 0 )
660+ def find_and_fix_stitch_faces (
661+ self ,
662+ bodies : list ["Body" ],
663+ max_distance : Distance = None ,
664+ allow_multiple_bodies : bool = False ,
665+ maintain_components : bool = True ,
666+ check_for_coincidence : bool = False ,
667+ comprehensive_result : bool = False ,
668+ ) -> RepairToolMessage :
669+ """Find and fix the stitch face problem areas.
670+
671+ Parameters
672+ ----------
673+ bodies : list[Body]
674+ List of bodies that stitchable faces are investigated on.
675+ max_distance : Real, optional
676+ The maximum distance between faces to be stitched.
677+ By default, 0.0001.
678+ allow_multiple_bodies : bool, optional
679+ Whether to allow multiple bodies in the result.
680+ By default, False.
681+ maintain_components : bool, optional
682+ Whether to stitch bodies within the components.
683+ By default, True.
684+ check_for_coincidence : bool, optional
685+ Whether coincidence surfaces are searched.
686+ By default, False.
687+ comprehensive_result : bool, optional
688+ Whether to fix all problem areas individually.
689+ By default, False.
690+
691+ Returns
692+ -------
693+ RepairToolMessage
694+ Message containing number of problem areas found/fixed, created and/or modified bodies.
695+
696+ Notes
697+ -----
698+ This method finds the stitchable faces and fixes them.
699+ """
700+ from ansys .geometry .core .designer .body import Body
701+
702+ check_type_all_elements_in_iterable (bodies , Body )
703+
704+ body_ids = [body .id for body in bodies ]
705+
706+ response = self ._grpc_client .services .repair_tools .find_and_fix_stitch_faces (
707+ body_ids = body_ids ,
708+ max_distance = max_distance .value if max_distance is not None else None ,
709+ allow_multiple_bodies = allow_multiple_bodies ,
710+ maintain_components = maintain_components ,
711+ check_for_coincidence = check_for_coincidence ,
712+ comprehensive_result = comprehensive_result ,
713+ )
714+
715+ parent_design = get_design_from_body (bodies [0 ])
716+ parent_design ._update_design_inplace ()
717+ message = RepairToolMessage (
718+ response .get ("success" ),
719+ response .get ("created_bodies_monikers" ),
720+ response .get ("modified_bodies_monikers" ),
721+ response .get ("found" ),
722+ response .get ("repaired" ),
723+ )
724+ return message
725+
655726 def inspect_geometry (self , bodies : list ["Body" ] = None ) -> list [InspectResult ]:
656727 """Return a list of geometry issues organized by body.
657728
@@ -715,7 +786,6 @@ def __create_issues_from_response(
715786 issues .append (geometry_issue )
716787 return issues
717788
718- @protect_grpc
719789 @min_backend_version (25 , 2 , 0 )
720790 def repair_geometry (self , bodies : list ["Body" ] = None ) -> RepairToolMessage :
721791 """Attempt to repair the geometry for the given bodies.
0 commit comments