Skip to content

feat: logo detection #1819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 83 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
ed028b0
ci: simplify ci for blitz
RobPasMue Jan 2, 2025
54f3b60
ci: simplify ci for blitz
RobPasMue Jan 2, 2025
4f74754
Merge branch 'blitz' of https://github.com/ansys/pyansys-geometry int…
RobPasMue Jan 13, 2025
e4955c0
feat: create a fillet on an edge/face (#1621)
jonahrb Jan 13, 2025
e79ef3b
feat: create a full fillet between multiple faces (#1623)
jonahrb Jan 13, 2025
5201f65
feat: extrude existing faces, setup face offset relationships (#1628)
jonahrb Jan 14, 2025
6b57225
feat: extrude existing edges to create surface bodies (#1638)
jonahrb Jan 15, 2025
0b26b26
build: bump ansys-api-geometry in blitz branch
RobPasMue Jan 16, 2025
72049ba
build: using ansys-api-geometry 0.4.29
RobPasMue Jan 17, 2025
7c25285
build: bump ansys-api-geometry in blitz branch
RobPasMue Jan 17, 2025
6315fa1
feat: create and modify linear patterns (#1641)
jonahrb Jan 17, 2025
51b8797
feat: body suppression state (#1643)
umutsoysalansys Jan 17, 2025
b20f1c7
feat: surface body from trimmed curves (#1650)
jonahrb Jan 17, 2025
4993883
test: add more find and fix tests for repair tools (#1645)
RyanJWard Jan 17, 2025
c917586
ci: simplify ci for blitz
RobPasMue Jan 2, 2025
4b71674
feat: create a fillet on an edge/face (#1621)
jonahrb Jan 13, 2025
4add452
feat: create a full fillet between multiple faces (#1623)
jonahrb Jan 13, 2025
17454c9
feat: extrude existing faces, setup face offset relationships (#1628)
jonahrb Jan 14, 2025
e89d79d
feat: extrude existing edges to create surface bodies (#1638)
jonahrb Jan 15, 2025
b700d7f
feat: create and modify linear patterns (#1641)
jonahrb Jan 17, 2025
6f84751
feat: body suppression state (#1643)
umutsoysalansys Jan 17, 2025
e429375
feat: surface body from trimmed curves (#1650)
jonahrb Jan 17, 2025
ec8d992
test: add more find and fix tests for repair tools (#1645)
RyanJWard Jan 17, 2025
b55f379
Merge branch 'blitz' of https://github.com/ansys/pyansys-geometry int…
RobPasMue Jan 20, 2025
0ebf4b2
feat: create circular and fill patterns (#1653)
jonahrb Jan 20, 2025
85dcb8b
feat: rename object (#1648)
jacobrkerstetter Jan 20, 2025
034e060
feat: parameters refurbished (#1647)
umutsoysalansys Jan 21, 2025
65f43c4
feat: replace face (#1664)
jacobrkerstetter Jan 21, 2025
0e37d41
feat: enable get/set persistent ids for stride import/export (#1671)
MikeJanes Jan 21, 2025
89382c9
feat: revolve faces a set distance, up to another object, or by a hel…
jonahrb Jan 21, 2025
212132a
feat: find fix simplify (#1661)
jacobrkerstetter Jan 21, 2025
0beb35d
test: Add some new tests (#1670)
RyanJWard Jan 21, 2025
8397962
feat: add split body and tests (#1669)
david-gorman Jan 22, 2025
546c73b
ci: ensure design is closed on test exit (#1680)
RobPasMue Jan 23, 2025
0b08f8c
build: bump ansys api geometry from 0.4.30 to 0.4.32 (#1677)
b-matteo Jan 23, 2025
693590c
feat: find and fix edge methods (#1672)
mlkaplan36 Jan 23, 2025
3fa977e
feat: shell methods (#1673)
jacobrkerstetter Jan 24, 2025
edac0da
feat: interference repair tool (#1633)
smereu Jan 24, 2025
d520914
fix: filter set export id to only CoreService based backends (#1685)
b-matteo Jan 24, 2025
2f32019
feat: get assigned material (#1684)
jacobrkerstetter Jan 24, 2025
f5e93d6
test: add unit tests for 3 repair tools (#1683)
mlkaplan36 Jan 27, 2025
f746d51
feat: implementation of NURBS curves (#1675)
RobPasMue Jan 27, 2025
9105449
fix: cleanup unsupported module (#1690)
RobPasMue Jan 27, 2025
ab39ca0
feat: matrix rotation and translation (#1689)
umutsoysalansys Jan 28, 2025
bb11e2f
Merge branch 'main' into blitz
RobPasMue Jan 28, 2025
1bb39e5
fix: issues with tests
RobPasMue Jan 28, 2025
78bde4c
feat: export and download stride format (#1698)
b-matteo Jan 28, 2025
6cda8d6
feat: commands for merge and intersect (#1665)
smereu Jan 28, 2025
5524957
ci: revert workflow modifications
RobPasMue Jan 29, 2025
aaa41a9
Merge branch 'main' into blitz
RobPasMue Jan 29, 2025
6b1622a
chore: adding changelog file 1701.added.md [dependabot-skip]
pyansys-ci-bot Jan 29, 2025
4a9dc2d
fix: tech review fixes for blitz branch (#1703)
RobPasMue Jan 29, 2025
f256eea
fix: url build for assets
RobPasMue Jan 29, 2025
fccaa24
Merge branch 'main' into blitz
RobPasMue Jan 29, 2025
4041bd4
fix: ref to read_existing_design in docs
RobPasMue Jan 29, 2025
4044462
Merge branch 'blitz' of https://github.com/ansys/pyansys-geometry int…
RobPasMue Jan 29, 2025
97eb31a
chore: update CHANGELOG for v0.9.0 (#1753)
pyansys-ci-bot Feb 17, 2025
b827101
ci: simplify blitz ci
RobPasMue Mar 10, 2025
1547839
Merge branch 'main' of https://github.com/ansys/pyansys-geometry
smereu Mar 10, 2025
31c141d
Merge branch 'blitz' of https://github.com/ansys/pyansys-geometry int…
smereu Mar 10, 2025
dc8430a
Exposure of detect llogo implementation
smereu Mar 12, 2025
b261533
chore: auto fixes from pre-commit hooks
pre-commit-ci[bot] Mar 12, 2025
f4577de
clean-up from precommit
smereu Mar 12, 2025
6e1d0e7
ci: simplify blitz ci
RobPasMue Mar 10, 2025
c01276f
fix: translating sketch issues when using a custom default unit (#1808)
RobPasMue Mar 10, 2025
b10fb50
feat: matrix helper methods (#1806)
umutsoysalansys Mar 11, 2025
eb8b206
fix: edge start and end were not being mapped correctly (#1816)
RobPasMue Mar 11, 2025
9389ba5
ci: fix ci/cd
RobPasMue Mar 12, 2025
3bc7c02
Merge branch 'blitz' into feat/logo-detection
RobPasMue Mar 12, 2025
d7574c3
docs: remove changelog fragments
RobPasMue Mar 12, 2025
b8af7f3
chore: adding changelog file 1819.added.md [dependabot-skip]
pyansys-ci-bot Mar 12, 2025
c2d7175
fix: pre-commit
RobPasMue Mar 12, 2025
fa8ca72
Merge branch 'feat/logo-detection' of https://github.com/ansys/pyansy…
RobPasMue Mar 12, 2025
e07aeb3
ci: simplify blitz ci
RobPasMue Mar 10, 2025
4e2eeb3
fix: translating sketch issues when using a custom default unit (#1808)
RobPasMue Mar 10, 2025
22bb08f
feat: matrix helper methods (#1806)
umutsoysalansys Mar 11, 2025
5515312
fix: edge start and end were not being mapped correctly (#1816)
RobPasMue Mar 11, 2025
ce21ad6
ci: use proper runner
RobPasMue Mar 12, 2025
47202cf
Merge branch 'blitz' into feat/logo-detection
RobPasMue Mar 12, 2025
2703db6
Merge branch 'feat/logo-detection' of https://github.com/ansys/pyansy…
smereu Mar 27, 2025
4d32d26
Merge branch 'main' into feat/logo-detection
smereu Mar 27, 2025
ef9bc01
Merge remote-tracking branch 'origin/main' into feat/logo-detection
smereu Mar 27, 2025
5bc7f46
chore: auto fixes from pre-commit hooks
pre-commit-ci[bot] Mar 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
492 changes: 43 additions & 449 deletions .github/workflows/ci_cd.yml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions doc/changelog.d/1753.maintenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
update CHANGELOG for v0.9.0
1 change: 1 addition & 0 deletions doc/changelog.d/1806.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
matrix helper methods
1 change: 1 addition & 0 deletions doc/changelog.d/1808.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
translating sketch issues when using a custom default unit
1 change: 1 addition & 0 deletions doc/changelog.d/1816.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
edge start and end were not being mapped correctly
1 change: 1 addition & 0 deletions doc/changelog.d/1819.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
logo detection
92 changes: 91 additions & 1 deletion src/ansys/geometry/core/tools/prepare_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from google.protobuf.wrappers_pb2 import BoolValue, DoubleValue

from ansys.api.dbu.v0.dbumodels_pb2 import EntityIdentifier
from ansys.api.geometry.v0.models_pb2 import Body as GRPCBody, Face as GRPCFace
from ansys.api.geometry.v0.models_pb2 import Body as GRPCBody, Face as GRPCFace, FindLogoOptions
from ansys.api.geometry.v0.preparetools_pb2 import (
ExtractVolumeFromEdgeLoopsRequest,
ExtractVolumeFromFacesRequest,
Expand All @@ -42,6 +42,7 @@
get_design_from_face,
)
from ansys.geometry.core.misc.checks import check_type_all_elements_in_iterable, min_backend_version
from ansys.geometry.core.tools.problem_areas import LogoProblemArea
from ansys.geometry.core.tools.repair_tool_message import RepairToolMessage
from ansys.geometry.core.typing import Real

Expand Down Expand Up @@ -295,3 +296,92 @@ def enhanced_share_topology(
share_topo_response.repaired,
)
return message

@protect_grpc
@min_backend_version(25, 2, 0)
def find_logos(
self, bodies: list["Body"] = None, min_height: Real = None, max_height: Real = None
) -> "LogoProblemArea":
"""Detect logos in geometry.

Detects logos, using a list of bodies if provided.
The logos are returned as a list of faces.

Parameters
----------
bodies : list[Body], optional
List of bodies where logos should be detected
min_height : real, optional
The minimum height when searching for logos
max_height: real, optional
The minimum height when searching for logos

Returns
-------
Logo problem area
Problem area with logo faces.
"""
from ansys.geometry.core.designer.body import Body

# Verify inputs
if bodies:
if len(bodies) > 0:
check_type_all_elements_in_iterable(bodies, Body)

body_ids = [] if bodies is None else [body._grpc_id for body in bodies]
find_logo_options = FindLogoOptions()
if min_height:
find_logo_options.min_height = min_height
if max_height:
find_logo_options.max_height = max_height

response = self._prepare_stub.FindLogos(
FindLogosRequest(bodies=body_ids, options=find_logo_options)
)

face_ids = []
for grpc_face in response.logo_faces:
face_ids.append(grpc_face.id)
return LogoProblemArea(id=response.id, grpc_client=self._grpc_client, face_ids=face_ids)

@protect_grpc
@min_backend_version(25, 2, 0)
def find_and_remove_logos(
self, bodies: list["Body"] = None, min_height: Real = None, max_height: Real = None
) -> bool:
"""Detect and remove logos in geometry.

Detects and remove logos, using a list of bodies if provided.

Parameters
----------
bodies : list[Body], optional
List of bodies where logos should be detected and removed.
min_height : real, optional
The minimum height when searching for logos
max_height: real, optional
The minimum height when searching for logos

Returns
-------
Boolean value indicating whether the operation was successful.
"""
from ansys.geometry.core.designer.body import Body

# Verify inputs
if bodies:
if len(bodies) > 0:
check_type_all_elements_in_iterable(bodies, Body)

body_ids = [] if bodies is None else [body._grpc_id for body in bodies]
find_logo_options = FindLogoOptions()
if min_height:
find_logo_options.min_height = min_height
if max_height:
find_logo_options.max_height = max_height

response = self._prepare_stub.FindAndRemoveLogos(
FindLogosRequest(bodies=body_ids, options=find_logo_options)
)

return response.success
48 changes: 48 additions & 0 deletions src/ansys/geometry/core/tools/problem_areas.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@

from google.protobuf.wrappers_pb2 import Int32Value

from ansys.api.dbu.v0.dbumodels_pb2 import EntityIdentifier
from ansys.api.geometry.v0.preparetools_pb2 import (
RemoveLogoRequest,
)
from ansys.api.geometry.v0.preparetools_pb2_grpc import PrepareToolsStub
from ansys.api.geometry.v0.repairtools_pb2 import (
FixAdjustSimplifyRequest,
FixDuplicateFacesRequest,
Expand Down Expand Up @@ -71,6 +76,7 @@ def __init__(self, id: str, grpc_client: GrpcClient):
self._id = id
self._grpc_id = Int32Value(value=int(id))
self._repair_stub = RepairToolsStub(grpc_client.channel)
self._prepare_stub = PrepareToolsStub(grpc_client.channel)

@property
def id(self) -> str:
Expand Down Expand Up @@ -619,3 +625,45 @@ def fix(self) -> RepairToolMessage:
message = RepairToolMessage(response.result.success, [], [])

return message


class LogoProblemArea(ProblemArea):
"""Represents a logo problem area defined by a list of faces.

Parameters
----------
id : str
Server-defined ID for the problem area.
grpc_client : GrpcClient
Active supporting geometry service instance for design modeling.
faces : list[str]
List of faces defining the logo problem area.
"""

def __init__(self, id: str, grpc_client: GrpcClient, face_ids: list[str]):
"""Initialize a new instance of the logo problem area class."""
super().__init__(id, grpc_client)

self._face_ids = face_ids

@property
def face_ids(self) -> list["str"]:
"""The ids of the faces defining the logos."""
return self._face_ids

@protect_grpc
def fix(self) -> bool:
"""Fix the problem area by deleting the logos.

Returns
-------
message: bool
Message that return whether the operation was successful.
"""
if len(self._face_ids) == 0:
return False

entity_ids = [EntityIdentifier(id=face_id) for face_id in self._face_ids]
response = self._prepare_stub.RemoveLogo(RemoveLogoRequest(face_ids=entity_ids))

return response.success
40 changes: 40 additions & 0 deletions tests/integration/test_design_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,46 @@
from .conftest import FILES_DIR, IMPORT_FILES_DIR


def _create_flat_design(modeler: Modeler) -> Design:
"""Create a demo design for the tests."""
modeler.create_design("Demo")

design_name = "DemoFlatDesign"
design = modeler.create_design(design_name)

# Create a car
comp1 = design.add_component("A")
wheel1 = design.add_component("Wheel1")

# Create car base frame
sketch = Sketch().box(Point2D([5, 10]), 10, 20)
design.add_component("Base").extrude_sketch("BaseBody", sketch, 5)

# Create first wheel
sketch = Sketch(Plane(direction_x=Vector3D([0, 1, 0]), direction_y=Vector3D([0, 0, 1])))
sketch.circle(Point2D([0, 0]), 5)
wheel1.extrude_sketch("Wheel", sketch, -5)

# Create 3 other wheels and move them into position
rotation_origin = Point3D([0, 0, 0])
rotation_direction = UnitVector3D([0, 0, 1])

wheel2 = design.add_component("Wheel2", wheel1)
wheel2.modify_placement(Vector3D([0, 20, 0]))

wheel3 = design.add_component("Wheel3", wheel1)
wheel3.modify_placement(Vector3D([10, 0, 0]), rotation_origin, rotation_direction, np.pi)

wheel4 = design.add_component("Wheel4", wheel1)
wheel4.modify_placement(Vector3D([10, 20, 0]), rotation_origin, rotation_direction, np.pi)

# Create top of car - applies to BOTH cars
sketch = Sketch(Plane(Point3D([0, 5, 5]))).box(Point2D([5, 2.5]), 10, 5)
comp1.extrude_sketch("Top", sketch, 5)

return design


def _create_flat_design(modeler: Modeler) -> Design:
"""Create a demo design for the tests."""
modeler.create_design("Demo")
Expand Down
33 changes: 33 additions & 0 deletions tests/integration/test_prepare_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,36 @@ def test_enhanced_share_topology(modeler: Modeler):
result = modeler.prepare_tools.enhanced_share_topology(design.bodies, 0.000554167, True)
assert result.found == 14
assert result.repaired == 14


def test_detect_logos(modeler: Modeler):
"""Test logos are detected and deleted."""
design = modeler.open_file(FILES_DIR / "Part1.SLDPRT")
assert len(design.components[0].bodies[2].faces) == 189
result = modeler.prepare_tools.find_logos()
# no logos should be found is max height is not given
assert len(result.face_ids) == 0
result = modeler.prepare_tools.find_logos(max_height=0.005)
assert len(result.face_ids) == 147
success = modeler.prepare_tools.find_and_remove_logos(max_height=0.005)
assert success is True
assert len(design.components[0].bodies[2].faces) == 42


def test_detect_and_fix_logo_as_problem_area(modeler: Modeler):
"""Test logos are detected and deleted as problem area"""
design = modeler.open_file(FILES_DIR / "Part1.SLDPRT")
bodies = []
# test that no issue occurs when no logos are found
bodies.append(design.components[0].bodies[0])
result = modeler.prepare_tools.find_logos(max_height=0.005)
assert len(result.face_ids) == 0
success = result.fix()
assert success is False
bodies = []
bodies.append(design.components[0].bodies[2])
result = modeler.prepare_tools.find_logos(max_height=0.005)
assert len(result.face_ids) == 147
result.fix()
assert success is True
assert len(design.components[0].bodies[2].faces) == 42
Loading