Skip to content
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

feat: add chamfer tool #1495

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
1 change: 1 addition & 0 deletions doc/changelog.d/1495.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add chamfer tool
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ classifiers = [
]

dependencies = [
"ansys-api-geometry==0.4.11",
"ansys-api-geometry==0.4.12",
"ansys-tools-path>=0.3,<1",
"ansys-tools-visualization-interface>=0.2.6,<1",
"beartype>=0.11.0,<0.20",
Expand Down
6 changes: 5 additions & 1 deletion src/ansys/geometry/core/designer/body.py
Original file line number Diff line number Diff line change
Expand Up @@ -1206,11 +1206,15 @@ def reset_tessellation_cache(func): # noqa: N805

@wraps(func)
def wrapper(self: "Body", *args, **kwargs):
self._template._tessellation = None
self._reset_tessellation_cache()
return func(self, *args, **kwargs)

return wrapper

def _reset_tessellation_cache(self): # noqa: N805
"""Reset the cached tessellation for a body."""
self._template._tessellation = None

jonahrb marked this conversation as resolved.
Show resolved Hide resolved
@property
def id(self) -> str: # noqa: D102
return self._id
Expand Down
5 changes: 5 additions & 0 deletions src/ansys/geometry/core/designer/edge.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ def _grpc_id(self) -> EntityIdentifier:
"""Entity ID of this edge on the server side."""
return EntityIdentifier(id=self._id)

@property
def body(self) -> "Body":
"""Body of the edge."""
return self._body
jonahrb marked this conversation as resolved.
Show resolved Hide resolved

@property
def is_reversed(self) -> bool:
"""Flag indicating if the edge is reversed."""
Expand Down
7 changes: 7 additions & 0 deletions src/ansys/geometry/core/modeler.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
from ansys.geometry.core.misc.options import ImportOptions
from ansys.geometry.core.tools.measurement_tools import MeasurementTools
from ansys.geometry.core.tools.prepare_tools import PrepareTools
from ansys.geometry.core.tools.pull_tools import PullTools
from ansys.geometry.core.tools.repair_tools import RepairTools
from ansys.geometry.core.typing import Real

Expand Down Expand Up @@ -128,6 +129,7 @@ def __init__(
self._repair_tools = RepairTools(self._grpc_client)
self._prepare_tools = PrepareTools(self._grpc_client)
self._measurement_tools = MeasurementTools(self._grpc_client)
self._pull_tools = PullTools(self._grpc_client)

# Maintaining references to all designs within the modeler workspace
self._designs: dict[str, "Design"] = {}
Expand Down Expand Up @@ -497,3 +499,8 @@ def prepare_tools(self) -> PrepareTools:
def measurement_tools(self) -> MeasurementTools:
"""Access to measurement tools."""
return self._measurement_tools

@property
def pull_tools(self) -> PullTools:
"""Access to pull tools."""
return self._pull_tools
1 change: 1 addition & 0 deletions src/ansys/geometry/core/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@
ExtraEdgeProblemAreas,
InexactEdgeProblemAreas,
)
from ansys.geometry.core.tools.pull_tools import PullTools
from ansys.geometry.core.tools.repair_tool_message import RepairToolMessage
from ansys.geometry.core.tools.repair_tools import RepairTools
74 changes: 74 additions & 0 deletions src/ansys/geometry/core/tools/pull_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Provides tools for pulling geometry."""

from typing import TYPE_CHECKING, Union

from ansys.api.geometry.v0.commands_pb2 import ChamferRequest
from ansys.api.geometry.v0.commands_pb2_grpc import CommandsStub
from ansys.geometry.core.connection import GrpcClient
from ansys.geometry.core.errors import protect_grpc
from ansys.geometry.core.misc.checks import min_backend_version
from ansys.geometry.core.typing import Real

if TYPE_CHECKING: # pragma: no cover
from ansys.geometry.core.designer.edge import Edge
from ansys.geometry.core.designer.face import Face


class PullTools:
"""Pull tools for PyAnsys Geometry.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Pull tools for PyAnsys Geometry.
"""Provides pull tools for PyAnsys Geometry.

Class descriptions should begin with a verb ending in "s" or "es"


Parameters
----------
grpc_client : GrpcClient
gRPC client to use for the measurement tools.
"""

@protect_grpc
def __init__(self, grpc_client: GrpcClient):
"""Initialize pull tools class."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Initialize pull tools class."""
"""Initialize an instance of the ``PullTools`` class."""

self._grpc_client = grpc_client
self._commands_stub = CommandsStub(self._grpc_client.channel)

@protect_grpc
@min_backend_version(25, 1, 0)
def chamfer(self, edge_or_face: Union["Edge", "Face"], distance: Real) -> bool:
"""Create a chamfer on an edge, or adjust the chamfer of a face.

Parameters
----------
edge_or_face : Edge | Face
Edge or face to act on.
distance : Real
Chamfer distance.

Returns
-------
bool
Success of chamfer command.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Success of chamfer command.
``True`` when successful, ``False`` when failed.

This is our standard verbiage for a Boolean return value.

"""
edge_or_face.body._reset_tessellation_cache()
RobPasMue marked this conversation as resolved.
Show resolved Hide resolved

result = self._commands_stub.Chamfer(ChamferRequest(id=edge_or_face.id, distance=distance))

return result.success
50 changes: 50 additions & 0 deletions tests/integration/test_pull_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
""" "Testing of repair tools."""

from pint import Quantity
import pytest

from ansys.geometry.core.math.point import Point2D
from ansys.geometry.core.misc import UNITS
from ansys.geometry.core.modeler import Modeler
from ansys.geometry.core.sketch.sketch import Sketch


def test_chamfer(modeler: Modeler):
"""Test chamfer on edge and face."""
design = modeler.create_design("chamfer")

body = design.extrude_sketch("box", Sketch().box(Point2D([0, 0]), 1, 1), 1)
assert len(body.faces) == 6
assert len(body.edges) == 12
assert body.volume.m == pytest.approx(Quantity(1, UNITS.m**3).m, rel=1e-6, abs=1e-8)

modeler.pull_tools.chamfer(body.edges[0], 0.1)
assert len(body.faces) == 7
assert len(body.edges) == 15
assert body.volume.m == pytest.approx(Quantity(0.995, UNITS.m**3).m, rel=1e-6, abs=1e-8)

modeler.pull_tools.chamfer(body.faces[-1], 0.5)
assert len(body.faces) == 7
assert len(body.edges) == 15
assert body.volume.m == pytest.approx(Quantity(0.875, UNITS.m**3).m, rel=1e-6, abs=1e-8)
Loading