Skip to content

Commit f9806df

Browse files
Merge branch 'main' into feat/loft_with_guides
2 parents 95cbf89 + 57587fa commit f9806df

File tree

13 files changed

+206
-17
lines changed

13 files changed

+206
-17
lines changed

.github/workflows/ci_cd.yml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
contents: write
4040
pull-requests: write
4141
steps:
42-
- uses: ansys/actions/doc-deploy-changelog@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
42+
- uses: ansys/actions/doc-deploy-changelog@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
4343
with:
4444
token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }}
4545
bot-user: ${{ secrets.PYANSYS_CI_BOT_USERNAME }}
@@ -49,7 +49,7 @@ jobs:
4949
name: Vulnerabilities
5050
runs-on: ubuntu-latest
5151
steps:
52-
- uses: ansys/actions/check-vulnerabilities@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
52+
- uses: ansys/actions/check-vulnerabilities@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
5353
with:
5454
python-version: ${{ env.MAIN_PYTHON_VERSION }}
5555
python-package-name: ${{ env.PACKAGE_NAME }}
@@ -62,7 +62,7 @@ jobs:
6262
runs-on: ubuntu-latest
6363
steps:
6464
- name: Check commit name
65-
uses: ansys/actions/check-pr-title@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
65+
uses: ansys/actions/check-pr-title@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
6666
with:
6767
token: ${{ secrets.GITHUB_TOKEN }}
6868

@@ -71,7 +71,7 @@ jobs:
7171
runs-on: ubuntu-latest
7272
steps:
7373
- name: PyAnsys documentation style checks
74-
uses: ansys/actions/doc-style@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
74+
uses: ansys/actions/doc-style@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
7575
with:
7676
token: ${{ secrets.GITHUB_TOKEN }}
7777

@@ -90,7 +90,7 @@ jobs:
9090
os: macos-latest
9191
steps:
9292
- name: Build wheelhouse and perform smoke test
93-
uses: ansys/actions/build-wheelhouse@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
93+
uses: ansys/actions/build-wheelhouse@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
9494
with:
9595
library-name: ${{ env.PACKAGE_NAME }}
9696
operating-system: ${{ matrix.os }}
@@ -102,7 +102,7 @@ jobs:
102102
runs-on: ubuntu-latest
103103
steps:
104104
- name: PyAnsys documentation style checks
105-
uses: ansys/actions/docker-style@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
105+
uses: ansys/actions/docker-style@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
106106
with:
107107
directory: docker
108108
recursive: true
@@ -346,7 +346,7 @@ jobs:
346346
docker run --detach --name ${{ env.GEO_CONT_NAME }} -e LICENSE_SERVER=${{ env.ANSRV_GEO_LICENSE_SERVER }} -p ${{ env.ANSRV_GEO_PORT }}:50051 ${{ env.ANSRV_GEO_IMAGE_DOCS_TAG }} ${{ secrets.TRANSPORT_MODE_SELECTION }}
347347
348348
- name: Run Ansys documentation building action
349-
uses: ansys/actions/doc-build@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
349+
uses: ansys/actions/doc-build@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
350350
with:
351351
python-version: ${{ env.MAIN_PYTHON_VERSION }}
352352
add-pdf-html-docs-as-assets: true
@@ -432,7 +432,7 @@ jobs:
432432

433433
- name: Run pytest
434434
if: env.SKIP_UNSTABLE == 'false'
435-
uses: ansys/actions/tests-pytest@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
435+
uses: ansys/actions/tests-pytest@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
436436
env:
437437
ALLOW_PLOTTING: true
438438
with:
@@ -640,7 +640,7 @@ jobs:
640640
id-token: write
641641
steps:
642642
- name: Build library source and wheel artifacts
643-
uses: ansys/actions/build-library@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
643+
uses: ansys/actions/build-library@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
644644
with:
645645
library-name: ${{ env.PACKAGE_NAME }}
646646
python-version: ${{ env.MAIN_PYTHON_VERSION }}
@@ -871,7 +871,7 @@ jobs:
871871
restore-keys: pyvista-image-cache-${{ runner.os }}-v-${{ env.RESET_IMAGE_CACHE }}
872872

873873
- name: Run pytest
874-
uses: ansys/actions/tests-pytest@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
874+
uses: ansys/actions/tests-pytest@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
875875
env:
876876
ALLOW_PLOTTING: true
877877
with:
@@ -912,7 +912,7 @@ jobs:
912912
contents: write
913913
steps:
914914
- name: Release to GitHub
915-
uses: ansys/actions/release-github@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
915+
uses: ansys/actions/release-github@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
916916
with:
917917
token: ${{ secrets.GITHUB_TOKEN }}
918918
library-name: ${{ env.PACKAGE_NAME }}
@@ -952,7 +952,7 @@ jobs:
952952
needs: [package]
953953
steps:
954954
- name: Deploy the latest documentation
955-
uses: ansys/actions/doc-deploy-dev@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
955+
uses: ansys/actions/doc-deploy-dev@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
956956
with:
957957
cname: ${{ env.DOCUMENTATION_CNAME }}
958958
token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }}
@@ -966,7 +966,7 @@ jobs:
966966
needs: [release, release-pypi]
967967
steps:
968968
- name: Deploy the stable documentation
969-
uses: ansys/actions/doc-deploy-stable@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
969+
uses: ansys/actions/doc-deploy-stable@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
970970
with:
971971
cname: ${{ env.DOCUMENTATION_CNAME }}
972972
token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }}
@@ -983,7 +983,7 @@ jobs:
983983
pull-requests: write
984984
steps:
985985
- name: Automerge PRs
986-
uses: ansys/actions/hk-automerge-prs@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
986+
uses: ansys/actions/hk-automerge-prs@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
987987
with:
988988
approver: ${{ secrets.PYANSYS_CI_BOT_USERNAME }}
989989
approver-token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }}

