Skip to content

Commit dc8430a

Browse files
committed
Exposure of detect llogo implementation
Exposure of detect logo implementation. Logo is defined as a problem area described by a list of faces. It is not a list of logs because the detection provides a list of faces without any distinction (other than per body). The problem area can be removed with a fix command or a find and remove can remove them all
1 parent 31c141d commit dc8430a

File tree

3 files changed

+176
-2
lines changed

3 files changed

+176
-2
lines changed

src/ansys/geometry/core/tools/prepare_tools.py

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,24 @@
2626
from google.protobuf.wrappers_pb2 import BoolValue, DoubleValue
2727

2828
from ansys.api.dbu.v0.dbumodels_pb2 import EntityIdentifier
29-
from ansys.api.geometry.v0.models_pb2 import Body as GRPCBody
29+
from ansys.api.geometry.v0.models_pb2 import Body as GRPCBody, FindLogoOptions
3030
from ansys.api.geometry.v0.preparetools_pb2 import (
3131
ExtractVolumeFromEdgeLoopsRequest,
3232
ExtractVolumeFromFacesRequest,
33+
FindLogosRequest,
3334
ShareTopologyRequest,
3435
)
3536
from ansys.api.geometry.v0.preparetools_pb2_grpc import PrepareToolsStub
3637
from ansys.geometry.core.connection import GrpcClient
38+
from ansys.geometry.core.designer.face import SurfaceType
3739
from ansys.geometry.core.errors import protect_grpc
3840
from ansys.geometry.core.misc.auxiliary import (
3941
get_bodies_from_ids,
4042
get_design_from_edge,
4143
get_design_from_face,
4244
)
4345
from ansys.geometry.core.misc.checks import check_type_all_elements_in_iterable, min_backend_version
46+
from ansys.geometry.core.tools.problem_areas import LogoProblemArea
4447
from ansys.geometry.core.tools.repair_tool_message import RepairToolMessage
4548
from ansys.geometry.core.typing import Real
4649

@@ -251,3 +254,96 @@ def enhanced_share_topology(
251254
share_topo_response.repaired,
252255
)
253256
return message
257+
258+
@protect_grpc
259+
@min_backend_version(25, 2, 0)
260+
def find_logos(
261+
self, bodies: list["Body"] = None, min_height: Real = None, max_height: Real = None
262+
) -> "LogoProblemArea":
263+
"""Detect logos in geometry.
264+
265+
Detects logos, using a list of bodies if provided.
266+
The logos are returned as a list of faces.
267+
268+
Parameters
269+
----------
270+
bodies : list[Body], optional
271+
List of bodies where logos should be detected
272+
min_height : real, optional
273+
The minimum height when searching for logos
274+
max_height: real, optional
275+
The minimum height when searching for logos
276+
277+
Returns
278+
-------
279+
Logo problem area
280+
Problem area with logo faces.
281+
"""
282+
from ansys.geometry.core.designer.body import Body
283+
# Verify inputs
284+
if (bodies):
285+
if len(bodies) > 0:
286+
check_type_all_elements_in_iterable(bodies, Body)
287+
288+
body_ids = [] if bodies is None else [body._grpc_id for body in bodies]
289+
find_logo_options = FindLogoOptions()
290+
if min_height:
291+
find_logo_options.min_height = min_height
292+
if max_height:
293+
find_logo_options.max_height = max_height
294+
295+
response = self._prepare_stub.FindLogos(
296+
FindLogosRequest(bodies=body_ids, options=find_logo_options)
297+
)
298+
299+
face_ids=[]
300+
for grpc_face in response.logo_faces:
301+
face_ids.append(grpc_face.id)
302+
return LogoProblemArea(
303+
id = response.id,
304+
grpc_client = self._grpc_client,
305+
face_ids = face_ids
306+
)
307+
308+
309+
@protect_grpc
310+
@min_backend_version(25, 2, 0)
311+
def find_and_remove_logos(
312+
self, bodies: list["Body"] = None, min_height: Real = None, max_height: Real = None
313+
) -> bool:
314+
"""Detect and remove logos in geometry.
315+
316+
Detects and remove logos, using a list of bodies if provided.
317+
318+
Parameters
319+
----------
320+
bodies : list[Body], optional
321+
List of bodies where logos should be detected and removed.
322+
min_height : real, optional
323+
The minimum height when searching for logos
324+
max_height: real, optional
325+
The minimum height when searching for logos
326+
327+
Returns
328+
-------
329+
Boolean value indicating whether the operation was successful.
330+
"""
331+
332+
from ansys.geometry.core.designer.body import Body
333+
# Verify inputs
334+
if (bodies):
335+
if len(bodies) > 0:
336+
check_type_all_elements_in_iterable(bodies, Body)
337+
338+
body_ids = [] if bodies is None else [body._grpc_id for body in bodies]
339+
find_logo_options = FindLogoOptions()
340+
if min_height:
341+
find_logo_options.min_height = min_height
342+
if max_height:
343+
find_logo_options.max_height = max_height
344+
345+
response = self._prepare_stub.FindAndRemoveLogos(
346+
FindLogosRequest(bodies=body_ids, options=find_logo_options)
347+
)
348+
349+
return response.success

