Skip to content

Commit 3dfe1c3

Browse files
feat: revolve_sketch rotation definition enhancement (#1336)
Co-authored-by: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com>
1 parent 896829b commit 3dfe1c3

File tree

4 files changed

+97
-29
lines changed

4 files changed

+97
-29
lines changed

doc/changelog.d/1336.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
feat: ``revolve_sketch`` rotation definition enhancement

src/ansys/geometry/core/designer/component.py

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -592,12 +592,6 @@ def revolve_sketch(
592592
) -> Body:
593593
"""Create a solid body by revolving a sketch profile around an axis.
594594
595-
Notes
596-
-----
597-
It is important that the sketch plane origin is not coincident with the rotation
598-
origin. If the sketch plane origin is coincident with the rotation origin, the
599-
distance between the two points is zero, and the revolve operation fails.
600-
601595
Parameters
602596
----------
603597
name : str
@@ -616,26 +610,16 @@ def revolve_sketch(
616610
Body
617611
Revolved body from the given sketch.
618612
"""
619-
# Check that the sketch plane origin is not coincident with the rotation origin
620-
if sketch.plane.origin == rotation_origin:
621-
raise ValueError(
622-
"The sketch plane origin is coincident with the rotation origin. "
623-
+ "The distance between the points is zero, and the revolve operation will fail."
624-
)
625-
626-
# Compute the distance between the rotation origin and the sketch plane
627-
rotation_origin_to_sketch = sketch.plane.origin - rotation_origin
628-
rotation_origin_to_sketch_as_vector = Vector3D(rotation_origin_to_sketch)
629-
distance = Distance(
630-
rotation_origin_to_sketch_as_vector.norm,
631-
unit=rotation_origin_to_sketch.base_unit,
632-
)
613+
# Based on the reference axis and the sketch plane's normal, retrieve the orthogonal
614+
# vector (i.e. this is the reference vector for the Circle object). Assuming a distance of 1
615+
# we revolve around the axis the angle given.
616+
rotation_vector = sketch._plane.normal.cross(axis)
633617

634618
# Define the revolve path
635619
circle = Circle(
636620
rotation_origin,
637-
radius=distance,
638-
reference=rotation_origin_to_sketch_as_vector,
621+
radius=Distance(1),
622+
reference=rotation_vector,
639623
axis=axis,
640624
)
641625
angle = angle if isinstance(angle, Angle) else Angle(angle)

tests/integration/test_design.py

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,10 +2390,43 @@ def test_revolve_sketch(modeler: Modeler):
23902390
assert np.isclose(body.volume.m, np.pi**2 * 2 * 5, rtol=1e-3) # quarter of a torus volume
23912391

23922392

2393-
def test_revolve_sketch_fail(modeler: Modeler):
2394-
"""Test demonstrating the failure of revolving a sketch when it is located
2395-
in the same origin.
2393+
def test_revolve_sketch_coincident_origins(modeler: Modeler):
2394+
"""Test demonstrating revolving a sketch when it is located
2395+
in the same origin does not fail.
23962396
"""
2397+
# Initialize a sphere sketch design given a semicircle profile
2398+
design = modeler.create_design("revolve-coincident-origins")
2399+
2400+
# Create an XZ plane centered at (0, 0, 0)
2401+
plane_profile = Plane(
2402+
origin=Point3D([0, 0, 0]), direction_x=UNITVECTOR3D_X, direction_y=UNITVECTOR3D_Z
2403+
)
2404+
profile = Sketch(plane=plane_profile)
2405+
(
2406+
profile.segment_to_point(Point2D([1, 0]))
2407+
.arc_to_point(Point2D([-1, 0]), Point2D([0, 0]))
2408+
.segment_to_point(Point2D([0, 0]))
2409+
)
2410+
2411+
# Try revolving the profile... coincident origins is not a problem anymore
2412+
body = design.revolve_sketch(
2413+
"cross-section-sphere",
2414+
sketch=profile,
2415+
axis=UNITVECTOR3D_X,
2416+
angle=Angle(90, unit=UNITS.degrees),
2417+
rotation_origin=Point3D([0, 0, 0]),
2418+
)
2419+
2420+
assert body.is_surface is False
2421+
assert body.name == "cross-section-sphere"
2422+
assert np.isclose(
2423+
body.volume.m, np.pi / 3, rtol=1e-3
2424+
) # quarter of a sphere volume (4/3 * pi * r^3) / 4
2425+
# 1/3 * pi * r^3 --> r = 1 --> 1/3 * pi
2426+
2427+
2428+
def test_revolve_sketch_fail_invalid_path(modeler: Modeler):
2429+
"""Test demonstrating the failure of revolving a sketch when an invalid path is provided."""
23972430
# Initialize the donut sketch design
23982431
design = modeler.create_design("revolve-fail")
23992432

@@ -2402,13 +2435,14 @@ def test_revolve_sketch_fail(modeler: Modeler):
24022435
origin=Point3D([0, 0, 0]), direction_x=UNITVECTOR3D_X, direction_y=UNITVECTOR3D_Z
24032436
)
24042437
profile = Sketch(plane=plane_profile)
2438+
profile.circle(Point2D([0, 0]), 1)
24052439

24062440
# Try revolving the profile...
24072441
with pytest.raises(
2408-
ValueError, match="The sketch plane origin is coincident with the rotation origin."
2442+
GeometryExitedError, match="The path is invalid, or it is unsuitable for the profile."
24092443
):
24102444
design.revolve_sketch(
2411-
"donut-body",
2445+
"cross-section-sphere",
24122446
sketch=profile,
24132447
axis=UNITVECTOR3D_Z,
24142448
angle=Angle(90, unit=UNITS.degrees),

tests/integration/test_issues.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,15 @@
2525

2626
import numpy as np
2727

28-
from ansys.geometry.core.math import UNITVECTOR3D_X, UNITVECTOR3D_Y, Plane, Point2D, Point3D
29-
from ansys.geometry.core.misc import DEFAULT_UNITS, UNITS, Distance
28+
from ansys.geometry.core.math import (
29+
UNITVECTOR3D_X,
30+
UNITVECTOR3D_Y,
31+
UNITVECTOR3D_Z,
32+
Plane,
33+
Point2D,
34+
Point3D,
35+
)
36+
from ansys.geometry.core.misc import DEFAULT_UNITS, UNITS, Angle, Distance
3037
from ansys.geometry.core.modeler import Modeler
3138
from ansys.geometry.core.sketch import Sketch
3239

@@ -130,3 +137,45 @@ def test_issue_1304_arc_sketch_creation():
130137
finally:
131138
# Reverse the default units to meter
132139
DEFAULT_UNITS.LENGTH = UNITS.meter
140+
141+
142+
def test_issue_1309_revolve_operation_with_coincident_origins(modeler: Modeler):
143+
"""Test that revolving a sketch with coincident origins (sketch and rotation origin)
144+
does not crash the program.
145+
146+
For more info see
147+
https://github.com/ansys/pyansys-geometry/issues/1309
148+
"""
149+
# Sketch Plane
150+
sketch_plane = Plane(
151+
origin=Point3D([0, 0, 5]), direction_x=UNITVECTOR3D_X, direction_y=UNITVECTOR3D_Z
152+
)
153+
154+
# Create Base
155+
sketch = Sketch(sketch_plane)
156+
157+
(
158+
sketch.arc(
159+
start=Point2D([0, 0]),
160+
end=Point2D([4.7, 4.7]),
161+
center=Point2D([0, 4.7]),
162+
clockwise=False,
163+
)
164+
.segment_to_point(Point2D([4.7, 12]))
165+
.segment_to_point(Point2D([-25.3, 12]))
166+
.segment_to_point(Point2D([-25.3, 0]))
167+
.segment_to_point(Point2D([0, 0]))
168+
)
169+
170+
# Create Component (Revolve sketch)
171+
design = modeler.create_design("cylinder")
172+
component = design.add_component("cylinder_toroid")
173+
revolved_body = component.revolve_sketch(
174+
"toroid",
175+
sketch=sketch,
176+
axis=UNITVECTOR3D_X,
177+
angle=Angle(360, UNITS.degrees),
178+
rotation_origin=Point3D([-10.3, 0, 0]),
179+
)
180+
181+
assert revolved_body.name == "toroid"

0 commit comments

Comments
 (0)