.github/workflows/docker_cleanup.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
steps:
2323

2424
- name: "Perform versions cleanup - except certain tags"
25-
uses: ansys/actions/hk-package-clean-except@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
25+
uses: ansys/actions/hk-package-clean-except@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
2626
with:
2727
package-name: 'geometry'
2828
token: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/label.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ jobs:
106106
pull-requests: write
107107
runs-on: ubuntu-latest
108108
steps:
109-
- uses: ansys/actions/doc-changelog@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
109+
- uses: ansys/actions/doc-changelog@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
110110
with:
111111
token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }}
112112
use-conventional-commits: true

.github/workflows/nightly_docker_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ jobs:
221221
uses: pyvista/setup-headless-display-action@7d84ae825e6d9297a8e99bdbbae20d1b919a0b19 # v4.2
222222

223223
- name: Run pytest
224-
uses: ansys/actions/tests-pytest@e0de7dd89b2a4c100f74327666d5521cfda17950 # v10.1.1
224+
uses: ansys/actions/tests-pytest@9de5aa715cf3c98a237b08e1a308c08599223c42 # v10.1.2
225225
env:
226226
ALLOW_PLOTTING: true
227227
with:

doc/changelog.d/2232.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Helix detection
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Bump ansys/actions from 10.1.1 to 10.1.2 in the actions group

src/ansys/geometry/core/_grpc/_services/base/prepare_tools.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,8 @@ def find_and_remove_logos(self, **kwargs) -> dict:
7878
def remove_logo(self, **kwargs) -> dict:
7979
"""Remove logos in geometry."""
8080
pass
81+
82+
@abstractmethod
83+
def detect_helixes(self, **kwargs) -> dict:
84+
"""Detect helixes in geometry."""
85+
pass

src/ansys/geometry/core/_grpc/_services/v0/prepare_tools.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,64 @@ def remove_logo(self, **kwargs): # noqa: D102
214214

215215
# Return the response - formatted as a dictionary
216216
return {"success": response.success}
217+
218+
@protect_grpc
219+
def detect_helixes(self, **kwargs) -> dict: # noqa: D102
220+
from ansys.api.dbu.v0.dbumodels_pb2 import EntityIdentifier
221+
from ansys.api.geometry.v0.models_pb2 import DetectHelixesOptions
222+
from ansys.api.geometry.v0.preparetools_pb2 import DetectHelixesRequest
223+
224+
from ansys.geometry.core.shapes.parameterization import Interval
225+
226+
from ..base.conversions import (
227+
from_measurement_to_server_length,
228+
to_distance,
229+
)
230+
from .conversions import (
231+
from_grpc_curve_to_curve,
232+
from_grpc_point_to_point3d,
233+
)
234+
235+
# Create the request - assumes all inputs are valid and of the proper type
236+
request = DetectHelixesRequest(
237+
body_ids=[EntityIdentifier(id=body.id) for body in kwargs["bodies"]],
238+
options=DetectHelixesOptions(
239+
min_radius=from_measurement_to_server_length(kwargs["min_radius"]),
240+
max_radius=from_measurement_to_server_length(kwargs["max_radius"]),
241+
fit_radius_error=from_measurement_to_server_length(kwargs["fit_radius_error"]),
242+
),
243+
)
244+
245+
# Call the gRPC service
246+
response = self.stub.DetectHelixes(request)
247+
248+
# If no helixes, return empty dictionary
249+
if len(response.helixes) == 0:
250+
return {"helixes": []}
251+
252+
# Return the response - formatted as a dictionary
253+
return {
254+
"helixes": [
255+
{
256+
"trimmed_curve": {
257+
"geometry": from_grpc_curve_to_curve(helix.trimmed_curve.curve),
258+
"start": from_grpc_point_to_point3d(helix.trimmed_curve.start),
259+
"end": from_grpc_point_to_point3d(helix.trimmed_curve.end),
260+
"interval": Interval(
261+
helix.trimmed_curve.interval_start, helix.trimmed_curve.interval_end
262+
),
263+
"length": to_distance(helix.trimmed_curve.length).value,
264+
},
265+
"edges": [
266+
{
267+
"id": edge.id,
268+
"parent_id": edge.parent.id,
269+
"curve_type": edge.curve_type,
270+
"is_reversed": edge.is_reversed,
271+
}
272+
for edge in helix.edges
273+
],
274+
}
275+
for helix in response.helixes
276+
]
277+
}