src/ansys/geometry/core/tools/problem_areas.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525
from typing import TYPE_CHECKING
2626

2727
from google.protobuf.wrappers_pb2 import Int32Value
28-
28+
from ansys.api.dbu.v0.dbumodels_pb2 import EntityIdentifier
29+
from ansys.api.geometry.v0.preparetools_pb2 import (
30+
RemoveLogoRequest,
31+
)
2932
from ansys.api.geometry.v0.repairtools_pb2 import (
3033
FixAdjustSimplifyRequest,
3134
FixDuplicateFacesRequest,
@@ -39,6 +42,7 @@
3942
FixStitchFacesRequest,
4043
)
4144
from ansys.api.geometry.v0.repairtools_pb2_grpc import RepairToolsStub
45+
from ansys.api.geometry.v0.preparetools_pb2_grpc import PrepareToolsStub
4246
from ansys.geometry.core.connection import GrpcClient
4347
from ansys.geometry.core.errors import protect_grpc
4448
from ansys.geometry.core.misc.auxiliary import (
@@ -71,6 +75,7 @@ def __init__(self, id: str, grpc_client: GrpcClient):
7175
self._id = id
7276
self._grpc_id = Int32Value(value=int(id))
7377
self._repair_stub = RepairToolsStub(grpc_client.channel)
78+
self._prepare_stub = PrepareToolsStub(grpc_client.channel)
7479

7580
@property
7681
def id(self) -> str:
@@ -619,3 +624,45 @@ def fix(self) -> RepairToolMessage:
619624
message = RepairToolMessage(response.result.success, [], [])
620625

621626
return message
627+
628+
629+
class LogoProblemArea(ProblemArea):
630+
"""Represents a logo problem area defined by a list of faces.
631+
632+
Parameters
633+
----------
634+
id : str
635+
Server-defined ID for the problem area.
636+
grpc_client : GrpcClient
637+
Active supporting geometry service instance for design modeling.
638+
faces : list[str]
639+
List of faces defining the logo problem area.
640+
"""
641+
642+
def __init__(self, id: str, grpc_client: GrpcClient, face_ids: list[str]):
643+
"""Initialize a new instance of the logo problem area class."""
644+
super().__init__(id, grpc_client)
645+
646+
self._face_ids = face_ids
647+
648+
@property
649+
def face_ids(self) -> list["str"]:
650+
"""The ids of the faces defining the logos."""
651+
return self._face_ids
652+
653+
@protect_grpc
654+
def fix(self) -> bool:
655+
"""Fix the problem area by deleting the logos.
656+
657+
Returns
658+
-------
659+
message: bool
660+
Message that return whether the operation was successful.
661+
"""
662+
if len(self._face_ids) == 0:
663+
return False
664+
665+
entity_ids=[EntityIdentifier(id=face_id) for face_id in self._face_ids]
666+
response = self._prepare_stub.RemoveLogo(RemoveLogoRequest(face_ids=entity_ids))
667+
668+
return response.success

tests/integration/test_prepare_tools.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,34 @@ def test_enhanced_share_topology(modeler: Modeler):
9696
result = modeler.prepare_tools.enhanced_share_topology(design.bodies, 0.000554167, True)
9797
assert result.found == 14
9898
assert result.repaired == 14
99+
100+
def test_detect_logos(modeler: Modeler):
101+
"""Test logos are detected and deleted."""
102+
design = modeler.open_file(FILES_DIR / "Part1.SLDPRT")
103+
assert len(design.components[0].bodies[2].faces) == 189
104+
result = modeler.prepare_tools.find_logos()
105+
# no logos should be found is max height is not given
106+
assert len(result.face_ids) == 0
107+
result = modeler.prepare_tools.find_logos(max_height=0.005)
108+
assert len(result.face_ids) == 147
109+
success = modeler.prepare_tools.find_and_remove_logos(max_height=0.005)
110+
assert success == True
111+
assert len(design.components[0].bodies[2].faces) == 42
112+
113+
def test_detect_and_fix_logo_as_problem_area(modeler: Modeler):
114+
"""Test logos are detected and deleted as problem area"""
115+
design = modeler.open_file(FILES_DIR / "Part1.SLDPRT")
116+
bodies = []
117+
#test that no issue occurs when no logos are found
118+
bodies.append(design.components[0].bodies[0])
119+
result = modeler.prepare_tools.find_logos(max_height=0.005)
120+
assert len(result.face_ids) == 0
121+
success = result.fix()
122+
assert success == False
123+
bodies = []
124+
bodies.append(design.components[0].bodies[2])
125+
result = modeler.prepare_tools.find_logos(max_height=0.005)
126+
assert len(result.face_ids) == 147
127+
result.fix()
128+
assert success == True
129+
assert len(design.components[0].bodies[2].faces) == 42

0 commit comments

Comments
 (0)