Skip to content

Commit 420a518

Browse files
committed
Detect logo functionality
Detect logo and remove logos functionality
1 parent 5a48878 commit 420a518

File tree

4 files changed

+174
-1
lines changed

4 files changed

+174
-1
lines changed

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

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@
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, Face as GRPCFace
29+
from ansys.api.geometry.v0.models_pb2 import Body as GRPCBody, Face as GRPCFace, FindLogoOptions
3030
from ansys.api.geometry.v0.preparetools_pb2 import (
3131
ExtractVolumeFromEdgeLoopsRequest,
3232
ExtractVolumeFromFacesRequest,
33+
FindLogosRequest,
3334
RemoveRoundsRequest,
3435
ShareTopologyRequest,
3536
)
@@ -42,6 +43,7 @@
4243
get_design_from_face,
4344
)
4445
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
4547
from ansys.geometry.core.tools.repair_tool_message import RepairToolMessage
4648
from ansys.geometry.core.typing import Real
4749

@@ -295,3 +297,93 @@ def enhanced_share_topology(
295297
share_topo_response.repaired,
296298
)
297299
return message
300+
301+
@protect_grpc
302+
@min_backend_version(25, 2, 0)
303+
def find_logos(
304+
self, bodies: list["Body"] = None, min_height: Real = None, max_height: Real = None
305+
) -> "LogoProblemArea":
306+
"""Detect logos in geometry.
307+
308+
Detects logos, using a list of bodies if provided.
309+
The logos are returned as a list of faces.
310+
311+
Parameters
312+
----------
313+
bodies : list[Body], optional
314+
List of bodies where logos should be detected
315+
min_height : real, optional
316+
The minimum height when searching for logos
317+
max_height: real, optional
318+
The minimum height when searching for logos
319+
320+
Returns
321+
-------
322+
Logo problem area
323+
324+
Problem area with logo faces.
325+
"""
326+
from ansys.geometry.core.designer.body import Body
327+
328+
# Verify inputs
329+
if bodies:
330+
if len(bodies) > 0:
331+
check_type_all_elements_in_iterable(bodies, Body)
332+
333+
body_ids = [] if bodies is None else [body._grpc_id for body in bodies]
334+
find_logo_options = FindLogoOptions()
335+
if min_height:
336+
find_logo_options.min_height = min_height
337+
if max_height:
338+
find_logo_options.max_height = max_height
339+
340+
response = self._prepare_stub.FindLogos(
341+
FindLogosRequest(bodies=body_ids, options=find_logo_options)
342+
)
343+
344+
face_ids = []
345+
for grpc_face in response.logo_faces:
346+
face_ids.append(grpc_face.id)
347+
return LogoProblemArea(id=response.id, grpc_client=self._grpc_client, face_ids=face_ids)
348+
349+
@protect_grpc
350+
@min_backend_version(25, 2, 0)
351+
def find_and_remove_logos(
352+
self, bodies: list["Body"] = None, min_height: Real = None, max_height: Real = None
353+
) -> bool:
354+
"""Detect and remove logos in geometry.
355+
356+
Detects and remove logos, using a list of bodies if provided.
357+
358+
Parameters
359+
----------
360+
bodies : list[Body], optional
361+
List of bodies where logos should be detected and removed.
362+
min_height : real, optional
363+
The minimum height when searching for logos
364+
max_height: real, optional
365+
The minimum height when searching for logos
366+
367+
Returns
368+
-------
369+
Boolean value indicating whether the operation was successful.
370+
"""
371+
from ansys.geometry.core.designer.body import Body
372+
373+
# Verify inputs
374+
if bodies:
375+
if len(bodies) > 0:
376+
check_type_all_elements_in_iterable(bodies, Body)
377+
378+
body_ids = [] if bodies is None else [body._grpc_id for body in bodies]
379+
find_logo_options = FindLogoOptions()
380+
if min_height:
381+
find_logo_options.min_height = min_height
382+
if max_height:
383+
find_logo_options.max_height = max_height
384+
385+
response = self._prepare_stub.FindAndRemoveLogos(
386+
FindLogosRequest(bodies=body_ids, options=find_logo_options)
387+
)
388+
389+
return response.success

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626

2727
from google.protobuf.wrappers_pb2 import Int32Value
2828

29+
from ansys.api.dbu.v0.dbumodels_pb2 import EntityIdentifier
30+
from ansys.api.geometry.v0.preparetools_pb2 import (
31+
RemoveLogoRequest,
32+
)
33+
from ansys.api.geometry.v0.preparetools_pb2_grpc import PrepareToolsStub
2934
from ansys.api.geometry.v0.repairtools_pb2 import (
3035
FixAdjustSimplifyRequest,
3136
FixDuplicateFacesRequest,
@@ -71,6 +76,7 @@ def __init__(self, id: str, grpc_client: GrpcClient):
7176
self._id = id
7277
self._grpc_id = Int32Value(value=int(id))
7378
self._repair_stub = RepairToolsStub(grpc_client.channel)
79+
self._prepare_stub = PrepareToolsStub(grpc_client.channel)
7480

7581
@property
7682
def id(self) -> str:
@@ -619,3 +625,45 @@ def fix(self) -> RepairToolMessage:
619625
message = RepairToolMessage(response.result.success, [], [])
620626

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

tests/integration/test_prepare_tools.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,36 @@ def test_enhanced_share_topology(modeler: Modeler):
112112
result = modeler.prepare_tools.enhanced_share_topology(design.bodies, 0.000554167, True)
113113
assert result.found == 14
114114
assert result.repaired == 14
115+
116+
117+
def test_detect_logos(modeler: Modeler):
118+
"""Test logos are detected and deleted."""
119+
design = modeler.open_file(FILES_DIR / "Part1.SLDPRT")
120+
assert len(design.components[0].bodies[2].faces) == 189
121+
result = modeler.prepare_tools.find_logos()
122+
# no logos should be found is max height is not given
123+
assert len(result.face_ids) == 0
124+
result = modeler.prepare_tools.find_logos(max_height=0.005)
125+
assert len(result.face_ids) == 147
126+
success = modeler.prepare_tools.find_and_remove_logos(max_height=0.005)
127+
assert success is True
128+
assert len(design.components[0].bodies[2].faces) == 42
129+
130+
131+
def test_detect_and_fix_logo_as_problem_area(modeler: Modeler):
132+
"""Test logos are detected and deleted as problem area"""
133+
design = modeler.open_file(FILES_DIR / "Part1.SLDPRT")
134+
bodies = []
135+
# test that no issue occurs when no logos are found
136+
bodies.append(design.components[0].bodies[0])
137+
result = modeler.prepare_tools.find_logos(bodies, max_height=0.005)
138+
assert len(result.face_ids) == 0
139+
success = result.fix()
140+
assert success is True
141+
bodies = []
142+
bodies.append(design.components[0].bodies[2])
143+
result = modeler.prepare_tools.find_logos(bodies, max_height=0.005)
144+
assert len(result.face_ids) == 147
145+
result.fix()
146+
assert success is False
147+
assert len(design.components[0].bodies[2].faces) == 42

0 commit comments

Comments
 (0)