src/ansys/geometry/core/_grpc/_services/v1/prepare_tools.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,7 @@ def find_and_remove_logos(self, **kwargs) -> dict: # noqa: D102
7878
@protect_grpc
7979
def remove_logo(self, **kwargs) -> dict: # noqa: D102
8080
raise NotImplementedError
81+
82+
@protect_grpc
83+
def detect_helixes(self, **kwargs) -> dict: # noqa: D102
84+
raise NotImplementedError

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

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,21 @@
2424
from typing import TYPE_CHECKING
2525

2626
from beartype import beartype as check_input_types
27+
from pint import Quantity
2728

2829
from ansys.geometry.core.connection import GrpcClient
2930
from ansys.geometry.core.connection.backend import BackendType
3031
from ansys.geometry.core.errors import GeometryRuntimeError
3132
from ansys.geometry.core.logger import LOG
3233
from ansys.geometry.core.misc.auxiliary import (
3334
get_bodies_from_ids,
35+
get_design_from_body,
3436
get_design_from_edge,
3537
get_design_from_face,
3638
)
3739
from ansys.geometry.core.misc.checks import check_type_all_elements_in_iterable, min_backend_version
40+
from ansys.geometry.core.misc.measurements import Distance
41+
from ansys.geometry.core.shapes.curves.trimmed_curve import TrimmedCurve
3842
from ansys.geometry.core.tools.problem_areas import LogoProblemArea
3943
from ansys.geometry.core.tools.repair_tool_message import RepairToolMessage
4044
from ansys.geometry.core.typing import Real
@@ -412,3 +416,86 @@ def find_and_remove_logos(
412416
)
413417

414418
return response.get("success")
419+
420+
@min_backend_version(26, 1, 0)
421+
def detect_helixes(
422+
self,
423+
bodies: list["Body"],
424+
min_radius: Distance | Quantity | Real = 0.0,
425+
max_radius: Distance | Quantity | Real = 100.0,
426+
fit_radius_error: Distance | Quantity | Real = 0.01,
427+
) -> dict["TrimmedCurve", list["Edge"]]:
428+
"""Detect helixes in the given bodies.
429+
430+
Parameters
431+
----------
432+
bodies : list[Body]
433+
List of bodies to detect helixes in.
434+
min_radius : Distance, Quantity, or Real, default: 0.0
435+
Minimum radius of the helix to be detected.
436+
max_radius : Distance, Quantity, or Real, default: 1e6
437+
Maximum radius of the helix to be detected.
438+
fit_radius_error : Distance, Quantity, or Real, default: 0.01
439+
Maximum fit radius error of the helix to be detected.
440+
441+
Returns
442+
-------
443+
dict
444+
Dictionary with key "helixes" containing a list of detected helixes.
445+
Each helix is represented as a dictionary with keys "trimmed_curve" and "edges".
446+
447+
Warnings
448+
--------
449+
This method is only available starting on Ansys release 26R1.
450+
"""
451+
from ansys.geometry.core.designer.body import Body
452+
from ansys.geometry.core.designer.edge import CurveType, Edge
453+
454+
if not bodies:
455+
self._grpc_client.log.info("No bodies provided...")
456+
return {"helixes": []}
457+
458+
# Verify inputs
459+
check_type_all_elements_in_iterable(bodies, Body)
460+
min_radius = min_radius if isinstance(min_radius, Distance) else Distance(min_radius)
461+
max_radius = max_radius if isinstance(max_radius, Distance) else Distance(max_radius)
462+
fit_radius_error = (
463+
fit_radius_error
464+
if isinstance(fit_radius_error, Distance)
465+
else Distance(fit_radius_error)
466+
)
467+
468+
response = self._grpc_client._services.prepare_tools.detect_helixes(
469+
bodies=bodies,
470+
min_radius=min_radius,
471+
max_radius=max_radius,
472+
fit_radius_error=fit_radius_error,
473+
)
474+
475+
parent_design = get_design_from_body(bodies[0])
476+
477+
return {
478+
"helixes": [
479+
{
480+
"trimmed_curve": TrimmedCurve(
481+
helix.get("trimmed_curve").get("geometry"),
482+
helix.get("trimmed_curve").get("start"),
483+
helix.get("trimmed_curve").get("end"),
484+
helix.get("trimmed_curve").get("interval"),
485+
helix.get("trimmed_curve").get("length"),
486+
grpc_client=self._grpc_client,
487+
),
488+
"edges": [
489+
Edge(
490+
edge.get("id"),
491+
CurveType(edge.get("curve_type")),
492+
get_bodies_from_ids(parent_design, [edge.get("parent_id")])[0],
493+
self._grpc_client,
494+
edge.get("is_reversed"),
495+
)
496+
for edge in helix.get("edges")
497+
],
498+
}
499+
for helix in response.get("helixes")
500+
]
501+
}

0 commit comments

Comments
 (0)