From dadd8fb5a290cbfc48c2b4c9112a97d1d883f1e1 Mon Sep 17 00:00:00 2001 From: jonahrb Date: Tue, 30 May 2023 11:05:59 -0400 Subject: [PATCH 01/76] re-org primitives folder to geometry --- src/ansys/geometry/core/geometry/__init__.py | 17 ++++++++++++++++ .../{primitives => geometry/curves}/circle.py | 14 ++++++------- .../curves}/curve_evaluation.py | 0 .../curves}/ellipse.py | 14 ++++++------- .../{primitives => geometry/curves}/line.py | 8 ++++---- .../parameterization.py | 0 .../{primitives => geometry/surfaces}/cone.py | 18 ++++++++--------- .../surfaces}/cylinder.py | 20 +++++++++---------- .../surfaces}/sphere.py | 16 +++++++-------- .../surfaces}/surface_evaluation.py | 2 +- .../surfaces}/torus.py | 16 +++++++-------- .../geometry/core/primitives/__init__.py | 16 --------------- src/ansys/geometry/core/sketch/circle.py | 2 +- src/ansys/geometry/core/sketch/ellipse.py | 2 +- src/ansys/geometry/core/sketch/segment.py | 2 +- tests/test_parameterization.py | 8 +------- tests/test_primitives.py | 20 +++++++++---------- 17 files changed, 85 insertions(+), 90 deletions(-) create mode 100644 src/ansys/geometry/core/geometry/__init__.py rename src/ansys/geometry/core/{primitives => geometry/curves}/circle.py (98%) rename src/ansys/geometry/core/{primitives => geometry/curves}/curve_evaluation.py (100%) rename src/ansys/geometry/core/{primitives => geometry/curves}/ellipse.py (98%) rename src/ansys/geometry/core/{primitives => geometry/curves}/line.py (98%) rename src/ansys/geometry/core/{primitives => geometry}/parameterization.py (100%) rename src/ansys/geometry/core/{primitives => geometry/surfaces}/cone.py (98%) rename src/ansys/geometry/core/{primitives => geometry/surfaces}/cylinder.py (97%) rename src/ansys/geometry/core/{primitives => geometry/surfaces}/sphere.py (98%) rename src/ansys/geometry/core/{primitives => geometry/surfaces}/surface_evaluation.py (97%) rename src/ansys/geometry/core/{primitives => geometry/surfaces}/torus.py (98%) delete mode 100644 src/ansys/geometry/core/primitives/__init__.py diff --git a/src/ansys/geometry/core/geometry/__init__.py b/src/ansys/geometry/core/geometry/__init__.py new file mode 100644 index 0000000000..19b2ba6518 --- /dev/null +++ b/src/ansys/geometry/core/geometry/__init__.py @@ -0,0 +1,17 @@ +"""Provides the PyGeometry ``geometry`` subpackage.""" + +from ansys.geometry.core.geometry.curves.circle import Circle, CircleEvaluation +from ansys.geometry.core.geometry.curves.ellipse import Ellipse, EllipseEvaluation +from ansys.geometry.core.geometry.curves.line import Line, LineEvaluation +from ansys.geometry.core.geometry.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, + ParamUV, +) +from ansys.geometry.core.geometry.surfaces.cone import Cone, ConeEvaluation +from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder, CylinderEvaluation +from ansys.geometry.core.geometry.surfaces.sphere import Sphere, SphereEvaluation +from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation +from ansys.geometry.core.geometry.surfaces.torus import Torus diff --git a/src/ansys/geometry/core/primitives/circle.py b/src/ansys/geometry/core/geometry/curves/circle.py similarity index 98% rename from src/ansys/geometry/core/primitives/circle.py rename to src/ansys/geometry/core/geometry/curves/circle.py index fdc482b91f..34faf70af5 100644 --- a/src/ansys/geometry/core/primitives/circle.py +++ b/src/ansys/geometry/core/geometry/curves/circle.py @@ -6,6 +6,13 @@ import numpy as np from pint import Quantity +from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.geometry.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, +) from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -15,13 +22,6 @@ Vector3D, ) from ansys.geometry.core.misc import Accuracy, Distance -from ansys.geometry.core.primitives.curve_evaluation import CurveEvaluation -from ansys.geometry.core.primitives.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, -) from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/primitives/curve_evaluation.py b/src/ansys/geometry/core/geometry/curves/curve_evaluation.py similarity index 100% rename from src/ansys/geometry/core/primitives/curve_evaluation.py rename to src/ansys/geometry/core/geometry/curves/curve_evaluation.py diff --git a/src/ansys/geometry/core/primitives/ellipse.py b/src/ansys/geometry/core/geometry/curves/ellipse.py similarity index 98% rename from src/ansys/geometry/core/primitives/ellipse.py rename to src/ansys/geometry/core/geometry/curves/ellipse.py index 4c83271f2a..4060f02779 100644 --- a/src/ansys/geometry/core/primitives/ellipse.py +++ b/src/ansys/geometry/core/geometry/curves/ellipse.py @@ -8,6 +8,13 @@ from pint import Quantity from scipy.integrate import quad +from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.geometry.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, +) from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -17,13 +24,6 @@ Vector3D, ) from ansys.geometry.core.misc import Accuracy, Distance -from ansys.geometry.core.primitives.curve_evaluation import CurveEvaluation -from ansys.geometry.core.primitives.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, -) from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/primitives/line.py b/src/ansys/geometry/core/geometry/curves/line.py similarity index 98% rename from src/ansys/geometry/core/primitives/line.py rename to src/ansys/geometry/core/geometry/curves/line.py index 866d91dfbb..6e896a07a5 100644 --- a/src/ansys/geometry/core/primitives/line.py +++ b/src/ansys/geometry/core/geometry/curves/line.py @@ -7,15 +7,15 @@ from beartype.typing import Union import numpy as np -from ansys.geometry.core.math import Matrix44, Point3D, UnitVector3D, Vector3D -from ansys.geometry.core.misc.accuracy import LENGTH_ACCURACY -from ansys.geometry.core.primitives.curve_evaluation import CurveEvaluation -from ansys.geometry.core.primitives.parameterization import ( +from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.geometry.parameterization import ( Interval, Parameterization, ParamForm, ParamType, ) +from ansys.geometry.core.math import Matrix44, Point3D, UnitVector3D, Vector3D +from ansys.geometry.core.misc.accuracy import LENGTH_ACCURACY from ansys.geometry.core.typing import RealSequence diff --git a/src/ansys/geometry/core/primitives/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py similarity index 100% rename from src/ansys/geometry/core/primitives/parameterization.py rename to src/ansys/geometry/core/geometry/parameterization.py diff --git a/src/ansys/geometry/core/primitives/cone.py b/src/ansys/geometry/core/geometry/surfaces/cone.py similarity index 98% rename from src/ansys/geometry/core/primitives/cone.py rename to src/ansys/geometry/core/geometry/surfaces/cone.py index e0e0e18d23..517392b653 100644 --- a/src/ansys/geometry/core/primitives/cone.py +++ b/src/ansys/geometry/core/geometry/surfaces/cone.py @@ -7,6 +7,15 @@ import numpy as np from pint import Quantity +from ansys.geometry.core.geometry.curves.line import Line +from ansys.geometry.core.geometry.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, + ParamUV, +) +from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -16,15 +25,6 @@ Vector3D, ) from ansys.geometry.core.misc import Angle, Distance -from ansys.geometry.core.primitives.line import Line -from ansys.geometry.core.primitives.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, - ParamUV, -) -from ansys.geometry.core.primitives.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/primitives/cylinder.py b/src/ansys/geometry/core/geometry/surfaces/cylinder.py similarity index 97% rename from src/ansys/geometry/core/primitives/cylinder.py rename to src/ansys/geometry/core/geometry/surfaces/cylinder.py index bcac8786c7..5745c13d50 100644 --- a/src/ansys/geometry/core/primitives/cylinder.py +++ b/src/ansys/geometry/core/geometry/surfaces/cylinder.py @@ -7,6 +7,16 @@ import numpy as np from pint import Quantity +from ansys.geometry.core.geometry.curves.circle import Circle +from ansys.geometry.core.geometry.curves.line import Line +from ansys.geometry.core.geometry.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, + ParamUV, +) +from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -16,16 +26,6 @@ Vector3D, ) from ansys.geometry.core.misc import Distance -from ansys.geometry.core.primitives.circle import Circle -from ansys.geometry.core.primitives.line import Line -from ansys.geometry.core.primitives.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, - ParamUV, -) -from ansys.geometry.core.primitives.surface_evaluation import ParamUV, SurfaceEvaluation from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/primitives/sphere.py b/src/ansys/geometry/core/geometry/surfaces/sphere.py similarity index 98% rename from src/ansys/geometry/core/primitives/sphere.py rename to src/ansys/geometry/core/geometry/surfaces/sphere.py index 8cf93a0cd7..a5fc68eaa3 100644 --- a/src/ansys/geometry/core/primitives/sphere.py +++ b/src/ansys/geometry/core/geometry/surfaces/sphere.py @@ -7,6 +7,14 @@ import numpy as np from pint import Quantity +from ansys.geometry.core.geometry.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, + ParamUV, +) +from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -16,14 +24,6 @@ Vector3D, ) from ansys.geometry.core.misc import Distance -from ansys.geometry.core.primitives.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, - ParamUV, -) -from ansys.geometry.core.primitives.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/primitives/surface_evaluation.py b/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py similarity index 97% rename from src/ansys/geometry/core/primitives/surface_evaluation.py rename to src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py index 53ad96f1d0..ec64de7883 100644 --- a/src/ansys/geometry/core/primitives/surface_evaluation.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py @@ -2,8 +2,8 @@ from functools import cached_property +from ansys.geometry.core.geometry.parameterization import ParamUV from ansys.geometry.core.math import Point3D, UnitVector3D, Vector3D -from ansys.geometry.core.primitives.parameterization import ParamUV from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/primitives/torus.py b/src/ansys/geometry/core/geometry/surfaces/torus.py similarity index 98% rename from src/ansys/geometry/core/primitives/torus.py rename to src/ansys/geometry/core/geometry/surfaces/torus.py index 941b26b4db..4f2fe4546d 100644 --- a/src/ansys/geometry/core/primitives/torus.py +++ b/src/ansys/geometry/core/geometry/surfaces/torus.py @@ -8,6 +8,14 @@ import numpy as np from pint import Quantity +from ansys.geometry.core.geometry.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, + ParamUV, +) +from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -17,14 +25,6 @@ Vector3D, ) from ansys.geometry.core.misc import Distance -from ansys.geometry.core.primitives.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, - ParamUV, -) -from ansys.geometry.core.primitives.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/primitives/__init__.py b/src/ansys/geometry/core/primitives/__init__.py deleted file mode 100644 index a05fdc90a0..0000000000 --- a/src/ansys/geometry/core/primitives/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Provides the PyGeometry ``primitives`` subpackage.""" - -from ansys.geometry.core.primitives.circle import Circle, CircleEvaluation -from ansys.geometry.core.primitives.cone import Cone, ConeEvaluation -from ansys.geometry.core.primitives.cylinder import Cylinder, CylinderEvaluation -from ansys.geometry.core.primitives.ellipse import Ellipse, EllipseEvaluation -from ansys.geometry.core.primitives.line import Line, LineEvaluation -from ansys.geometry.core.primitives.parameterization import ( - Parameterization, - ParamForm, - ParamType, - ParamUV, -) -from ansys.geometry.core.primitives.sphere import Sphere, SphereEvaluation -from ansys.geometry.core.primitives.surface_evaluation import SurfaceEvaluation -from ansys.geometry.core.primitives.torus import Torus diff --git a/src/ansys/geometry/core/sketch/circle.py b/src/ansys/geometry/core/sketch/circle.py index f5879f87de..2da57072d9 100644 --- a/src/ansys/geometry/core/sketch/circle.py +++ b/src/ansys/geometry/core/sketch/circle.py @@ -5,9 +5,9 @@ from pint import Quantity import pyvista as pv +from ansys.geometry.core.geometry import Circle from ansys.geometry.core.math import Plane, Point2D, Point3D from ansys.geometry.core.misc import DEFAULT_UNITS, Distance -from ansys.geometry.core.primitives import Circle from ansys.geometry.core.sketch.face import SketchFace from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/sketch/ellipse.py b/src/ansys/geometry/core/sketch/ellipse.py index 3eb0800650..ade00caca0 100644 --- a/src/ansys/geometry/core/sketch/ellipse.py +++ b/src/ansys/geometry/core/sketch/ellipse.py @@ -7,9 +7,9 @@ import pyvista as pv from scipy.spatial.transform import Rotation as spatial_rotation +from ansys.geometry.core.geometry import Ellipse from ansys.geometry.core.math import Matrix33, Matrix44, Plane, Point2D, Point3D, Vector3D from ansys.geometry.core.misc import DEFAULT_UNITS, UNITS, Angle, Distance -from ansys.geometry.core.primitives import Ellipse from ansys.geometry.core.sketch.face import SketchFace from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/sketch/segment.py b/src/ansys/geometry/core/sketch/segment.py index 8631a79cfb..f087eb4d29 100644 --- a/src/ansys/geometry/core/sketch/segment.py +++ b/src/ansys/geometry/core/sketch/segment.py @@ -5,9 +5,9 @@ from pint import Quantity import pyvista as pv +from ansys.geometry.core.geometry import Line from ansys.geometry.core.math import Plane, Point2D, Point3D, UnitVector3D from ansys.geometry.core.misc import DEFAULT_UNITS, check_ndarray_is_all_nan -from ansys.geometry.core.primitives import Line from ansys.geometry.core.sketch.edge import SketchEdge diff --git a/tests/test_parameterization.py b/tests/test_parameterization.py index 408c8fc4e3..617d95735a 100644 --- a/tests/test_parameterization.py +++ b/tests/test_parameterization.py @@ -2,14 +2,8 @@ import numpy as np import pytest +from ansys.geometry.core.geometry import Interval, Parameterization, ParamForm, ParamType, ParamUV from ansys.geometry.core.misc.accuracy import Accuracy -from ansys.geometry.core.primitives.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, - ParamUV, -) def test_param_uv(): diff --git a/tests/test_primitives.py b/tests/test_primitives.py index 20292c5c38..7c16a650b6 100644 --- a/tests/test_primitives.py +++ b/tests/test_primitives.py @@ -3,6 +3,16 @@ from pint import Quantity import pytest +from ansys.geometry.core.geometry import ( + Circle, + Cone, + Cylinder, + Ellipse, + Line, + ParamUV, + Sphere, + Torus, +) from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Y, @@ -13,16 +23,6 @@ Vector3D, ) from ansys.geometry.core.misc import DEFAULT_UNITS, UNITS, Accuracy, Distance -from ansys.geometry.core.primitives import ( - Circle, - Cone, - Cylinder, - Ellipse, - Line, - ParamUV, - Sphere, - Torus, -) def test_cylinder(): From 545626c002c04a2f67539b783a67d132f2c8489d Mon Sep 17 00:00:00 2001 From: jonahrb Date: Tue, 30 May 2023 11:50:15 -0400 Subject: [PATCH 02/76] add surface and curve ABC's --- src/ansys/geometry/core/geometry/__init__.py | 2 + .../geometry/core/geometry/curves/curve.py | 65 +++++++++++++++++++ .../core/geometry/surfaces/surface.py | 65 +++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 src/ansys/geometry/core/geometry/curves/curve.py create mode 100644 src/ansys/geometry/core/geometry/surfaces/surface.py diff --git a/src/ansys/geometry/core/geometry/__init__.py b/src/ansys/geometry/core/geometry/__init__.py index 19b2ba6518..71ca3adb6a 100644 --- a/src/ansys/geometry/core/geometry/__init__.py +++ b/src/ansys/geometry/core/geometry/__init__.py @@ -1,6 +1,7 @@ """Provides the PyGeometry ``geometry`` subpackage.""" from ansys.geometry.core.geometry.curves.circle import Circle, CircleEvaluation +from ansys.geometry.core.geometry.curves.curve import Curve from ansys.geometry.core.geometry.curves.ellipse import Ellipse, EllipseEvaluation from ansys.geometry.core.geometry.curves.line import Line, LineEvaluation from ansys.geometry.core.geometry.parameterization import ( @@ -13,5 +14,6 @@ from ansys.geometry.core.geometry.surfaces.cone import Cone, ConeEvaluation from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder, CylinderEvaluation from ansys.geometry.core.geometry.surfaces.sphere import Sphere, SphereEvaluation +from ansys.geometry.core.geometry.surfaces.surface import Surface from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.geometry.surfaces.torus import Torus diff --git a/src/ansys/geometry/core/geometry/curves/curve.py b/src/ansys/geometry/core/geometry/curves/curve.py new file mode 100644 index 0000000000..dab6579f5d --- /dev/null +++ b/src/ansys/geometry/core/geometry/curves/curve.py @@ -0,0 +1,65 @@ +"""Provides the ``Curve`` class.""" +from abc import ABC, abstractmethod + +from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.geometry.parameterization import Parameterization +from ansys.geometry.core.math import Matrix44, Point3D +from ansys.geometry.core.typing import Real + + +class Curve(ABC): + """ + Curve abstract base class. + + Represents a 3D curve. + """ + + @abstractmethod + def parameterization(self) -> Parameterization: + """Parameterization of the curve.""" + return + + @abstractmethod + def contains_param(self, param: Real) -> bool: + """Test whether a parameter is within the parametric range of the curve.""" + return + + @abstractmethod + def contains_point(self, point: Point3D) -> bool: + """ + Test whether the point is contained by the curve. + + The point can either lie within it, or on its boundary. + """ + return + + @abstractmethod + def transformed_copy(self, matrix: Matrix44) -> "Curve": + """Create a transformed copy of the curve.""" + return + + @abstractmethod + def __eq__(self, other: "Curve") -> bool: + """Determine if two curves are equal.""" + return + + @abstractmethod + def evaluate(self, parameter: Real) -> CurveEvaluation: + """Evaluate the curve at the given parameter.""" + return + + @abstractmethod + def project_point(self, point: Point3D) -> CurveEvaluation: + """ + Project a point to the curve. + + This returns the evaluation at the closest point. + """ + return + + # TODO: Implement more curve methods + # as_spline + # get_length + # get_polyline + # intersect_curve + # is_coincident diff --git a/src/ansys/geometry/core/geometry/surfaces/surface.py b/src/ansys/geometry/core/geometry/surfaces/surface.py new file mode 100644 index 0000000000..f5e631b30a --- /dev/null +++ b/src/ansys/geometry/core/geometry/surfaces/surface.py @@ -0,0 +1,65 @@ +"""Provides the ``Surface`` class.""" +from abc import ABC, abstractmethod + +from ansys.geometry.core.geometry.parameterization import Parameterization, ParamUV +from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation +from ansys.geometry.core.math import Matrix44, Point3D + + +class Surface(ABC): + """ + Surface abstract base class. + + Represents a 3D surface. + """ + + @abstractmethod + def parameterization(self) -> tuple[Parameterization, Parameterization]: + """Parameterization of the surface as a tuple (U and V respectively).""" + return + + @abstractmethod + def contains_param(self, param_uv: ParamUV) -> bool: + """Test whether a parameter is within the parametric range of the surface.""" + return + + @abstractmethod + def contains_point(self, point: Point3D) -> bool: + """ + Test whether the point is contained by the surface. + + The point can either lie within it, or on its boundary. + """ + return + + @abstractmethod + def transformed_copy(self, matrix: Matrix44) -> "Surface": + """Create a transformed copy of the surface.""" + return + + @abstractmethod + def __eq__(self, other: "Surface") -> bool: + """Determine if two surfaces are equal.""" + return + + @abstractmethod + def evaluate(self, parameter: ParamUV) -> SurfaceEvaluation: + """Evaluate the surface at the given parameter.""" + return + + @abstractmethod + def project_point(self, point: Point3D) -> SurfaceEvaluation: + """ + Project a point to the surface. + + This returns the evaluation at the closest point. + """ + return + + # TODO: Implement more surface methods + # is_ruled + # is_singular + # get_length + # intersect_curve + # intersect_surface + # is_coincident From 40c9bd7fd05f3e908fe965d800f89a7e67e57928 Mon Sep 17 00:00:00 2001 From: jonahrb Date: Wed, 14 Jun 2023 10:38:53 -0400 Subject: [PATCH 03/76] curves and surfaces now inherit from ABC's --- .../geometry/core/geometry/curves/circle.py | 13 +++++-- .../geometry/core/geometry/curves/ellipse.py | 11 +++++- .../geometry/core/geometry/curves/line.py | 13 +++++-- .../geometry/core/geometry/surfaces/cone.py | 35 ++++++++--------- .../core/geometry/surfaces/cylinder.py | 33 ++++++++-------- .../geometry/core/geometry/surfaces/sphere.py | 33 ++++++++-------- .../geometry/core/geometry/surfaces/torus.py | 39 +++++++++---------- 7 files changed, 97 insertions(+), 80 deletions(-) diff --git a/src/ansys/geometry/core/geometry/curves/circle.py b/src/ansys/geometry/core/geometry/curves/circle.py index 34faf70af5..f27e0c8d86 100644 --- a/src/ansys/geometry/core/geometry/curves/circle.py +++ b/src/ansys/geometry/core/geometry/curves/circle.py @@ -6,6 +6,7 @@ import numpy as np from pint import Quantity +from ansys.geometry.core.geometry.curves.curve import Curve from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation from ansys.geometry.core.geometry.parameterization import ( Interval, @@ -25,7 +26,7 @@ from ansys.geometry.core.typing import Real, RealSequence -class Circle: +class Circle(Curve): """ Provides 3D ``Circle`` representation. @@ -209,9 +210,9 @@ def is_coincident_circle(self, other: "Circle") -> bool: and self.dir_z == other.dir_z ) - def get_parameterization(self) -> Parameterization: + def parameterization(self) -> Parameterization: """ - Return the parametrization of a ``Circle`` instance. + Return the parametrization of a ``Circle`` curve. The parameter of a circle specifies the clockwise angle around the axis (right hand corkscrew law), with a zero parameter at `dir_x` and a period of 2*pi. @@ -223,6 +224,12 @@ def get_parameterization(self) -> Parameterization: """ return Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) + def contains_param(self, param: Real) -> bool: # noqa: D102 + raise NotImplementedError("contains_param() is not implemented.") + + def contains_point(self, point: Point3D) -> bool: # noqa: D102 + raise NotImplementedError("contains_point() is not implemented.") + class CircleEvaluation(CurveEvaluation): """ diff --git a/src/ansys/geometry/core/geometry/curves/ellipse.py b/src/ansys/geometry/core/geometry/curves/ellipse.py index 4060f02779..f785c1aa70 100644 --- a/src/ansys/geometry/core/geometry/curves/ellipse.py +++ b/src/ansys/geometry/core/geometry/curves/ellipse.py @@ -8,6 +8,7 @@ from pint import Quantity from scipy.integrate import quad +from ansys.geometry.core.geometry.curves.curve import Curve from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation from ansys.geometry.core.geometry.parameterization import ( Interval, @@ -27,7 +28,7 @@ from ansys.geometry.core.typing import Real, RealSequence -class Ellipse: +class Ellipse(Curve): """ Provides 3D ``Ellipse`` representation. @@ -271,7 +272,7 @@ def transformed_copy(self, matrix: Matrix44) -> "Ellipse": UnitVector3D(new_axis[0:3]), ) - def get_parameterization(self) -> Parameterization: + def parameterization(self) -> Parameterization: """ Return the parametrization of an ``Ellipse`` instance. @@ -285,6 +286,12 @@ def get_parameterization(self) -> Parameterization: """ return Parameterization(ParamForm.PERIODIC, ParamType.OTHER, Interval(0, 2 * np.pi)) + def contains_param(self, param: Real) -> bool: # noqa: D102 + raise NotImplementedError("contains_param() is not implemented.") + + def contains_point(self, point: Point3D) -> bool: # noqa: D102 + raise NotImplementedError("contains_point() is not implemented.") + class EllipseEvaluation(CurveEvaluation): """ diff --git a/src/ansys/geometry/core/geometry/curves/line.py b/src/ansys/geometry/core/geometry/curves/line.py index 6e896a07a5..471228fae7 100644 --- a/src/ansys/geometry/core/geometry/curves/line.py +++ b/src/ansys/geometry/core/geometry/curves/line.py @@ -7,6 +7,7 @@ from beartype.typing import Union import numpy as np +from ansys.geometry.core.geometry.curves.curve import Curve from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation from ansys.geometry.core.geometry.parameterization import ( Interval, @@ -16,10 +17,10 @@ ) from ansys.geometry.core.math import Matrix44, Point3D, UnitVector3D, Vector3D from ansys.geometry.core.misc.accuracy import LENGTH_ACCURACY -from ansys.geometry.core.typing import RealSequence +from ansys.geometry.core.typing import Real, RealSequence -class Line: +class Line(Curve): """ Provides 3D ``Line`` representation. @@ -156,7 +157,7 @@ def is_opposite_line(self, other: "Line") -> bool: return self.direction.is_opposite(other.direction) return False - def get_parameterization(self) -> Parameterization: + def parameterization(self) -> Parameterization: """ Return the parametrization of a ``Line`` instance. @@ -170,6 +171,12 @@ def get_parameterization(self) -> Parameterization: """ return Parameterization(ParamForm.OPEN, ParamType.LINEAR, Interval(np.NINF, np.inf)) + def contains_param(self, param: Real) -> bool: # noqa: D102 + raise NotImplementedError("contains_param() is not implemented.") + + def contains_point(self, point: Point3D) -> bool: # noqa: D102 + raise NotImplementedError("contains_point() is not implemented.") + class LineEvaluation(CurveEvaluation): """Provides result class when evaluating a line.""" diff --git a/src/ansys/geometry/core/geometry/surfaces/cone.py b/src/ansys/geometry/core/geometry/surfaces/cone.py index 517392b653..5321a3666c 100644 --- a/src/ansys/geometry/core/geometry/surfaces/cone.py +++ b/src/ansys/geometry/core/geometry/surfaces/cone.py @@ -15,6 +15,7 @@ ParamType, ParamUV, ) +from ansys.geometry.core.geometry.surfaces.surface import Surface from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, @@ -28,7 +29,7 @@ from ansys.geometry.core.typing import Real, RealSequence -class Cone: +class Cone(Surface): """ Provides 3D ``Cone`` representation. @@ -218,37 +219,35 @@ def project_point(self, point: Point3D) -> "ConeEvaluation": return ConeEvaluation(self, ParamUV(u, v)) - def get_u_parameterization(self) -> Parameterization: + def parameterization(self) -> tuple[Parameterization, Parameterization]: """ - Retrieve the U parameter parametrization conditions. + Parameterization of the cone surface as a tuple (U and V respectively). The U parameter specifies the clockwise angle around the axis (right hand corkscrew law), with a zero parameter at `dir_x`, and a period of 2*pi. - Returns - ------- - Parameterization - Information about how a cone's u parameter is parameterized. - """ - return Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) - - def get_v_parameterization(self) -> Parameterization: - """ - Retrieve the V parameter parametrization conditions. - The V parameter specifies the distance along the axis, with a zero parameter at the XY plane of the Cone. Returns ------- - Parameterization - Information about how a cone's v parameter is parameterized. + tuple[Parameterization, Parameterization] + Information about how a cone's u and v parameters are parameterized, respectively. """ - # V parameter interval depends on which way the cone opens + u = Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) + start, end = ( (self.apex_param, np.inf) if self.apex_param < 0 else (np.NINF, self.apex_param) ) - return Parameterization(ParamForm.OPEN, ParamType.LINEAR, Interval(start, end)) + v = Parameterization(ParamForm.OPEN, ParamType.LINEAR, Interval(start, end)) + + return (u, v) + + def contains_param(self, param_uv: ParamUV) -> bool: # noqa: D102 + raise NotImplementedError("contains_param() is not implemented.") + + def contains_point(self, point: Point3D) -> bool: # noqa: D102 + raise NotImplementedError("contains_point() is not implemented.") class ConeEvaluation(SurfaceEvaluation): diff --git a/src/ansys/geometry/core/geometry/surfaces/cylinder.py b/src/ansys/geometry/core/geometry/surfaces/cylinder.py index 5745c13d50..9760b85cbd 100644 --- a/src/ansys/geometry/core/geometry/surfaces/cylinder.py +++ b/src/ansys/geometry/core/geometry/surfaces/cylinder.py @@ -16,6 +16,7 @@ ParamType, ParamUV, ) +from ansys.geometry.core.geometry.surfaces.surface import Surface from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, @@ -29,7 +30,7 @@ from ansys.geometry.core.typing import Real, RealSequence -class Cylinder: +class Cylinder(Surface): """ Provides 3D ``Cylinder`` representation. @@ -221,33 +222,31 @@ def project_point(self, point: Point3D) -> "CylinderEvaluation": return CylinderEvaluation(self, ParamUV(u, v)) - def get_u_parameterization(self) -> Parameterization: + def parameterization(self) -> tuple[Parameterization, Parameterization]: """ - Retrieve the U parameter parametrization conditions. + Parameterization of the cylinder surface as a tuple (U and V respectively). The U parameter specifies the clockwise angle around the axis (right hand corkscrew law), with a zero parameter at `dir_x`, and a period of 2*pi. - Returns - ------- - Parameterization - Information about how a cylinder's u parameter is parameterized. - """ - return Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) - - def get_v_parameterization(self) -> Parameterization: - """ - Retrieve the V parameter parametrization conditions. - The V parameter specifies the distance along the axis, with a zero parameter at the XY plane of the Cylinder. Returns ------- - Parameterization - Information about how a cylinders's v parameter is parameterized. + tuple[Parameterization, Parameterization] + Information about how a cylinder's u and v parameters are parameterized, respectively. """ - return Parameterization(ParamForm.OPEN, ParamType.LINEAR, Interval(np.NINF, np.inf)) + u = Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) + v = Parameterization(ParamForm.OPEN, ParamType.LINEAR, Interval(np.NINF, np.inf)) + + return (u, v) + + def contains_param(self, param_uv: ParamUV) -> bool: # noqa: D102 + raise NotImplementedError("contains_param() is not implemented.") + + def contains_point(self, point: Point3D) -> bool: # noqa: D102 + raise NotImplementedError("contains_point() is not implemented.") class CylinderEvaluation(SurfaceEvaluation): diff --git a/src/ansys/geometry/core/geometry/surfaces/sphere.py b/src/ansys/geometry/core/geometry/surfaces/sphere.py index a5fc68eaa3..8be62d2bce 100644 --- a/src/ansys/geometry/core/geometry/surfaces/sphere.py +++ b/src/ansys/geometry/core/geometry/surfaces/sphere.py @@ -14,6 +14,7 @@ ParamType, ParamUV, ) +from ansys.geometry.core.geometry.surfaces.surface import Surface from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, @@ -27,7 +28,7 @@ from ansys.geometry.core.typing import Real, RealSequence -class Sphere: +class Sphere(Surface): """ Provides 3D ``Sphere`` representation. @@ -186,34 +187,32 @@ def project_point(self, point: Point3D) -> "SphereEvaluation": v = np.arctan2(z, np.sqrt(x * x + y * y)) return SphereEvaluation(self, ParamUV(u, v)) - def get_u_parameterization(self) -> Parameterization: + def parameterization(self) -> tuple[Parameterization, Parameterization]: """ - Retrieve the U parameter parametrization conditions. + Parameterization of the sphere surface as a tuple (U and V respectively). The U parameter specifies the longitude angle, increasing clockwise (East) about `dir_z` (right hand corkscrew law). It has a zero parameter at `dir_x`, and a period of 2*pi. - Returns - ------- - Parameterization - Information about how a sphere's u parameter is parameterized. - """ - return Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) - - def get_v_parameterization(self) -> Parameterization: - """ - Retrieve the V parameter parametrization conditions. - The V parameter specifies the latitude, increasing North, with a zero parameter at the equator, and a range of [-pi/2, pi/2]. Returns ------- - Parameterization - Information about how a sphere's v parameter is parameterized. + tuple[Parameterization, Parameterization] + Information about how a sphere's u and v parameters are parameterized, respectively. """ - return Parameterization(ParamForm.CLOSED, ParamType.OTHER, Interval(-np.pi / 2, np.pi / 2)) + u = Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) + v = Parameterization(ParamForm.CLOSED, ParamType.OTHER, Interval(-np.pi / 2, np.pi / 2)) + + return (u, v) + + def contains_param(self, param_uv: ParamUV) -> bool: # noqa: D102 + raise NotImplementedError("contains_param() is not implemented.") + + def contains_point(self, point: Point3D) -> bool: # noqa: D102 + raise NotImplementedError("contains_point() is not implemented.") class SphereEvaluation(SurfaceEvaluation): diff --git a/src/ansys/geometry/core/geometry/surfaces/torus.py b/src/ansys/geometry/core/geometry/surfaces/torus.py index 4f2fe4546d..9a1a1de78b 100644 --- a/src/ansys/geometry/core/geometry/surfaces/torus.py +++ b/src/ansys/geometry/core/geometry/surfaces/torus.py @@ -15,6 +15,7 @@ ParamType, ParamUV, ) +from ansys.geometry.core.geometry.surfaces.surface import Surface from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, @@ -28,7 +29,7 @@ from ansys.geometry.core.typing import Real, RealSequence -class Torus: +class Torus(Surface): """ Provides 3D ``Torus`` representation. @@ -177,40 +178,32 @@ def evaluate(self, parameter: ParamUV) -> "TorusEvaluation": """ return TorusEvaluation(self, parameter) - def get_u_parameterization(self): + def parameterization(self) -> tuple[Parameterization, Parameterization]: """ - Retrieve the U parameter parametrization conditions. + Parameterization of the torus surface as a tuple (U and V respectively). The U parameter specifies the longitude angle, increasing clockwise (East) about the axis (right hand corkscrew law). It has a zero parameter at Geometry.Frame.DirX, and a period of 2*pi. - Returns - ------- - Parameterization - Information about how a sphere's u parameter is parameterized. - """ - return Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) - - def get_v_parameterization(self) -> Parameterization: - """ - Retrieve the V parameter parametrization conditions. - The V parameter specifies the latitude, increasing North, with a zero parameter - at the equator. For the donut, where the Geometry.Torus.MajorRadius is greater - than the Geometry.Torus.MinorRadius, the range is [-pi, pi] and the + at the equator. For the donut, where the major radius is greater + than the minor radius, the range is [-pi, pi] and the parameterization is periodic. For a degenerate torus, the range is restricted - accordingly and the parameterization is non- periodic. + accordingly and the parameterization is non-periodic. Returns ------- - Parameterization - Information about how a torus's v parameter is parameterized. + tuple[Parameterization, Parameterization] + Information about how a torus's u and v parameters are parameterized, respectively. """ - return Parameterization( + u = Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) + v = Parameterization( ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(-np.pi / 2, np.pi / 2) ) + return (u, v) + def project_point(self, point: Point3D) -> "TorusEvaluation": """ Project a point onto the torus and return its ``TorusEvaluation``. @@ -245,6 +238,12 @@ def project_point(self, point: Point3D) -> "TorusEvaluation": else: return TorusEvaluation(self, ParamUV(u + np.pi, v2)) + def contains_param(self, param_uv: ParamUV) -> bool: # noqa: D102 + raise NotImplementedError("contains_param() is not implemented.") + + def contains_point(self, point: Point3D) -> bool: # noqa: D102 + raise NotImplementedError("contains_point() is not implemented.") + class TorusEvaluation(SurfaceEvaluation): """ From 58ab3059f01e1f4d6f61b46524d63f702a261a0a Mon Sep 17 00:00:00 2001 From: jonahrb Date: Fri, 16 Jun 2023 11:39:55 -0400 Subject: [PATCH 04/76] fix component instance bug --- src/ansys/geometry/core/designer/component.py | 27 ++++++++++++++++--- src/ansys/geometry/core/designer/part.py | 12 ++++++++- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/ansys/geometry/core/designer/component.py b/src/ansys/geometry/core/designer/component.py index 9a6294780c..85e265ffaf 100644 --- a/src/ansys/geometry/core/designer/component.py +++ b/src/ansys/geometry/core/designer/component.py @@ -159,20 +159,19 @@ def __init__( template._transformed_part.part, template._transformed_part.transform, ) - tp.part.parts.append(tp) self._transformed_part = tp # Recurse - Create more children components from template's remaining children self.__create_children(template) - return elif not read_existing_comp: # This is an independent Component - Create new Part and MasterComponent p = Part(uuid.uuid4(), f"p_{name}", [], []) tp = MasterComponent(uuid.uuid4(), f"tp_{name}", p) - p.parts.append(tp) self._transformed_part = tp + self._transformed_part.occurrences.append(self) + @property def id(self) -> str: """ID of the component.""" @@ -336,7 +335,27 @@ def add_component(self, name: str, template: Optional["Component"] = None) -> "C Component New component with no children in the design assembly. """ - self._components.append(Component(name, self, self._grpc_client, template=template)) + new_comp = Component(name, self, self._grpc_client, template=template) + master = new_comp._transformed_part + master_id = new_comp.id.split("/")[-1] + + for comp in self._transformed_part.occurrences: + print(f"{comp.id} - {self.id}") + if comp.id != self.id: + print("here") + comp.components.append( + Component( + name, + comp, + self._grpc_client, + template, + preexisting_id=f"{comp.id}/{master_id}", + transformed_part=master, + read_existing_comp=True, + ) + ) + + self.components.append(new_comp) return self._components[-1] @protect_grpc diff --git a/src/ansys/geometry/core/designer/part.py b/src/ansys/geometry/core/designer/part.py index fa41306722..52495319e8 100644 --- a/src/ansys/geometry/core/designer/part.py +++ b/src/ansys/geometry/core/designer/part.py @@ -1,9 +1,12 @@ """Provides the ``Part`` class module.""" -from beartype.typing import List +from beartype.typing import TYPE_CHECKING, List from ansys.geometry.core.designer.body import MasterBody from ansys.geometry.core.math import IDENTITY_MATRIX44, Matrix44 +if TYPE_CHECKING: + from ansys.geometry.core.designer.component import Component + class Part: """ @@ -103,7 +106,9 @@ def __init__( self._id: str = id self._name: str = name self._part: Part = part + part.parts.append(self) self._transform: Matrix44 = transform + self._occurrences: List["Component"] = [] @property def id(self) -> str: @@ -115,6 +120,11 @@ def name(self) -> str: """Name of the transformed part.""" return self._name + @property + def occurrences(self) -> List["Component"]: + """All occurrences of this component.""" + return self._occurrences + @property def part(self) -> Part: """The master part of this transformed part.""" From 89eeb6f10c3e9826b330e55f5335807959f9691f Mon Sep 17 00:00:00 2001 From: jonahrb Date: Mon, 26 Jun 2023 13:02:25 -0400 Subject: [PATCH 05/76] temp changes to get hedgehog working --- src/ansys/geometry/core/designer/body.py | 25 +++++++++++-- src/ansys/geometry/core/designer/edge.py | 46 ++++++++++++++++++++++-- src/ansys/geometry/core/designer/face.py | 34 +++++++++++++++--- 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/src/ansys/geometry/core/designer/body.py b/src/ansys/geometry/core/designer/body.py index 7c74f674d1..cdbb705e34 100644 --- a/src/ansys/geometry/core/designer/body.py +++ b/src/ansys/geometry/core/designer/body.py @@ -540,7 +540,13 @@ def faces(self) -> List[Face]: # noqa: D102 self._grpc_client.log.debug(f"Retrieving faces for body {self.id} from server.") grpc_faces = self._bodies_stub.GetFaces(self._grpc_id) return [ - Face(grpc_face.id, SurfaceType(grpc_face.surface_type), self, self._grpc_client) + Face( + grpc_face.id, + SurfaceType(grpc_face.surface_type), + self, + self._grpc_client, + grpc_face.is_reversed, + ) for grpc_face in grpc_faces.faces ] @@ -550,7 +556,13 @@ def edges(self) -> List[Edge]: # noqa: D102 self._grpc_client.log.debug(f"Retrieving edges for body {self.id} from server.") grpc_edges = self._bodies_stub.GetEdges(self._grpc_id) return [ - Edge(grpc_edge.id, CurveType(grpc_edge.curve_type), self, self._grpc_client) + Edge( + grpc_edge.id, + CurveType(grpc_edge.curve_type), + self, + self._grpc_client, + grpc_edge.is_reversed, + ) for grpc_edge in grpc_edges.edges ] @@ -822,6 +834,7 @@ def faces(self) -> List[Face]: # noqa: D102 SurfaceType(grpc_face.surface_type), self, self._template._grpc_client, + grpc_face.is_reversed, ) for grpc_face in grpc_faces.faces ] @@ -832,7 +845,13 @@ def edges(self) -> List[Edge]: # noqa: D102 self._template._grpc_client.log.debug(f"Retrieving edges for body {self.id} from server.") grpc_edges = self._template._bodies_stub.GetEdges(EntityIdentifier(id=self.id)) return [ - Edge(grpc_edge.id, CurveType(grpc_edge.curve_type), self, self._template._grpc_client) + Edge( + grpc_edge.id, + CurveType(grpc_edge.curve_type), + self, + self._template._grpc_client, + grpc_edge.is_reversed, + ) for grpc_edge in grpc_edges.edges ] diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index d6106395b7..4afd767e16 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -2,6 +2,7 @@ from enum import Enum, unique +from ansys.api.geometry.v0.edges_pb2 import EvaluateRequest from ansys.api.geometry.v0.edges_pb2_grpc import EdgesStub from ansys.api.geometry.v0.models_pb2 import EntityIdentifier from beartype.typing import TYPE_CHECKING, List @@ -9,7 +10,9 @@ from ansys.geometry.core.connection import GrpcClient from ansys.geometry.core.errors import protect_grpc +from ansys.geometry.core.math import Point3D from ansys.geometry.core.misc import DEFAULT_UNITS +from ansys.geometry.core.typing import Real if TYPE_CHECKING: # pragma: no cover from ansys.geometry.core.designer.body import Body @@ -46,13 +49,21 @@ class Edge: Active supporting Geometry service instance for design modeling. """ - def __init__(self, id: str, curve_type: CurveType, body: "Body", grpc_client: GrpcClient): + def __init__( + self, + id: str, + curve_type: CurveType, + body: "Body", + grpc_client: GrpcClient, + is_reversed: bool = False, + ): """Initialize ``Edge`` class.""" self._id = id self._curve_type = curve_type self._body = body self._grpc_client = grpc_client self._edges_stub = EdgesStub(grpc_client.channel) + self._is_reversed = is_reversed @property def id(self) -> str: @@ -64,6 +75,11 @@ def _grpc_id(self) -> EntityIdentifier: """Entity identifier of this edge on the server side.""" return EntityIdentifier(id=self._id) + @property + def is_reversed(self) -> bool: + """Edge is reversed.""" + return self._is_reversed + @property @protect_grpc def length(self) -> Quantity: @@ -86,6 +102,32 @@ def faces(self) -> List["Face"]: self._grpc_client.log.debug("Requesting edge faces from server.") grpc_faces = self._edges_stub.GetFaces(self._grpc_id).faces return [ - Face(grpc_face.id, SurfaceType(grpc_face.surface_type), self._body, self._grpc_client) + Face( + grpc_face.id, + SurfaceType(grpc_face.surface_type), + self._body, + self._grpc_client, + grpc_face.is_reversed, + ) for grpc_face in grpc_faces ] + + @protect_grpc + def evaluate_proportion(self, param: Real) -> Point3D: + """ + Evaluate the edge at a given proportion, a value in the range [0, 1]. + + Parameters + ---------- + param: Real + The parameter at which to evaluate the edge. + + Returns + ------- + Point3D + The position of the evaluation. + """ + response = self._edges_stub.EvaluateProportion( + EvaluateRequest(id=self.id, param=param) + ).point + return Point3D([response.x, response.y, response.z], DEFAULT_UNITS.SERVER_LENGTH) diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index bfa06e581d..f29639a7df 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -3,14 +3,14 @@ from enum import Enum, unique from ansys.api.geometry.v0.edges_pb2_grpc import EdgesStub -from ansys.api.geometry.v0.faces_pb2 import EvaluateRequest, GetNormalRequest +from ansys.api.geometry.v0.faces_pb2 import EvaluateRequest, GetNormalRequest, ProjectPointRequest from ansys.api.geometry.v0.faces_pb2_grpc import FacesStub from ansys.api.geometry.v0.models_pb2 import Edge as GRPCEdge from ansys.api.geometry.v0.models_pb2 import EntityIdentifier from beartype.typing import TYPE_CHECKING, List from pint import Quantity -from ansys.geometry.core.connection import GrpcClient +from ansys.geometry.core.connection import GrpcClient, point3d_to_grpc_point from ansys.geometry.core.designer.edge import CurveType, Edge from ansys.geometry.core.errors import protect_grpc from ansys.geometry.core.math import Point3D, UnitVector3D @@ -124,7 +124,14 @@ class Face: Active supporting Geometry service instance for design modeling. """ - def __init__(self, id: str, surface_type: SurfaceType, body: "Body", grpc_client: GrpcClient): + def __init__( + self, + id: str, + surface_type: SurfaceType, + body: "Body", + grpc_client: GrpcClient, + is_reversed: bool = False, + ): """Initialize ``Face`` class.""" self._id = id self._surface_type = surface_type @@ -132,6 +139,7 @@ def __init__(self, id: str, surface_type: SurfaceType, body: "Body", grpc_client self._grpc_client = grpc_client self._faces_stub = FacesStub(grpc_client.channel) self._edges_stub = EdgesStub(grpc_client.channel) + self._is_reversed = is_reversed @property def id(self) -> str: @@ -143,6 +151,11 @@ def _grpc_id(self) -> EntityIdentifier: """Entity identifier of this face on the server side.""" return EntityIdentifier(id=self._id) + @property + def is_reversed(self) -> bool: + """Face is reversed.""" + return self._is_reversed + @property def body(self) -> "Body": """Body that the face belongs to.""" @@ -283,6 +296,19 @@ def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List[Edge]: edges = [] for edge_grpc in edges_grpc: edges.append( - Edge(edge_grpc.id, CurveType(edge_grpc.curve_type), self._body, self._grpc_client) + Edge( + edge_grpc.id, + CurveType(edge_grpc.curve_type), + self._body, + self._grpc_client, + edge_grpc.is_reversed, + ) ) return edges + + def project_point(self, point: Point3D) -> UnitVector3D: + """Project a point to the face.""" + response = self._faces_stub.ProjectPoint( + ProjectPointRequest(id=self.id, point=point3d_to_grpc_point(point)) + ) + return UnitVector3D([response.normal.x, response.normal.y, response.normal.z]) From b0f95255ed1e51dbad6ac148ebb974b9a746acfa Mon Sep 17 00:00:00 2001 From: Dastan Abdulla Date: Tue, 15 Aug 2023 02:02:05 -0400 Subject: [PATCH 06/76] surface and curve evaluation with respect to direction --- src/ansys/geometry/core/designer/edge.py | 61 +++++- src/ansys/geometry/core/designer/face.py | 98 +++++++-- src/ansys/geometry/core/geometry/box_uv.py | 170 +++++++++++++++ .../core/geometry/curves/trimmed_curve.py | 49 +++++ .../core/geometry/parameterization.py | 132 ++++++++++++ .../geometry/core/geometry/surfaces/plane.py | 204 ++++++++++++++++++ .../core/geometry/surfaces/trimmed_surface.py | 100 +++++++++ src/ansys/geometry/core/misc/accuracy.py | 25 +++ 8 files changed, 818 insertions(+), 21 deletions(-) create mode 100644 src/ansys/geometry/core/geometry/box_uv.py create mode 100644 src/ansys/geometry/core/geometry/curves/trimmed_curve.py create mode 100644 src/ansys/geometry/core/geometry/surfaces/plane.py create mode 100644 src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 4afd767e16..b63bde3b52 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -10,7 +10,13 @@ from ansys.geometry.core.connection import GrpcClient from ansys.geometry.core.errors import protect_grpc +from ansys.geometry.core.geometry.curves.circle import Circle +from ansys.geometry.core.geometry.curves.curve import Curve +from ansys.geometry.core.geometry.curves.ellipse import Ellipse +from ansys.geometry.core.geometry.curves.line import Line +from ansys.geometry.core.geometry.curves.trimmed_curve import TrimmedCurve from ansys.geometry.core.math import Point3D +from ansys.geometry.core.math.vector import UnitVector3D from ansys.geometry.core.misc import DEFAULT_UNITS from ansys.geometry.core.typing import Real @@ -64,6 +70,50 @@ def __init__( self._grpc_client = grpc_client self._edges_stub = EdgesStub(grpc_client.channel) self._is_reversed = is_reversed + self._shape = TrimmedCurve(self) + # request the underlying curve from the server + self._grpc_client.log.debug("Requesting edge properties from server.") + curve_response = self._edges_stub.GetCurve(self._grpc_id) + origin = Point3D( + [curve_response.origin.x, curve_response.origin.y, curve_response.origin.z] + ) + # check if the curve is a circle or ellipse + if ( + self.curve_type == CurveType.CURVETYPE_CIRCLE + or self.curve_type == CurveType.CURVETYPE_ELLIPSE + ): + axis_response = curve_response.axis + reference_response = curve_response.reference + axis = UnitVector3D([axis_response.x, axis_response.y, axis_response.z]) + reference = UnitVector3D( + [reference_response.x, reference_response.y, reference_response.z] + ) + if self.curve_type == CurveType.CURVETYPE_CIRCLE: + # circle + self._curve = Circle(origin, curve_response.radius, reference, axis) + else: + # ellipse + self._curve = Ellipse( + origin, + curve_response.major_radius, + curve_response.minor_radius, + reference, + axis, + ) + elif self.curve_type == CurveType.CURVETYPE_LINE: + # line + self._curve = Line( + origin, + UnitVector3D( + [ + curve_response.direction.x, + curve_response.direction.y, + curve_response.direction.z, + ] + ), + ) + else: + self._curve = None @property def id(self) -> str: @@ -80,6 +130,16 @@ def is_reversed(self) -> bool: """Edge is reversed.""" return self._is_reversed + @property + def curve(self) -> Curve: + """Internal curve object.""" + return self._curve + + @property + def shape(self) -> TrimmedCurve: + """Internal Trimmed Curve object.""" + return self._shape + @property @protect_grpc def length(self) -> Quantity: @@ -121,7 +181,6 @@ def evaluate_proportion(self, param: Real) -> Point3D: ---------- param: Real The parameter at which to evaluate the edge. - Returns ------- Point3D diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index f29639a7df..31ad9c8ba7 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -3,21 +3,30 @@ from enum import Enum, unique from ansys.api.geometry.v0.edges_pb2_grpc import EdgesStub -from ansys.api.geometry.v0.faces_pb2 import EvaluateRequest, GetNormalRequest, ProjectPointRequest +from ansys.api.geometry.v0.faces_pb2 import EvaluateRequest, GetNormalRequest from ansys.api.geometry.v0.faces_pb2_grpc import FacesStub from ansys.api.geometry.v0.models_pb2 import Edge as GRPCEdge from ansys.api.geometry.v0.models_pb2 import EntityIdentifier from beartype.typing import TYPE_CHECKING, List from pint import Quantity -from ansys.geometry.core.connection import GrpcClient, point3d_to_grpc_point -from ansys.geometry.core.designer.edge import CurveType, Edge +from ansys.geometry.core.connection import GrpcClient from ansys.geometry.core.errors import protect_grpc + +# surfaces +from ansys.geometry.core.geometry.surfaces.cone import Cone +from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder +from ansys.geometry.core.geometry.surfaces.plane import Plane +from ansys.geometry.core.geometry.surfaces.sphere import Sphere +from ansys.geometry.core.geometry.surfaces.surface import Surface +from ansys.geometry.core.geometry.surfaces.torus import Torus +from ansys.geometry.core.geometry.surfaces.trimmed_surface import TrimmedSurface from ansys.geometry.core.math import Point3D, UnitVector3D from ansys.geometry.core.misc import DEFAULT_UNITS if TYPE_CHECKING: # pragma: no cover from ansys.geometry.core.designer.body import Body + from ansys.geometry.core.designer.edge import Edge @unique @@ -71,7 +80,7 @@ def __init__( length: Quantity, min_bbox: Point3D, max_bbox: Point3D, - edges: List[Edge], + edges: List["Edge"], ): """Initialize ``FaceLoop`` class.""" self._type = type @@ -101,7 +110,7 @@ def max_bbox(self) -> Point3D: return self._max_bbox @property - def edges(self) -> List[Edge]: + def edges(self) -> List["Edge"]: """Edges contained in the loop.""" return self._edges @@ -140,6 +149,58 @@ def __init__( self._faces_stub = FacesStub(grpc_client.channel) self._edges_stub = EdgesStub(grpc_client.channel) self._is_reversed = is_reversed + self._shape = TrimmedSurface(self) + # request the underlying surface from the server + self._grpc_client.log.debug("Requesting surface properties from server.") + surface_response = self._faces_stub.GetSurface(self._grpc_id) + origin = surface_response.origin + axis_response = surface_response.axis + reference_response = surface_response.reference + axis = UnitVector3D([axis_response.x, axis_response.y, axis_response.z]) + reference = UnitVector3D([reference_response.x, reference_response.y, reference_response.z]) + if self.surface_type == SurfaceType.SURFACETYPE_CONE: + # cone + self._surface = Cone( + Point3D([origin.x, origin.y, origin.z], DEFAULT_UNITS.SERVER_LENGTH), + surface_response.radius, + surface_response.half_angle, + reference, + axis, + ) + elif self.surface_type == SurfaceType.SURFACETYPE_CYLINDER: + # cylinder + self._surface = Cylinder( + Point3D([origin.x, origin.y, origin.z], DEFAULT_UNITS.SERVER_LENGTH), + surface_response.radius, + reference, + axis, + ) + elif self.surface_type == SurfaceType.SURFACETYPE_SPHERE: + # sphere + self._surface = Sphere( + Point3D([origin.x, origin.y, origin.z], DEFAULT_UNITS.SERVER_LENGTH), + surface_response.radius, + reference, + axis, + ) + elif self.surface_type == SurfaceType.SURFACETYPE_TORUS: + # torus + self._surface = Torus( + Point3D([origin.x, origin.y, origin.z], DEFAULT_UNITS.SERVER_LENGTH), + surface_response.major_radius, + surface_response.minor_radius, + reference, + axis, + ) + elif self.surface_type == SurfaceType.SURFACETYPE_PLANE: + # plane + self._surface = Plane( + Point3D([origin.x, origin.y, origin.z], DEFAULT_UNITS.SERVER_LENGTH), + reference, + axis, + ) + else: + self._surface = None @property def id(self) -> str: @@ -162,21 +223,23 @@ def body(self) -> "Body": return self._body @property - @protect_grpc - def area(self) -> Quantity: - """Calculated area of the face.""" - self._grpc_client.log.debug("Requesting face area from server.") - area_response = self._faces_stub.GetArea(self._grpc_id) - return Quantity(area_response.area, DEFAULT_UNITS.SERVER_AREA) + def shape(self) -> TrimmedSurface: + """Internal TrimmedSurface instance.""" + return self._shape @property def surface_type(self) -> SurfaceType: """Surface type of the face.""" return self._surface_type + @property + def surface(self) -> Surface: + """Surface type of the face.""" + return self._surface + @property @protect_grpc - def edges(self) -> List[Edge]: + def edges(self) -> List["Edge"]: """Get all edges of the face.""" self._grpc_client.log.debug("Requesting face edges from server.") edges_response = self._faces_stub.GetEdges(self._grpc_id) @@ -280,7 +343,7 @@ def face_point(self, u: float = 0.5, v: float = 0.5) -> Point3D: response = self._faces_stub.Evaluate(EvaluateRequest(id=self.id, u=u, v=v)).point return Point3D([response.x, response.y, response.z], DEFAULT_UNITS.SERVER_LENGTH) - def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List[Edge]: + def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List["Edge"]: """Transform a list of gRPC edge messages into actual ``Edge`` objects. Parameters @@ -293,6 +356,8 @@ def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List[Edge]: List[Edge] ``Edge`` objects to obtain from gRPC messages. """ + from ansys.geometry.core.designer.edge import CurveType, Edge + edges = [] for edge_grpc in edges_grpc: edges.append( @@ -305,10 +370,3 @@ def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List[Edge]: ) ) return edges - - def project_point(self, point: Point3D) -> UnitVector3D: - """Project a point to the face.""" - response = self._faces_stub.ProjectPoint( - ProjectPointRequest(id=self.id, point=point3d_to_grpc_point(point)) - ) - return UnitVector3D([response.normal.x, response.normal.y, response.normal.z]) diff --git a/src/ansys/geometry/core/geometry/box_uv.py b/src/ansys/geometry/core/geometry/box_uv.py new file mode 100644 index 0000000000..0ef13afb5a --- /dev/null +++ b/src/ansys/geometry/core/geometry/box_uv.py @@ -0,0 +1,170 @@ +"""provides the ``BoxUV`` class.""" +from enum import Enum + +from ansys.geometry.core.geometry.parameterization import Interval, ParamUV +from ansys.geometry.core.typing import Real + + +class LocationUV(Enum): + """provides the ``LocationUV`` class to indicate locations for BoxUV.""" + + TopLeft = 1 + TopCenter = 2 + TopRight = 3 + BottomLeft = 4 + BottomCenter = 5 + BottomRight = 6 + LeftCenter = 7 + RightCenter = 8 + Center = 9 + + +class BoxUV: + """BoxUV class.""" + + def __init__(self, rangeU: Interval = None, rangeV: Interval = None) -> None: + """Root constructor for BoxUV.""" + if rangeV is not None: + self.interval_v = rangeV + if rangeU is not None: + self.interval_u = rangeU + + @classmethod + def from_param(cls, param: ParamUV): + """Secondary constructor for BoxUV using a ParamUV object type.""" + return cls(Interval(param.U, param.U), Interval(param.V, param.V)) + + @classmethod + def from_two_params(cls, param1: ParamUV, param2: ParamUV): + """Secondary constructor for BoxUV using two ParamUV object types.""" + return cls( + Interval(min(param1.U, param2.U), max(param1.U, param2.U)), + Interval(min(param1.V, param2.V), max(param1.V, param2.V)), + ) + + @property + def IntervalU(self) -> Interval: + """Return the u interval.""" + return self.interval_u + + @property + def IntervalV(self) -> Interval: + """Return the v interval.""" + return self.interval_v + + def __eq__(self, other: object) -> bool: + """Check whether two BoxUV instances are equal.""" + if not isinstance(other, BoxUV): + # don't attempt to compare against unrelated types + return NotImplemented + return self.IntervalU.__eq__(other.IntervalU) and self.IntervalV.__eq__(other.IntervalV) + + def __ne__(self, other: object) -> bool: + """Check whether two BoxUV instances are not equal.""" + if not isinstance(other, BoxUV): + # don't attempt to compare against unrelated types + return NotImplemented + return not self.IntervalU.__eq__(other.IntervalU) or not self.IntervalV.__eq__( + other.IntervalV + ) + + def is_empty(self): + """Return whether this BoxUV is empty.""" + return self.IntervalU.is_empty() or self.IntervalV.is_empty() + + def proportion(self, prop_u: Real, prop_v: Real) -> ParamUV: + """Evaluate the BoxUV at the given proportions.""" + return ParamUV( + self.IntervalU.get_relative_val(prop_u), self.IntervalV.get_relative_val(prop_v) + ) + + def get_center(self) -> ParamUV: + """Evaluate the BoxUV in the middle.""" + return self.proportion(0.5, 0.5) + + def is_negative(self, tolerance_u: Real, tolerance_v: Real) -> bool: + """Check whether the BoxUV is negative.""" + if self.is_empty(): + return False + return self.IntervalU.is_negative(tolerance_u) or self.IntervalV.is_negative(tolerance_v) + + @staticmethod + def unite(first: "BoxUV", second: "BoxUV") -> "BoxUV": + """Return the union of two BoxUV instances.""" + if first.is_empty(): + return second + if second.is_empty(): + return first + return BoxUV( + Interval.unite(first.IntervalU, second.IntervalU), + Interval.unite(first.IntervalV, second.IntervalV), + ) + + @staticmethod + def Intersect(first: "BoxUV", second: "BoxUV", toleranceU: Real, toleranceV: Real) -> "BoxUV": + """Return the intersection of two BoxUV instances.""" + if first.is_empty() or second.is_empty(): + return None # supposed to be empty + intersection = BoxUV( + Interval.intersect(first.IntervalU, second.IntervalU, toleranceU), + Interval.intersect(first.IntervalV, second.IntervalV, toleranceV), + ) + if not intersection.is_negative(toleranceU, toleranceV): + return intersection + return None # supposed to be empty + + def contains(self, param: ParamUV) -> bool: + """Check whether the BoxUV contains a given u and v pair parameter.""" + if self.is_empty(): + # throw Error.InvalidMethodOnEmptyObjectException(GetType()) + raise Exception("Invalid Method On Empty Object Exception" + type(self).__name__) + return self.IntervalU.contains(param.u) and self.IntervalV.contains(param.v) + + def inflate(self, deltaU: Real, deltaV: Real) -> "BoxUV": + """Enlarge the BoxUV u and v intervals by deltaU and deltaV respectively.""" + if self.is_empty(): + # throw Error.InvalidMethodOnEmptyObjectException(GetType()) + raise Exception("Invalid Method On Empty Object Exception" + type(self).__name__) + return BoxUV(self.InteravlU.inflate(deltaU), self.InteravlV.inflate(deltaV)) + + def inflate(self, delta: Real) -> "BoxUV": + """Enlarge the BoxUV by a given delta.""" + if self.is_empty(): + # throw Error.InvalidMethodOnEmptyObjectException(GetType()) + raise Exception("Invalid Method On Empty Object Exception" + type(self).__name__) + return BoxUV(self.InteravlU.inflate(delta), self.InteravlV.inflate(delta)) + + def get_corner(self, location: LocationUV) -> ParamUV: + """Return the corner location of the BoxUV.""" + u = 0 + v = 0 + if ( + location == LocationUV.TopLeft + or location == LocationUV.BottomLeft + or location == LocationUV.LeftCenter + ): + u = self.IntervalU.get_relative_val(0) + elif ( + location == LocationUV.TopRight + or location == LocationUV.BottomRight + or location == LocationUV.RightCenter + ): + u = self.IntervalU.get_relative_val(1) + else: + u = self.IntervalU.get_relative_val(0.5) + + if ( + location == LocationUV.BottomRight + or location == LocationUV.BottomLeft + or location == LocationUV.BottomCenter + ): + v = self.IntervalU.get_relative_val(0) + elif ( + location == LocationUV.TopRight + or location == LocationUV.TopLeft + or location == LocationUV.TopCenter + ): + v = self.IntervalU.get_relative_val(1) + else: + v = self.IntervalU.get_relative_val(0.5) + return ParamUV(u, v) diff --git a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py new file mode 100644 index 0000000000..09482f862a --- /dev/null +++ b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py @@ -0,0 +1,49 @@ +"""Trimmed curve class.""" +from beartype.typing import TYPE_CHECKING +from pint import Quantity + +from ansys.geometry.core.errors import protect_grpc +from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.geometry.parameterization import Interval +from ansys.geometry.core.math import Point3D +from ansys.geometry.core.misc.measurements import DEFAULT_UNITS +from ansys.geometry.core.typing import Real + +if TYPE_CHECKING: + from ansys.geometry.core.designer.edge import Edge + + +class TrimmedCurve: + """TrimmedCurve class.""" + + def __init__(self, desEdge: "Edge") -> None: + """Construct the TrimmedCurve using the Edge object argument.""" + self.edge = desEdge + + @property + @protect_grpc + def length(self) -> Quantity: + """Calculated length of the edge.""" + self.edge._grpc_client.log.debug("Requesting edge length from server.") + length_response = self.edge._edges_stub.GetLength(self._grpc_id) + return Quantity(length_response.length, DEFAULT_UNITS.SERVER_LENGTH) + + @property + @protect_grpc + def interval(self) -> Interval: + """Calculated interval of the edge.""" + self.edge._grpc_client.log.debug("Requesting edge interval from server.") + interva_response = self.edge._edges_stub.GetInterval(self.edge._grpc_id) + return Interval(interva_response.start, interva_response.end) + + def evaluate(self, param: Real) -> Point3D: + """Evaluate the curve with respect to the curve direction (reversed or not).""" + eval = self.eval_proportion(param) + if self.edge.is_reversed: + eval = self.eval_proportion(1 - param) + return eval.position + + def eval_proportion(self, param: Real) -> CurveEvaluation: + """Evaluate the given curve at the given parameter.""" + bounds = self.interval + return self.edge.curve.evaluate(bounds.start + bounds.get_span() * param) diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py index 12463b3434..96e6885dcc 100644 --- a/src/ansys/geometry/core/geometry/parameterization.py +++ b/src/ansys/geometry/core/geometry/parameterization.py @@ -5,6 +5,7 @@ from beartype import beartype as check_input_types import numpy as np +from ansys.geometry.core.misc.accuracy import Accuracy from ansys.geometry.core.typing import Real @@ -134,6 +135,7 @@ def __init__(self, start: Real, end: Real) -> None: self._start = start self._end = end + self.not_empty = True @property def start(self) -> Real: @@ -145,6 +147,18 @@ def end(self) -> Real: """End value of the interval.""" return self._end + def __eq__(self, other: object): + """Compare two intervals.""" + if not isinstance(other, Interval): + # don't attempt to compare against unrelated types + return NotImplemented + if self.is_empty() or other.is_empty(): + return self.is_empty() and other.is_empty() + + return Accuracy.equal_doubles(self.start, other.start) and Accuracy.equal_doubles( + self.end, other.end + ) + def is_open(self) -> bool: """ If the interval is open (-inf, inf). @@ -167,6 +181,16 @@ def is_closed(self) -> bool: """ return self.start > np.NINF and self.end < np.inf + def is_empty(self) -> bool: + """ + If the current interval is empty return true, else return false. + + Returns: + Bool + The value that indicates whether the interval is empty or not. + """ + return not self.not_empty + def get_span(self) -> Real: """ Return the quantity contained by the interval. Interval must be closed. @@ -181,6 +205,114 @@ def get_span(self) -> Real: return self.end - self.start + def get_relative_val(self, t: Real) -> Real: + """ + Return an evaluation property of the interval, used in BoxUV. + + Args: + t (Real): The offset that the interval gets evaluated at. + + Returns: + Real: The actual value according to the offset + """ + return self.start + t * self.get_span() + + def is_negative(self, tolerance: Real) -> bool: + """ + Boolean value that indicates whether the current interval is negative. + + Args: + tolerance (Real): The accepted range since we could be working with doubles + + Returns: + bool: True if negative False otherwise + """ + return Accuracy.compare_with_tolerance(self.get_span(), 0, tolerance, tolerance) + + @staticmethod + def unite(first: "Interval", second: "Interval") -> "Interval": + """ + Return the union of two intervals. + + Args: + first (Interval): First Interval + second (Interval): Second Interval + + Returns: + Interval: The union of the two intervals + """ + if first.is_empty(): + return second + if second.is_empty(): + return first + return Interval(min(first.start, second.start), max(first.end, second.end)) + + @staticmethod + def Intersect(first: "Interval", second: "Interval", tolerance: Real) -> "Interval": + """ + Return the intersection of two intervals. + + Args: + first (Interval): First Interval + second (Interval): Second Interval + + Returns: + Interval: The intersection of the two intervals + """ + if first.is_empty() or second.is_empty(): + return None # supposed to be empty + intersection = Interval(max(first.start, second.start), min(first.end, second.send)) + if not intersection.is_negative(tolerance): + return intersection + return None # supposed to be empty + + def contains(self, t: Real, accuracy: Real) -> bool: + """ + Check whether the current interval contains a value (t). + + Args: + t (Real): The value of interest + accuracy (Real): The accepted range of error since we could be working with floats + + Returns: + bool: True if the interval contains the value, false otherwise + """ + if self.is_empty(): + return False + negative_abs_accuracy = -abs(accuracy) + if self.start > self.end: + if self.start - t < negative_abs_accuracy: + return False + if t - self.end < negative_abs_accuracy: + return False + else: + if t - self.start < negative_abs_accuracy: + return False + if self.end - t < negative_abs_accuracy: + return False + return True + + def contains(self, t: Real) -> bool: + """ + Check whether the current interval contains a value (t) using the default. + + length_accuracy constant. + + Args: + t (Real): The value of interest + + Returns: + bool: True if the interval contains the value, false otherwise + """ + return self.contains(t, Accuracy.length_accuracy) + + def inflate(self, delta: Real) -> "Interval": + """Enlarge the current interval by the given delta value.""" + if self.is_empty(): + # throw Error.InvalidMethodOnEmptyObjectException(GetType()) + raise Exception("Invalid Method On Empty Object Exception" + type(self).__name__) + return Interval(self.start - delta, self.end + delta) + def __repr__(self) -> str: """Represent the ``Interval`` as a string.""" return f"Interval(start={self.start}, end={self.end})" diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py new file mode 100644 index 0000000000..cfeeac301b --- /dev/null +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -0,0 +1,204 @@ +"""The plane surface class.""" +from functools import cached_property + +from beartype import beartype as check_input_types +from beartype.typing import Union +import numpy as np + +from ansys.geometry.core.geometry.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, + ParamUV, +) +from ansys.geometry.core.geometry.surfaces.surface import Surface +from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation +from ansys.geometry.core.math import ( + UNITVECTOR3D_X, + UNITVECTOR3D_Z, + Matrix44, + Point3D, + UnitVector3D, + Vector3D, +) +from ansys.geometry.core.typing import Real, RealSequence + + +class Plane(Surface): + """ + Provides 3D ``Plane`` representation. + + Parameters + ---------- + origin : Union[~numpy.ndarray, RealSequence, Point3D], + Centered origin of the torus. + reference : Union[~numpy.ndarray, RealSequence, UnitVector3D, Vector3D] + X-axis direction. + axis : Union[~numpy.ndarray, RealSequence, UnitVector3D, Vector3D] + X-axis direction. + """ + + def __init__( + self, + origin: Union[np.ndarray, RealSequence, Point3D], + reference: Union[np.ndarray, RealSequence, UnitVector3D, Vector3D] = UNITVECTOR3D_X, + axis: Union[np.ndarray, RealSequence, UnitVector3D, Vector3D] = UNITVECTOR3D_Z, + ): + """Initialize ``Plane`` class.""" + self._origin = Point3D(origin) if not isinstance(origin, Point3D) else origin + + self._reference = ( + UnitVector3D(reference) if not isinstance(reference, UnitVector3D) else reference + ) + self._axis = UnitVector3D(axis) if not isinstance(axis, UnitVector3D) else axis + if not self._reference.is_perpendicular_to(self._axis): + raise ValueError("Plane reference (dir_x) and axis (dir_z) must be perpendicular.") + + @property + def dir_x(self) -> UnitVector3D: + """X-direction of the cylinder.""" + return self._reference + + @property + def dir_y(self) -> UnitVector3D: + """Y-direction of the cylinder.""" + return self.dir_z.cross(self.dir_x) + + @property + def dir_z(self) -> UnitVector3D: + """Z-direction of the cylinder.""" + return self._axis + + @check_input_types + def __eq__(self, other: "Plane") -> bool: + """Check whether two planes are equal.""" + return ( + self._origin == other._origin + and self._reference == other._reference + and self._axis == other._axis + ) + + def contains_param(self, param_uv: ParamUV) -> bool: + """Check whether the plane contains a u and v pair point.""" + raise NotImplementedError("contains_param() is not implemented.") + + def contains_point(self, point: Point3D) -> bool: + """Check whether the plane contains a 3D point.""" + raise NotImplementedError("contains_point() is not implemented.") + + def parameterization(self) -> tuple[Parameterization, Parameterization]: + """Return plane parametrization.""" + u = Parameterization(ParamForm.OPEN, ParamType.LINEAR, Interval(np.NINF, np.inf)) + v = Parameterization(ParamForm.OPEN, ParamType.LINEAR, Interval(np.NINF, np.inf)) + + return (u, v) + + def project_point(self, point: Point3D) -> SurfaceEvaluation: + """Evaluate the plane at a given 3D point.""" + origin_to_point = point - self._origin + u = origin_to_point.dot(self.dir_x) + v = origin_to_point.dot(self.dir_y) + return PlaneEvaluation(self, ParamUV(u, v)) + + def transformed_copy(self, matrix: Matrix44) -> Surface: + """Return transformed version of the plane given the transform matrix.""" + new_point = self.origin.transform(matrix) + new_reference = self._reference.transform(matrix) + new_axis = self._axis.transform(matrix) + return Plane( + new_point, + UnitVector3D(new_reference[0:3]), + UnitVector3D(new_axis[0:3]), + ) + + def evaluate(self, parameter: ParamUV) -> "PlaneEvaluation": + """Evaluate the plane at a given u and v parameter.""" + return PlaneEvaluation(self, parameter) + + +class PlaneEvaluation(SurfaceEvaluation): + """ + Provides ``Plane`` evaluation at certain parameters. + + Parameters + ---------- + plane: ~ansys.geometry.core.primitives.plane.Plane + The ``Plane`` object to be evaluated. + parameter: ParamUV + The parameters (u, v) at which the ``Plane`` evaluation is requested. + """ + + def __init__(self, plane: Plane, parameter: ParamUV) -> None: + """``SphereEvaluation`` class constructor.""" + self._plane = plane + self._parameter = parameter + + @property + def plane(self) -> Plane: + """The plane being evaluated.""" + return self._plane + + @property + def parameter(self) -> ParamUV: + """The parameter that the evaluation is based upon.""" + return self._parameter + + @cached_property + def position(self) -> Point3D: + """The point on the surface, based on the evaluation.""" + return ( + self.plane.origin + + self.parameter.u * self.plane.dir_x + + self.parameter.v * self.plane.dir_y + ) + + @cached_property + def normal(self) -> UnitVector3D: + """The normal to the surface.""" + return self.plane.dir_z + + @cached_property + def u_derivative(self) -> Vector3D: + """The first derivative with respect to u.""" + return self.plane.dir_z + + @cached_property + def v_derivative(self) -> Vector3D: + """The first derivative with respect to v.""" + return self.plane.dir_y + + @cached_property + def uu_derivative(self) -> Vector3D: + """The second derivative with respect to u.""" + return Vector3D([0, 0, 0]) + + @cached_property + def uv_derivative(self) -> Vector3D: + """The second derivative with respect to u and v.""" + return Vector3D([0, 0, 0]) + + @cached_property + def vv_derivative(self) -> Vector3D: + """The second derivative with respect to v.""" + return Vector3D([0, 0, 0]) + + @cached_property + def min_curvature(self) -> Real: + """The minimum curvature.""" + return 0 + + @cached_property + def min_curvature_direction(self) -> UnitVector3D: + """The minimum curvature direction.""" + return self.plane.dir_x + + @cached_property + def max_curvature(self) -> Real: + """The maximum curvature.""" + return 0 + + @cached_property + def max_curvature_direction(self) -> UnitVector3D: + """The maximum curvature direction.""" + return self.plane.dir_y diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py new file mode 100644 index 0000000000..8d654a0307 --- /dev/null +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -0,0 +1,100 @@ +"""Provides the ``TrimmedSurface`` class.""" + +from ansys.api.geometry.v0.faces_pb2 import ProjectPointRequest +from beartype.typing import TYPE_CHECKING +from pint import Quantity + +from ansys.geometry.core.connection.conversions import point3d_to_grpc_point +from ansys.geometry.core.errors import protect_grpc +from ansys.geometry.core.geometry.box_uv import BoxUV +from ansys.geometry.core.geometry.parameterization import Interval, ParamUV +from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation +from ansys.geometry.core.math import Point3D +from ansys.geometry.core.math.vector import UnitVector3D +from ansys.geometry.core.misc.measurements import DEFAULT_UNITS +from ansys.geometry.core.typing import Real + +if TYPE_CHECKING: + from ansys.geometry.core.designer.face import Face + + +class TrimmedSurface: + """TrimmedSurface class.""" + + def __init__(self, desFace: "Face") -> None: + """Construct the TrimmedSurface using the Face object argument.""" + self.face = desFace + + @property + @protect_grpc + def area(self) -> Quantity: + """Calculated area of the face.""" + self.face._grpc_client.log.debug("Requesting face area from server.") + area_response = self.face._faces_stub.GetArea(self._grpc_id) + return Quantity(area_response.area, DEFAULT_UNITS.SERVER_AREA) + + @property + def boxUV(self) -> BoxUV: + """Calculated box UV of the face.""" + self.face._grpc_client.log.debug("Requesting box UV from server.") + box_response = self.face._faces_stub.GetBoxUV(self.face._grpc_id) + startU = box_response.start_u + endU = box_response.end_u + startV = box_response.start_v + endV = box_response.end_v + return BoxUV(Interval(startU, endU), Interval(startV, endV)) + + def normal(self, u: float = 0.5, v: float = 0.5) -> UnitVector3D: + """ + Get the normal direction to the face evaluated at certain UV coordinates. + + Notes + ----- + To properly use this method, you must handle UV coordinates. Thus, you must + know how these relate to the underlying Geometry service. It is an advanced + method for Geometry experts only. + + Parameters + ---------- + u : float, default: 0.5 + First coordinate of the 2D representation of a surface in UV space. + The default is the center of the surface. + v : float, default: 0.5 + Second coordinate of the 2D representation of a surface in UV space. + The default is the center of the surface. + + Returns + ------- + UnitVector3D + The :class:`UnitVector3D ` + object evaluated at the given U and V coordinates. + This :class:`UnitVector3D ` + object is perpendicular to the surface at the given UV coordinates. + """ + direction = self.eval_proportions(u, v).normal + if self.face.is_reversed: + return UnitVector3D([-direction.x, -direction.y, -direction.z]) + return UnitVector3D([direction.x, direction.y, direction.z]) + + def project_point(self, point: Point3D): + """Project a point to the face.""" + response = self.face._faces_stub.ProjectPoint( + ProjectPointRequest(id=self.face.id, point=point3d_to_grpc_point(point)) + ) + boundsU = self.boxUV.IntervalU + boundsV = self.boxUV.IntervalV + return ( + (response.param_u - boundsU.start) / boundsU.get_span(), + (response.param_v - boundsV.start) / boundsV.get_span(), + ) + + def eval_proportions(self, proportionU: Real, proportionV: Real) -> SurfaceEvaluation: + """Evaluate the surface at a given u and v value.""" + boundsU = self.boxUV.IntervalU + boundsV = self.boxUV.IntervalV + return self.face.surface.evaluate( + ParamUV( + boundsU.start + boundsU.get_span() * proportionU, + boundsV.start + boundsV.get_span() * proportionV, + ) + ) diff --git a/src/ansys/geometry/core/misc/accuracy.py b/src/ansys/geometry/core/misc/accuracy.py index d91918537d..05ef9c3feb 100644 --- a/src/ansys/geometry/core/misc/accuracy.py +++ b/src/ansys/geometry/core/misc/accuracy.py @@ -11,10 +11,18 @@ ANGLE_ACCURACY = 1e-6 """Constant for decimal accuracy in angle comparisons.""" +DOUBLE_ACCURACY = 1e-13 +"""Constant for double accuracy.""" + class Accuracy: """Provides decimal precision evaluations for actions such as equivalency.""" + @property + def length_accuracy() -> Real: + """Return the LENGTH_ACCURACY constant.""" + return LENGTH_ACCURACY + def length_is_equal(comparison_length: Real, reference_length: Real) -> bool: """ Check if the comparison length is equal to the reference length. @@ -33,6 +41,23 @@ def length_is_equal(comparison_length: Real, reference_length: Real) -> bool: comparison_length, reference_length, LENGTH_ACCURACY, LENGTH_ACCURACY ) + def equal_doubles(a: Real, b: Real): + """Compare two double values.""" + return Accuracy.is_within_tolerance(a, b, DOUBLE_ACCURACY, DOUBLE_ACCURACY) + + def compare_with_tolerance( + a: Real, b: Real, relative_tolerance: Real, absolute_tolerance: Real + ) -> Real: + """Compare two doubles given the relative and absolute tolerances.""" + if Accuracy.is_within_tolerance(a, b, relative_tolerance, absolute_tolerance): + return 0 + if a < b: + return -1 + elif a == b: + return 0 + else: + return 1 + def length_is_greater_than_or_equal(comparison_length: Real, reference_length: Real) -> bool: """ Check if the comparison length is greater than the reference length. From 46afca0cbd4038e050873621b3b4acf081731fdf Mon Sep 17 00:00:00 2001 From: Dastan Abdulla Date: Tue, 15 Aug 2023 10:37:50 -0400 Subject: [PATCH 07/76] minor fix in component.py --- src/ansys/geometry/core/designer/component.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ansys/geometry/core/designer/component.py b/src/ansys/geometry/core/designer/component.py index 58611f7579..372b028953 100644 --- a/src/ansys/geometry/core/designer/component.py +++ b/src/ansys/geometry/core/designer/component.py @@ -172,8 +172,6 @@ def __init__( self._master_component.occurrences.append(self) - self._transformed_part.occurrences.append(self) - @property def id(self) -> str: """ID of the component.""" From 2543d069e039e16a5384bbe2af6e11f8b2c1f2c3 Mon Sep 17 00:00:00 2001 From: Dastan Abdulla Date: Tue, 15 Aug 2023 10:40:20 -0400 Subject: [PATCH 08/76] styling --- src/ansys/geometry/core/geometry/box_uv.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ansys/geometry/core/geometry/box_uv.py b/src/ansys/geometry/core/geometry/box_uv.py index 0ef13afb5a..4873711272 100644 --- a/src/ansys/geometry/core/geometry/box_uv.py +++ b/src/ansys/geometry/core/geometry/box_uv.py @@ -1,4 +1,4 @@ -"""provides the ``BoxUV`` class.""" +"""Provides the ``BoxUV`` class.""" from enum import Enum from ansys.geometry.core.geometry.parameterization import Interval, ParamUV @@ -6,7 +6,7 @@ class LocationUV(Enum): - """provides the ``LocationUV`` class to indicate locations for BoxUV.""" + """Provides the ``LocationUV`` class to indicate locations for BoxUV.""" TopLeft = 1 TopCenter = 2 From da8b1f00a4bd4c2f8bcfabc6b23f3665cacade31 Mon Sep 17 00:00:00 2001 From: Dastan Abdulla Date: Wed, 16 Aug 2023 13:05:05 -0400 Subject: [PATCH 09/76] fixed design tests --- .../geometry/core/geometry/surfaces/trimmed_surface.py | 2 +- tests/integration/test_design.py | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index 8d654a0307..7956b8e0e3 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -30,7 +30,7 @@ def __init__(self, desFace: "Face") -> None: def area(self) -> Quantity: """Calculated area of the face.""" self.face._grpc_client.log.debug("Requesting face area from server.") - area_response = self.face._faces_stub.GetArea(self._grpc_id) + area_response = self.face._faces_stub.GetArea(self.face._grpc_id) return Quantity(area_response.area, DEFAULT_UNITS.SERVER_AREA) @property diff --git a/tests/integration/test_design.py b/tests/integration/test_design.py index 13e4f9a4e4..d0b0dc1a6b 100644 --- a/tests/integration/test_design.py +++ b/tests/integration/test_design.py @@ -150,7 +150,7 @@ def test_face_to_body_creation(modeler: Modeler): assert len(nested_component.components) == 0 assert len(nested_component.bodies) == 1 assert surface_body.volume.m == Quantity(0, UNITS.m**3).m - assert surface_body.faces[0].area.m == pytest.approx( + assert surface_body.faces[0].shape.area.m == pytest.approx( Quantity(2e-4, UNITS.m**2).m, rel=1e-6, abs=1e-8 ) @@ -319,8 +319,10 @@ def test_faces_edges(modeler: Modeler): assert len(faces) == 7 # top + bottom + sides assert all(face.id is not None for face in faces) assert all(face.surface_type == SurfaceType.SURFACETYPE_PLANE for face in faces) - assert all(face.area > 0.0 for face in faces) - assert abs(faces[0].area.to_base_units().m - sketch.faces[0].area.to_base_units().m) <= 1e-15 + assert all(face.shape.area > 0.0 for face in faces) + assert ( + abs(faces[0].shape.area.to_base_units().m - sketch.faces[0].area.to_base_units().m) <= 1e-15 + ) assert all(face.body.id == body_polygon_comp.id for face in faces) # Get the normal to some of the faces From 38d1958c016c7e5c895c91e5beef9c08e311dd0e Mon Sep 17 00:00:00 2001 From: Dastan Abdulla Date: Thu, 17 Aug 2023 03:21:10 -0400 Subject: [PATCH 10/76] fixed some EvaluateRequest import issue --- src/ansys/geometry/core/designer/edge.py | 7 +------ src/ansys/geometry/core/designer/face.py | 6 ++---- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 7cbfefd0cc..86efeb25ec 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -2,7 +2,6 @@ from enum import Enum, unique -from ansys.api.geometry.v0.edges_pb2 import EvaluateRequest from ansys.api.geometry.v0.edges_pb2_grpc import EdgesStub from ansys.api.geometry.v0.models_pb2 import EntityIdentifier from beartype.typing import TYPE_CHECKING, List @@ -172,7 +171,6 @@ def faces(self) -> List["Face"]: for grpc_face in grpc_faces ] - @protect_grpc def evaluate_proportion(self, param: Real) -> Point3D: """ Evaluate the edge at a given proportion, a value in the range [0, 1]. @@ -186,7 +184,4 @@ def evaluate_proportion(self, param: Real) -> Point3D: Point3D The position of the evaluation. """ - response = self._edges_stub.EvaluateProportion( - EvaluateRequest(id=self.id, param=param) - ).point - return Point3D([response.x, response.y, response.z], DEFAULT_UNITS.SERVER_LENGTH) + return self.shape.evaluate(param) diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index 878826bd4a..c857b5e40f 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -3,7 +3,7 @@ from enum import Enum, unique from ansys.api.geometry.v0.edges_pb2_grpc import EdgesStub -from ansys.api.geometry.v0.faces_pb2 import EvaluateRequest, GetNormalRequest +from ansys.api.geometry.v0.faces_pb2 import EvaluateRequest from ansys.api.geometry.v0.faces_pb2_grpc import FacesStub from ansys.api.geometry.v0.models_pb2 import Edge as GRPCEdge from ansys.api.geometry.v0.models_pb2 import EntityIdentifier @@ -309,9 +309,7 @@ def face_normal(self, u: float = 0.5, v: float = 0.5) -> UnitVector3D: This :class:`UnitVector3D ` object is perpendicular to the surface at the given UV coordinates. """ - self._grpc_client.log.debug(f"Requesting face normal from server with (u,v)=({u},{v}).") - response = self._faces_stub.GetNormal(GetNormalRequest(id=self.id, u=u, v=v)).direction - return UnitVector3D([response.x, response.y, response.z]) + return self.shape.normal(u, v) @protect_grpc def face_point(self, u: float = 0.5, v: float = 0.5) -> Point3D: From c690d73f7308808a90b85e4924742a2d5f9aff83 Mon Sep 17 00:00:00 2001 From: Dastan Abdulla Date: Thu, 17 Aug 2023 04:09:32 -0400 Subject: [PATCH 11/76] fixed ProjectPoint request --- .../core/geometry/surfaces/surface_evaluation.py | 2 +- .../core/geometry/surfaces/trimmed_surface.py | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py b/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py index 41eec6e4b5..63df2909ef 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py @@ -15,7 +15,7 @@ def __init__(self, parameter: ParamUV) -> None: self._parameter = parameter @property - def parameter(self) -> Real: + def parameter(self) -> ParamUV: """Parameter that the evaluation is based upon.""" raise NotImplementedError("Each evaluation must provide the parameter definition.") diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index 7956b8e0e3..cfc8b02f63 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -1,10 +1,8 @@ """Provides the ``TrimmedSurface`` class.""" -from ansys.api.geometry.v0.faces_pb2 import ProjectPointRequest from beartype.typing import TYPE_CHECKING from pint import Quantity -from ansys.geometry.core.connection.conversions import point3d_to_grpc_point from ansys.geometry.core.errors import protect_grpc from ansys.geometry.core.geometry.box_uv import BoxUV from ansys.geometry.core.geometry.parameterization import Interval, ParamUV @@ -78,14 +76,14 @@ def normal(self, u: float = 0.5, v: float = 0.5) -> UnitVector3D: def project_point(self, point: Point3D): """Project a point to the face.""" - response = self.face._faces_stub.ProjectPoint( - ProjectPointRequest(id=self.face.id, point=point3d_to_grpc_point(point)) - ) boundsU = self.boxUV.IntervalU boundsV = self.boxUV.IntervalV + params = self.face.surface.project_point(point).parameter + u = params.u + v = params.v return ( - (response.param_u - boundsU.start) / boundsU.get_span(), - (response.param_v - boundsV.start) / boundsV.get_span(), + (u - boundsU.start) / boundsU.get_span(), + (v - boundsV.start) / boundsV.get_span(), ) def eval_proportions(self, proportionU: Real, proportionV: Real) -> SurfaceEvaluation: From ed065cbb254c1ddd5bf7d01084e9acd8b2cbf3e5 Mon Sep 17 00:00:00 2001 From: jonahrb Date: Tue, 12 Sep 2023 10:04:40 -0400 Subject: [PATCH 12/76] full face/surface refactor of Dastan's work --- .../geometry/core/connection/__init__.py | 1 + .../geometry/core/connection/conversions.py | 41 ++++ src/ansys/geometry/core/designer/face.py | 105 +++------- src/ansys/geometry/core/geometry/__init__.py | 1 + src/ansys/geometry/core/geometry/box_uv.py | 70 +++---- .../core/geometry/curves/trimmed_curve.py | 6 +- .../core/geometry/parameterization.py | 6 +- .../geometry/core/geometry/surfaces/plane.py | 5 + .../core/geometry/surfaces/trimmed_surface.py | 188 ++++++++++++------ tests/integration/test_design.py | 8 +- 10 files changed, 254 insertions(+), 177 deletions(-) diff --git a/src/ansys/geometry/core/connection/__init__.py b/src/ansys/geometry/core/connection/__init__.py index d34c6f9294..a61d8e7f52 100644 --- a/src/ansys/geometry/core/connection/__init__.py +++ b/src/ansys/geometry/core/connection/__init__.py @@ -6,6 +6,7 @@ frame_to_grpc_frame, grpc_frame_to_frame, grpc_matrix_to_matrix, + grpc_surface_to_surface, plane_to_grpc_plane, point3d_to_grpc_point, sketch_shapes_to_grpc_geometries, diff --git a/src/ansys/geometry/core/connection/conversions.py b/src/ansys/geometry/core/connection/conversions.py index 2923e41828..77d760f85e 100644 --- a/src/ansys/geometry/core/connection/conversions.py +++ b/src/ansys/geometry/core/connection/conversions.py @@ -11,9 +11,11 @@ from ansys.api.geometry.v0.models_pb2 import Plane as GRPCPlane from ansys.api.geometry.v0.models_pb2 import Point as GRPCPoint from ansys.api.geometry.v0.models_pb2 import Polygon as GRPCPolygon +from ansys.api.geometry.v0.models_pb2 import Surface as GRPCSurface from ansys.api.geometry.v0.models_pb2 import Tessellation from beartype.typing import TYPE_CHECKING, List, Optional, Tuple +from ansys.geometry.core.geometry import Cone, Cylinder, Plane, Sphere, Surface, Torus from ansys.geometry.core.math import Frame, Matrix44, Plane, Point2D, Point3D, UnitVector3D from ansys.geometry.core.misc import DEFAULT_UNITS from ansys.geometry.core.sketch import ( @@ -29,6 +31,8 @@ if TYPE_CHECKING: # pragma: no cover from pyvista import PolyData + from ansys.geometry.core.designer import SurfaceType + def unit_vector_to_grpc_direction(unit_vector: UnitVector3D) -> GRPCDirection: """ @@ -410,3 +414,40 @@ def grpc_frame_to_frame(frame: GRPCFrame) -> Frame: ] ), ) + + +def grpc_surface_to_surface(surface: GRPCSurface, surface_type: "SurfaceType") -> Surface: + """ + Convert an ``ansys.api.geometry.Surface`` gRPC message to a ``Surface`` class. + + Parameters + ---------- + surface: GRPCSurface + Geometry service gRPC surface message. + + Returns + ------- + Surface + Resulting converted surface. + """ + from ansys.geometry.core.designer import SurfaceType + + origin = Point3D( + [surface.origin.x, surface.origin.y, surface.origin.z], DEFAULT_UNITS.SERVER_LENGTH + ) + axis = UnitVector3D([surface.axis.x, surface.axis.y, surface.axis.z]) + reference = UnitVector3D([surface.reference.x, surface.reference.y, surface.reference.z]) + + if surface_type == SurfaceType.SURFACETYPE_CONE: + result = Cone(origin, surface.radius, surface.half_angle, reference, axis) + elif surface_type == SurfaceType.SURFACETYPE_CYLINDER: + result = Cylinder(origin, surface.radius, reference, axis) + elif surface_type == SurfaceType.SURFACETYPE_SPHERE: + result = Sphere(origin, surface.radius, reference, axis) + elif surface_type == SurfaceType.SURFACETYPE_TORUS: + result = Torus(origin, surface.major_radius, surface.minor_radius, reference, axis) + elif surface_type == SurfaceType.SURFACETYPE_PLANE: + result = Plane(origin, reference, axis) + else: + result = None + return result diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index c857b5e40f..ee6b857464 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -3,24 +3,18 @@ from enum import Enum, unique from ansys.api.geometry.v0.edges_pb2_grpc import EdgesStub -from ansys.api.geometry.v0.faces_pb2 import EvaluateRequest from ansys.api.geometry.v0.faces_pb2_grpc import FacesStub from ansys.api.geometry.v0.models_pb2 import Edge as GRPCEdge from ansys.api.geometry.v0.models_pb2 import EntityIdentifier from beartype.typing import TYPE_CHECKING, List from pint import Quantity -from ansys.geometry.core.connection import GrpcClient +from ansys.geometry.core.connection import GrpcClient, grpc_surface_to_surface from ansys.geometry.core.errors import protect_grpc - -# surfaces -from ansys.geometry.core.geometry.surfaces.cone import Cone -from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder -from ansys.geometry.core.geometry.surfaces.plane import Plane -from ansys.geometry.core.geometry.surfaces.sphere import Sphere -from ansys.geometry.core.geometry.surfaces.surface import Surface -from ansys.geometry.core.geometry.surfaces.torus import Torus -from ansys.geometry.core.geometry.surfaces.trimmed_surface import TrimmedSurface +from ansys.geometry.core.geometry.surfaces.trimmed_surface import ( + ReversedTrimmedSurface, + TrimmedSurface, +) from ansys.geometry.core.math import Point3D, UnitVector3D from ansys.geometry.core.misc import DEFAULT_UNITS @@ -149,58 +143,9 @@ def __init__( self._faces_stub = FacesStub(grpc_client.channel) self._edges_stub = EdgesStub(grpc_client.channel) self._is_reversed = is_reversed - self._shape = TrimmedSurface(self) - # request the underlying surface from the server + self._shape = None + self._grpc_client.log.debug("Requesting surface properties from server.") - surface_response = self._faces_stub.GetSurface(self._grpc_id) - origin = surface_response.origin - axis_response = surface_response.axis - reference_response = surface_response.reference - axis = UnitVector3D([axis_response.x, axis_response.y, axis_response.z]) - reference = UnitVector3D([reference_response.x, reference_response.y, reference_response.z]) - if self.surface_type == SurfaceType.SURFACETYPE_CONE: - # cone - self._surface = Cone( - Point3D([origin.x, origin.y, origin.z], DEFAULT_UNITS.SERVER_LENGTH), - surface_response.radius, - surface_response.half_angle, - reference, - axis, - ) - elif self.surface_type == SurfaceType.SURFACETYPE_CYLINDER: - # cylinder - self._surface = Cylinder( - Point3D([origin.x, origin.y, origin.z], DEFAULT_UNITS.SERVER_LENGTH), - surface_response.radius, - reference, - axis, - ) - elif self.surface_type == SurfaceType.SURFACETYPE_SPHERE: - # sphere - self._surface = Sphere( - Point3D([origin.x, origin.y, origin.z], DEFAULT_UNITS.SERVER_LENGTH), - surface_response.radius, - reference, - axis, - ) - elif self.surface_type == SurfaceType.SURFACETYPE_TORUS: - # torus - self._surface = Torus( - Point3D([origin.x, origin.y, origin.z], DEFAULT_UNITS.SERVER_LENGTH), - surface_response.major_radius, - surface_response.minor_radius, - reference, - axis, - ) - elif self.surface_type == SurfaceType.SURFACETYPE_PLANE: - # plane - self._surface = Plane( - Point3D([origin.x, origin.y, origin.z], DEFAULT_UNITS.SERVER_LENGTH), - reference, - axis, - ) - else: - self._surface = None @property def id(self) -> str: @@ -224,7 +169,20 @@ def body(self) -> "Body": @property def shape(self) -> TrimmedSurface: - """Internal TrimmedSurface instance.""" + """ + Underlying trimmed surface of the face. + + If the face is reversed, its shape will be a `ReversedTrimmedSurface`, which handles the + direction of the normal vector to ensure it is always facing outward. + """ + if self._shape is None: + surface_response = self._faces_stub.GetSurface(self._grpc_id) + geometry = grpc_surface_to_surface(surface_response, self._surface_type) + self._shape = ( + ReversedTrimmedSurface(self, geometry) + if self.is_reversed + else TrimmedSurface(self, geometry) + ) return self._shape @property @@ -233,9 +191,12 @@ def surface_type(self) -> SurfaceType: return self._surface_type @property - def surface(self) -> Surface: - """Surface type of the face.""" - return self._surface + @protect_grpc + def area(self) -> Quantity: + """Calculated area of the face.""" + self.face._grpc_client.log.debug("Requesting face area from server.") + area_response = self.face._faces_stub.GetArea(self.face._grpc_id) + return Quantity(area_response.area, DEFAULT_UNITS.SERVER_AREA) @property @protect_grpc @@ -282,9 +243,9 @@ def loops(self) -> List[FaceLoop]: return loops @protect_grpc - def face_normal(self, u: float = 0.5, v: float = 0.5) -> UnitVector3D: + def normal(self, u: float = 0.5, v: float = 0.5) -> UnitVector3D: """ - Get the normal direction to the face evaluated at certain UV coordinates. + Get the normal direction to the face at certain proportional UV coordinates. Notes ----- @@ -312,9 +273,9 @@ def face_normal(self, u: float = 0.5, v: float = 0.5) -> UnitVector3D: return self.shape.normal(u, v) @protect_grpc - def face_point(self, u: float = 0.5, v: float = 0.5) -> Point3D: + def point(self, u: float = 0.5, v: float = 0.5) -> Point3D: """ - Get a point of the face evaluated at certain UV coordinates. + Get a point of the face evaluated at certain proportional UV coordinates. Notes ----- @@ -337,9 +298,7 @@ def face_point(self, u: float = 0.5, v: float = 0.5) -> Point3D: :class:`Point3D ` object evaluated at the given UV coordinates. """ - self._grpc_client.log.debug(f"Requesting face point from server with (u,v)=({u},{v}).") - response = self._faces_stub.Evaluate(EvaluateRequest(id=self.id, u=u, v=v)).point - return Point3D([response.x, response.y, response.z], DEFAULT_UNITS.SERVER_LENGTH) + return self.shape.evaluate_proportion(u, v).position def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List["Edge"]: """ diff --git a/src/ansys/geometry/core/geometry/__init__.py b/src/ansys/geometry/core/geometry/__init__.py index 71ca3adb6a..bb85f55f6b 100644 --- a/src/ansys/geometry/core/geometry/__init__.py +++ b/src/ansys/geometry/core/geometry/__init__.py @@ -13,6 +13,7 @@ ) from ansys.geometry.core.geometry.surfaces.cone import Cone, ConeEvaluation from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder, CylinderEvaluation +from ansys.geometry.core.geometry.surfaces.plane import Plane, PlaneEvaluation from ansys.geometry.core.geometry.surfaces.sphere import Sphere, SphereEvaluation from ansys.geometry.core.geometry.surfaces.surface import Surface from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation diff --git a/src/ansys/geometry/core/geometry/box_uv.py b/src/ansys/geometry/core/geometry/box_uv.py index 4873711272..003bd2edcb 100644 --- a/src/ansys/geometry/core/geometry/box_uv.py +++ b/src/ansys/geometry/core/geometry/box_uv.py @@ -22,60 +22,60 @@ class LocationUV(Enum): class BoxUV: """BoxUV class.""" - def __init__(self, rangeU: Interval = None, rangeV: Interval = None) -> None: + def __init__(self, range_u: Interval = None, range_v: Interval = None) -> None: """Root constructor for BoxUV.""" - if rangeV is not None: - self.interval_v = rangeV - if rangeU is not None: - self.interval_u = rangeU + if range_u is not None: + self._interval_u = range_u + if range_v is not None: + self._interval_v = range_v @classmethod def from_param(cls, param: ParamUV): """Secondary constructor for BoxUV using a ParamUV object type.""" - return cls(Interval(param.U, param.U), Interval(param.V, param.V)) + return cls(Interval(param.u, param.u), Interval(param.v, param.v)) @classmethod def from_two_params(cls, param1: ParamUV, param2: ParamUV): """Secondary constructor for BoxUV using two ParamUV object types.""" return cls( - Interval(min(param1.U, param2.U), max(param1.U, param2.U)), - Interval(min(param1.V, param2.V), max(param1.V, param2.V)), + Interval(min(param1.u, param2.u), max(param1.u, param2.u)), + Interval(min(param1.v, param2.v), max(param1.v, param2.v)), ) @property - def IntervalU(self) -> Interval: + def interval_u(self) -> Interval: """Return the u interval.""" - return self.interval_u + return self._interval_u @property - def IntervalV(self) -> Interval: + def interval_v(self) -> Interval: """Return the v interval.""" - return self.interval_v + return self._interval_v def __eq__(self, other: object) -> bool: """Check whether two BoxUV instances are equal.""" if not isinstance(other, BoxUV): # don't attempt to compare against unrelated types return NotImplemented - return self.IntervalU.__eq__(other.IntervalU) and self.IntervalV.__eq__(other.IntervalV) + return self.interval_u.__eq__(other.interval_u) and self.interval_v.__eq__(other.interval_v) def __ne__(self, other: object) -> bool: """Check whether two BoxUV instances are not equal.""" if not isinstance(other, BoxUV): # don't attempt to compare against unrelated types return NotImplemented - return not self.IntervalU.__eq__(other.IntervalU) or not self.IntervalV.__eq__( - other.IntervalV + return not self.interval_u.__eq__(other.interval_u) or not self.interval_v.__eq__( + other.interval_v ) def is_empty(self): """Return whether this BoxUV is empty.""" - return self.IntervalU.is_empty() or self.IntervalV.is_empty() + return self.interval_u.is_empty() or self.interval_v.is_empty() def proportion(self, prop_u: Real, prop_v: Real) -> ParamUV: """Evaluate the BoxUV at the given proportions.""" return ParamUV( - self.IntervalU.get_relative_val(prop_u), self.IntervalV.get_relative_val(prop_v) + self.interval_u.get_relative_val(prop_u), self.interval_v.get_relative_val(prop_v) ) def get_center(self) -> ParamUV: @@ -86,7 +86,7 @@ def is_negative(self, tolerance_u: Real, tolerance_v: Real) -> bool: """Check whether the BoxUV is negative.""" if self.is_empty(): return False - return self.IntervalU.is_negative(tolerance_u) or self.IntervalV.is_negative(tolerance_v) + return self.interval_u.is_negative(tolerance_u) or self.interval_v.is_negative(tolerance_v) @staticmethod def unite(first: "BoxUV", second: "BoxUV") -> "BoxUV": @@ -96,20 +96,20 @@ def unite(first: "BoxUV", second: "BoxUV") -> "BoxUV": if second.is_empty(): return first return BoxUV( - Interval.unite(first.IntervalU, second.IntervalU), - Interval.unite(first.IntervalV, second.IntervalV), + Interval.unite(first.interval_u, second.interval_u), + Interval.unite(first.interval_v, second.interval_v), ) @staticmethod - def Intersect(first: "BoxUV", second: "BoxUV", toleranceU: Real, toleranceV: Real) -> "BoxUV": + def intersect(first: "BoxUV", second: "BoxUV", tolerance_u: Real, tolerance_v: Real) -> "BoxUV": """Return the intersection of two BoxUV instances.""" if first.is_empty() or second.is_empty(): return None # supposed to be empty intersection = BoxUV( - Interval.intersect(first.IntervalU, second.IntervalU, toleranceU), - Interval.intersect(first.IntervalV, second.IntervalV, toleranceV), + Interval.intersect(first.interval_u, second.interval_u, tolerance_u), + Interval.intersect(first.interval_v, second.interval_v, tolerance_v), ) - if not intersection.is_negative(toleranceU, toleranceV): + if not intersection.is_negative(tolerance_u, tolerance_v): return intersection return None # supposed to be empty @@ -118,21 +118,21 @@ def contains(self, param: ParamUV) -> bool: if self.is_empty(): # throw Error.InvalidMethodOnEmptyObjectException(GetType()) raise Exception("Invalid Method On Empty Object Exception" + type(self).__name__) - return self.IntervalU.contains(param.u) and self.IntervalV.contains(param.v) + return self.interval_u.contains(param.u) and self.interval_v.contains(param.v) - def inflate(self, deltaU: Real, deltaV: Real) -> "BoxUV": - """Enlarge the BoxUV u and v intervals by deltaU and deltaV respectively.""" + def inflate(self, delta_u: Real, delta_v: Real) -> "BoxUV": + """Enlarge the BoxUV u and v intervals by delta_u and delta_v respectively.""" if self.is_empty(): # throw Error.InvalidMethodOnEmptyObjectException(GetType()) raise Exception("Invalid Method On Empty Object Exception" + type(self).__name__) - return BoxUV(self.InteravlU.inflate(deltaU), self.InteravlV.inflate(deltaV)) + return BoxUV(self.interval_u.inflate(delta_u), self.interval_v.inflate(delta_v)) def inflate(self, delta: Real) -> "BoxUV": """Enlarge the BoxUV by a given delta.""" if self.is_empty(): # throw Error.InvalidMethodOnEmptyObjectException(GetType()) raise Exception("Invalid Method On Empty Object Exception" + type(self).__name__) - return BoxUV(self.InteravlU.inflate(delta), self.InteravlV.inflate(delta)) + return BoxUV(self.interval_u.inflate(delta), self.interval_v.inflate(delta)) def get_corner(self, location: LocationUV) -> ParamUV: """Return the corner location of the BoxUV.""" @@ -143,28 +143,28 @@ def get_corner(self, location: LocationUV) -> ParamUV: or location == LocationUV.BottomLeft or location == LocationUV.LeftCenter ): - u = self.IntervalU.get_relative_val(0) + u = self.interval_u.get_relative_val(0) elif ( location == LocationUV.TopRight or location == LocationUV.BottomRight or location == LocationUV.RightCenter ): - u = self.IntervalU.get_relative_val(1) + u = self.interval_u.get_relative_val(1) else: - u = self.IntervalU.get_relative_val(0.5) + u = self.interval_u.get_relative_val(0.5) if ( location == LocationUV.BottomRight or location == LocationUV.BottomLeft or location == LocationUV.BottomCenter ): - v = self.IntervalU.get_relative_val(0) + v = self.interval_u.get_relative_val(0) elif ( location == LocationUV.TopRight or location == LocationUV.TopLeft or location == LocationUV.TopCenter ): - v = self.IntervalU.get_relative_val(1) + v = self.interval_u.get_relative_val(1) else: - v = self.IntervalU.get_relative_val(0.5) + v = self.interval_u.get_relative_val(0.5) return ParamUV(u, v) diff --git a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py index 09482f862a..32f8055fb6 100644 --- a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py +++ b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py @@ -38,12 +38,12 @@ def interval(self) -> Interval: def evaluate(self, param: Real) -> Point3D: """Evaluate the curve with respect to the curve direction (reversed or not).""" - eval = self.eval_proportion(param) + eval = self.evaluate_proportion(param) if self.edge.is_reversed: - eval = self.eval_proportion(1 - param) + eval = self.evaluate_proportion(1 - param) return eval.position - def eval_proportion(self, param: Real) -> CurveEvaluation: + def evaluate_proportion(self, param: Real) -> CurveEvaluation: """Evaluate the given curve at the given parameter.""" bounds = self.interval return self.edge.curve.evaluate(bounds.start + bounds.get_span() * param) diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py index 96e6885dcc..4cb649ce4f 100644 --- a/src/ansys/geometry/core/geometry/parameterization.py +++ b/src/ansys/geometry/core/geometry/parameterization.py @@ -110,6 +110,10 @@ def __truediv__(self, other: "ParamUV") -> "ParamUV": """ return ParamUV(self._u / other._u, self._v / other._v) + def __iter__(self): + """Iterate a `ParamUV`.""" + return iter((self.u, self.v)) + def __repr__(self) -> str: """Represent the ``ParamUV`` as a string.""" return f"ParamUV(u={self.u}, v={self.v})" @@ -248,7 +252,7 @@ def unite(first: "Interval", second: "Interval") -> "Interval": return Interval(min(first.start, second.start), max(first.end, second.end)) @staticmethod - def Intersect(first: "Interval", second: "Interval", tolerance: Real) -> "Interval": + def intersect(first: "Interval", second: "Interval", tolerance: Real) -> "Interval": """ Return the intersection of two intervals. diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index cfeeac301b..0e11ea1bb5 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -55,6 +55,11 @@ def __init__( if not self._reference.is_perpendicular_to(self._axis): raise ValueError("Plane reference (dir_x) and axis (dir_z) must be perpendicular.") + @property + def origin(self) -> Point3D: + """Origin of the cylinder.""" + return self._origin + @property def dir_x(self) -> UnitVector3D: """X-direction of the cylinder.""" diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index cfc8b02f63..a295685ec8 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -1,15 +1,13 @@ """Provides the ``TrimmedSurface`` class.""" from beartype.typing import TYPE_CHECKING -from pint import Quantity -from ansys.geometry.core.errors import protect_grpc from ansys.geometry.core.geometry.box_uv import BoxUV from ansys.geometry.core.geometry.parameterization import Interval, ParamUV +from ansys.geometry.core.geometry.surfaces.surface import Surface from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import Point3D from ansys.geometry.core.math.vector import UnitVector3D -from ansys.geometry.core.misc.measurements import DEFAULT_UNITS from ansys.geometry.core.typing import Real if TYPE_CHECKING: @@ -17,82 +15,150 @@ class TrimmedSurface: - """TrimmedSurface class.""" + """ + Represents a trimmed surface. - def __init__(self, desFace: "Face") -> None: - """Construct the TrimmedSurface using the Face object argument.""" - self.face = desFace + A trimmed surface is a surface that has a boundary. This boundary comes in the form of a + bounding BoxUV. + + Parameters + ---------- + face : Face + Face that the TrimmedSurface belongs to. + geometry : Surface + The underlying mathematical representation of the surface. + """ + + def __init__(self, face: "Face", geometry: Surface) -> None: + """Initialize ``TrimmedSurface`` class.""" + self._face = face + self._geometry = geometry + + @property + def face(self) -> "Face": + """The face this TrimmedSurface belongs to.""" + return self._face @property - @protect_grpc - def area(self) -> Quantity: - """Calculated area of the face.""" - self.face._grpc_client.log.debug("Requesting face area from server.") - area_response = self.face._faces_stub.GetArea(self.face._grpc_id) - return Quantity(area_response.area, DEFAULT_UNITS.SERVER_AREA) + def geometry(self) -> Surface: + """The underlying mathematical surface.""" + return self._geometry @property - def boxUV(self) -> BoxUV: - """Calculated box UV of the face.""" - self.face._grpc_client.log.debug("Requesting box UV from server.") - box_response = self.face._faces_stub.GetBoxUV(self.face._grpc_id) - startU = box_response.start_u - endU = box_response.end_u - startV = box_response.start_v - endV = box_response.end_v - return BoxUV(Interval(startU, endU), Interval(startV, endV)) - - def normal(self, u: float = 0.5, v: float = 0.5) -> UnitVector3D: + def box_uv(self) -> BoxUV: + """The bounding BoxUV of the surface.""" + self._face._grpc_client.log.debug("Requesting box UV from server.") + box = self._face._faces_stub.GetBoxUV(self.face._grpc_id) + return BoxUV(Interval(box.start_u, box.end_u), Interval(box.start_v, box.end_v)) + + def get_proportional_parameters(self, param_uv: ParamUV) -> ParamUV: """ - Get the normal direction to the face evaluated at certain UV coordinates. + Convert non-proportional parameters into proportional parameters. - Notes - ----- - To properly use this method, you must handle UV coordinates. Thus, you must - know how these relate to the underlying Geometry service. It is an advanced - method for Geometry experts only. + Parameters + ---------- + param_uv : ParamUV + Non-proportional UV parameters. + + Returns + ------- + ParamUV + Proportional (from 0-1) UV parameters. + """ + bounds_u = self.box_uv.IntervalU + bounds_v = self.box_uv.IntervalV + u = param_uv.u + v = param_uv.v + return ( + (u - bounds_u.start) / bounds_u.get_span(), + (v - bounds_v.start) / bounds_v.get_span(), + ) + + def normal(self, u: Real, v: Real) -> UnitVector3D: + """ + Provide the normal to the surface. Parameters ---------- - u : float, default: 0.5 + u : Real First coordinate of the 2D representation of a surface in UV space. - The default is the center of the surface. - v : float, default: 0.5 + v : Real Second coordinate of the 2D representation of a surface in UV space. - The default is the center of the surface. Returns ------- UnitVector3D - The :class:`UnitVector3D ` - object evaluated at the given U and V coordinates. - This :class:`UnitVector3D ` - object is perpendicular to the surface at the given UV coordinates. + This unit vector is normal to the surface at the given UV coordinates. """ - direction = self.eval_proportions(u, v).normal - if self.face.is_reversed: - return UnitVector3D([-direction.x, -direction.y, -direction.z]) - return UnitVector3D([direction.x, direction.y, direction.z]) - - def project_point(self, point: Point3D): - """Project a point to the face.""" - boundsU = self.boxUV.IntervalU - boundsV = self.boxUV.IntervalV - params = self.face.surface.project_point(point).parameter - u = params.u - v = params.v - return ( - (u - boundsU.start) / boundsU.get_span(), - (v - boundsV.start) / boundsV.get_span(), - ) + return self.evaluate_proportion(u, v).normal + + def project_point(self, point: Point3D) -> SurfaceEvaluation: + """ + Project a point onto the surface and evaluate it at that location. + + Parameters + ---------- + point : Point3D + Point to project onto the surface. + + Returns + ------- + SurfaceEvaluation + Resulting evaluation. + """ + return self.geometry.project_point(point) - def eval_proportions(self, proportionU: Real, proportionV: Real) -> SurfaceEvaluation: - """Evaluate the surface at a given u and v value.""" - boundsU = self.boxUV.IntervalU - boundsV = self.boxUV.IntervalV - return self.face.surface.evaluate( + def evaluate_proportion(self, u: Real, v: Real) -> SurfaceEvaluation: + """ + Evaluate the surface at proportional u and v values. + + Parameters + ---------- + u : Real + U parameter in the proportional range [0,1]. + v : Real + V parameter in the proportional range [0,1]. + + Returns + ------- + SurfaceEvaluation + The corresponding surface evaluation. + """ + boundsU = self.box_uv.IntervalU + boundsV = self.box_uv.IntervalV + return self.geometry.evaluate( ParamUV( - boundsU.start + boundsU.get_span() * proportionU, - boundsV.start + boundsV.get_span() * proportionV, + boundsU.start + boundsU.get_span() * u, + boundsV.start + boundsV.get_span() * v, ) ) + + # TODO: perimeter + + +class ReversedTrimmedSurface(TrimmedSurface): + """ + Represents a reversed TrimmedSurface. + + When a surface is reversed, its normal vector is negated in order to provide the proper + outward facing vector. + + Parameters + ---------- + face : Face + Face that the TrimmedSurface belongs to. + geometry : Surface + The underlying mathematical representation of the surface. + """ + + def __init__(self, face: "Face", geometry: Surface) -> None: + """Initialize ``ReversedTrimmedSurface`` class.""" + super().__init__(face, geometry) + + def normal(self, u: Real, v: Real) -> UnitVector3D: # noqa: D102 + return -self.evaluate_proportion(u, v).normal + + def project_point(self, point: Point3D) -> SurfaceEvaluation: # noqa: D102 + evaluation = self.geometry.project_point(point) + evaluation.normal = -evaluation.normal + return evaluation diff --git a/tests/integration/test_design.py b/tests/integration/test_design.py index 24af6f0554..532721d4ff 100644 --- a/tests/integration/test_design.py +++ b/tests/integration/test_design.py @@ -326,12 +326,12 @@ def test_faces_edges(modeler: Modeler): assert all(face.body.id == body_polygon_comp.id for face in faces) # Get the normal to some of the faces - assert faces[0].face_normal() == UnitVector3D(-UNITVECTOR3D_Z) # Bottom - assert faces[1].face_normal() == UNITVECTOR3D_Z # Top + assert faces[0].normal() == UnitVector3D(-UNITVECTOR3D_Z) # Bottom + assert faces[1].normal() == UNITVECTOR3D_Z # Top # Get the central point of some of the surfaces - assert faces[0].face_point(u=-0.03, v=-0.03) == Point3D([-30, -30, 0], UNITS.mm) - assert faces[1].face_point(u=-0.03, v=-0.03) == Point3D([-30, -30, 30], UNITS.mm) + assert faces[0].point(u=-0.03, v=-0.03) == Point3D([-30, -30, 0], UNITS.mm) + assert faces[1].point(u=-0.03, v=-0.03) == Point3D([-30, -30, 30], UNITS.mm) loops = faces[0].loops assert len(loops) == 1 From e4b69cb3c450cb2bd93f7872fb05fdcb5fd6c16e Mon Sep 17 00:00:00 2001 From: jonahrb Date: Tue, 19 Sep 2023 10:58:59 -0400 Subject: [PATCH 13/76] Refactor edge/trimmedcurve --- .../geometry/core/connection/__init__.py | 1 + .../geometry/core/connection/conversions.py | 53 ++++++++- src/ansys/geometry/core/designer/edge.py | 78 ++++--------- src/ansys/geometry/core/designer/face.py | 17 +++ .../core/geometry/curves/trimmed_curve.py | 109 +++++++++++++++--- .../core/geometry/surfaces/trimmed_surface.py | 14 +-- 6 files changed, 188 insertions(+), 84 deletions(-) diff --git a/src/ansys/geometry/core/connection/__init__.py b/src/ansys/geometry/core/connection/__init__.py index a61d8e7f52..e706f47e15 100644 --- a/src/ansys/geometry/core/connection/__init__.py +++ b/src/ansys/geometry/core/connection/__init__.py @@ -4,6 +4,7 @@ from ansys.geometry.core.connection.client import GrpcClient from ansys.geometry.core.connection.conversions import ( frame_to_grpc_frame, + grpc_curve_to_curve, grpc_frame_to_frame, grpc_matrix_to_matrix, grpc_surface_to_surface, diff --git a/src/ansys/geometry/core/connection/conversions.py b/src/ansys/geometry/core/connection/conversions.py index 77d760f85e..886f1e3550 100644 --- a/src/ansys/geometry/core/connection/conversions.py +++ b/src/ansys/geometry/core/connection/conversions.py @@ -1,5 +1,6 @@ """Module providing for conversions.""" +from ansys.api.geometry.v0.edges_pb2 import GetCurveResponse from ansys.api.geometry.v0.models_pb2 import Arc as GRPCArc from ansys.api.geometry.v0.models_pb2 import Circle as GRPCCircle from ansys.api.geometry.v0.models_pb2 import Direction as GRPCDirection @@ -15,7 +16,9 @@ from ansys.api.geometry.v0.models_pb2 import Tessellation from beartype.typing import TYPE_CHECKING, List, Optional, Tuple -from ansys.geometry.core.geometry import Cone, Cylinder, Plane, Sphere, Surface, Torus +from ansys.geometry.core.geometry import Circle, Cone, Curve, Cylinder, Ellipse, Line +from ansys.geometry.core.geometry import Plane as SurfacePlane +from ansys.geometry.core.geometry import Sphere, Surface, Torus from ansys.geometry.core.math import Frame, Matrix44, Plane, Point2D, Point3D, UnitVector3D from ansys.geometry.core.misc import DEFAULT_UNITS from ansys.geometry.core.sketch import ( @@ -31,7 +34,7 @@ if TYPE_CHECKING: # pragma: no cover from pyvista import PolyData - from ansys.geometry.core.designer import SurfaceType + from ansys.geometry.core.designer import CurveType, SurfaceType def unit_vector_to_grpc_direction(unit_vector: UnitVector3D) -> GRPCDirection: @@ -447,7 +450,51 @@ def grpc_surface_to_surface(surface: GRPCSurface, surface_type: "SurfaceType") - elif surface_type == SurfaceType.SURFACETYPE_TORUS: result = Torus(origin, surface.major_radius, surface.minor_radius, reference, axis) elif surface_type == SurfaceType.SURFACETYPE_PLANE: - result = Plane(origin, reference, axis) + result = SurfacePlane(origin, reference, axis) + else: + result = None + return result + + +def grpc_curve_to_curve(curve: GetCurveResponse, curve_type: "CurveType") -> Curve: + """ + Convert an ``ansys.api.geometry.GetCurveResponse`` gRPC message to a ``Curve``. + + Parameters + ---------- + curve: GRPCCurve + Geometry service gRPC curve message. + + Returns + ------- + Curve + Resulting converted curve. + """ + from ansys.geometry.core.designer import CurveType + + origin = Point3D([curve.origin.x, curve.origin.y, curve.origin.z]) + try: + axis = UnitVector3D([curve.reference.x, curve.reference.y, curve.reference.z]) + reference = UnitVector3D([curve.axis.x, curve.axis.y, curve.axis.z]) + except ValueError: + pass + + if curve_type == CurveType.CURVETYPE_CIRCLE: + result = Circle(origin, curve.radius, reference, axis) + elif curve_type == CurveType.CURVETYPE_ELLIPSE: + result = Ellipse(origin, curve.major_radius, curve.minor_radius, reference, axis) + elif curve_type == CurveType.CURVETYPE_LINE: + result = Line( + origin, + UnitVector3D( + [ + curve.direction.x, + curve.direction.y, + curve.direction.z, + ] + ), + ) else: result = None + return result diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 86efeb25ec..6dc347aab0 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -7,15 +7,10 @@ from beartype.typing import TYPE_CHECKING, List from pint import Quantity -from ansys.geometry.core.connection import GrpcClient +from ansys.geometry.core.connection import GrpcClient, grpc_curve_to_curve from ansys.geometry.core.errors import protect_grpc -from ansys.geometry.core.geometry.curves.circle import Circle -from ansys.geometry.core.geometry.curves.curve import Curve -from ansys.geometry.core.geometry.curves.ellipse import Ellipse -from ansys.geometry.core.geometry.curves.line import Line -from ansys.geometry.core.geometry.curves.trimmed_curve import TrimmedCurve +from ansys.geometry.core.geometry.curves.trimmed_curve import ReversedTrimmedCurve, TrimmedCurve from ansys.geometry.core.math import Point3D -from ansys.geometry.core.math.vector import UnitVector3D from ansys.geometry.core.misc import DEFAULT_UNITS from ansys.geometry.core.typing import Real @@ -69,50 +64,7 @@ def __init__( self._grpc_client = grpc_client self._edges_stub = EdgesStub(grpc_client.channel) self._is_reversed = is_reversed - self._shape = TrimmedCurve(self) - # request the underlying curve from the server - self._grpc_client.log.debug("Requesting edge properties from server.") - curve_response = self._edges_stub.GetCurve(self._grpc_id) - origin = Point3D( - [curve_response.origin.x, curve_response.origin.y, curve_response.origin.z] - ) - # check if the curve is a circle or ellipse - if ( - self.curve_type == CurveType.CURVETYPE_CIRCLE - or self.curve_type == CurveType.CURVETYPE_ELLIPSE - ): - axis_response = curve_response.axis - reference_response = curve_response.reference - axis = UnitVector3D([axis_response.x, axis_response.y, axis_response.z]) - reference = UnitVector3D( - [reference_response.x, reference_response.y, reference_response.z] - ) - if self.curve_type == CurveType.CURVETYPE_CIRCLE: - # circle - self._curve = Circle(origin, curve_response.radius, reference, axis) - else: - # ellipse - self._curve = Ellipse( - origin, - curve_response.major_radius, - curve_response.minor_radius, - reference, - axis, - ) - elif self.curve_type == CurveType.CURVETYPE_LINE: - # line - self._curve = Line( - origin, - UnitVector3D( - [ - curve_response.direction.x, - curve_response.direction.y, - curve_response.direction.z, - ] - ), - ) - else: - self._curve = None + self._shape = None @property def id(self) -> str: @@ -129,14 +81,24 @@ def is_reversed(self) -> bool: """Edge is reversed.""" return self._is_reversed - @property - def curve(self) -> Curve: - """Internal curve object.""" - return self._curve - @property def shape(self) -> TrimmedCurve: - """Internal Trimmed Curve object.""" + """ + Underlying trimmed curve of the edge. + + If the edge is reversed, its shape will be a `ReversedTrimmedCurve`, which swaps the + start and end points of the curve and handles parameters to allow evaluation as if the + curve is not reversed. + """ + if self._shape is None: + self._grpc_client.log.debug("Requesting edge properties from server.") + response = self._edges_stub.GetCurve(self._grpc_id) + geometry = grpc_curve_to_curve(response, self.curve_type) + self._shape = ( + ReversedTrimmedCurve(self, geometry) + if self.is_reversed + else TrimmedCurve(self, geometry) + ) return self._shape @property @@ -171,7 +133,7 @@ def faces(self) -> List["Face"]: for grpc_face in grpc_faces ] - def evaluate_proportion(self, param: Real) -> Point3D: + def evaluate_proportion_remove_this(self, param: Real) -> Point3D: """ Evaluate the edge at a given proportion, a value in the range [0, 1]. diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index ee6b857464..f524521dfa 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -3,6 +3,7 @@ from enum import Enum, unique from ansys.api.geometry.v0.edges_pb2_grpc import EdgesStub +from ansys.api.geometry.v0.faces_pb2 import CreateIsoParamCurvesRequest from ansys.api.geometry.v0.faces_pb2_grpc import FacesStub from ansys.api.geometry.v0.models_pb2 import Edge as GRPCEdge from ansys.api.geometry.v0.models_pb2 import EntityIdentifier @@ -328,3 +329,19 @@ def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List["Edge"]: ) ) return edges + + def create_isoparametric_curve(self, use_u_param: bool, parameter: float): + """ + Create an isoparametic curve at the given proportional parameter. + + Parameters + ---------- + use_u_param : bool + Define whether the parameter is the u coordinate or v coordinate. If True, + then u parameter is used. If False, then v parameter is used. + parameter : float + The proportional [0-1] parameter to create the curve at. + """ + self._faces_stub.CreateIsoParamCurves( + CreateIsoParamCurvesRequest(id=self.id, u_dir_curve=use_u_param, proportion=parameter) + ) diff --git a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py index 32f8055fb6..b33e84efaf 100644 --- a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py +++ b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py @@ -3,6 +3,7 @@ from pint import Quantity from ansys.geometry.core.errors import protect_grpc +from ansys.geometry.core.geometry.curves.curve import Curve from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation from ansys.geometry.core.geometry.parameterization import Interval from ansys.geometry.core.math import Point3D @@ -14,11 +15,48 @@ class TrimmedCurve: - """TrimmedCurve class.""" + """ + Represents a trimmed curve. - def __init__(self, desEdge: "Edge") -> None: - """Construct the TrimmedCurve using the Edge object argument.""" - self.edge = desEdge + A trimmed curve is a curve that has a boundary. This boundary comes in the form of an Interval. + + Parameters + ---------- + edge : Edge + Edge that the TrimmedCurve belongs to. + geometry : Curve + The underlying mathematical representation of the curve. + """ + + def __init__(self, edge: "Edge", geometry: Curve): + """Initialize ``TrimmedCurve`` class.""" + self._edge = edge + self._geometry = geometry + + self.edge._grpc_client.log.debug("Requesting edge points from server.") + response = self.edge._edges_stub.GetStartAndEndPoints(self._grpc_id) + self._start = Point3D([response.start.x, response.start.y, response.start.z]) + self._end = Point3D([response.end.x, response.end.y, response.end.z]) + + @property + def edge(self) -> "Edge": + """The edge this TrimmedCurve belongs to.""" + return self._edge + + @property + def geometry(self) -> Curve: + """The underlying mathematical curve.""" + return self._geometry + + @property + def start(self) -> Point3D: + """The start point of the curve.""" + return self._start + + @property + def end(self) -> Point3D: + """The end point of the curve.""" + return self._end @property @protect_grpc @@ -31,19 +69,58 @@ def length(self) -> Quantity: @property @protect_grpc def interval(self) -> Interval: - """Calculated interval of the edge.""" + """Interval of the curve that provides its boundary.""" self.edge._grpc_client.log.debug("Requesting edge interval from server.") - interva_response = self.edge._edges_stub.GetInterval(self.edge._grpc_id) - return Interval(interva_response.start, interva_response.end) - - def evaluate(self, param: Real) -> Point3D: - """Evaluate the curve with respect to the curve direction (reversed or not).""" - eval = self.evaluate_proportion(param) - if self.edge.is_reversed: - eval = self.evaluate_proportion(1 - param) - return eval.position + interval = self.edge._edges_stub.GetInterval(self.edge._grpc_id) + return Interval(interval.start, interval.end) def evaluate_proportion(self, param: Real) -> CurveEvaluation: - """Evaluate the given curve at the given parameter.""" + """ + Evaluate the curve at a proportional value. + + A parameter of 0 would correspond to the start of the curve, while a parameter of 1 would + correspond to the end of the curve. + + Parameters + ---------- + param : Real + Parameter in the proportional range [0,1]. + + Returns + ------- + CurveEvaluation + The resulting curve evaluation. + """ bounds = self.interval - return self.edge.curve.evaluate(bounds.start + bounds.get_span() * param) + return self.geometry.evaluate(bounds.start + bounds.get_span() * param) + + +class ReversedTrimmedCurve(TrimmedCurve): + """ + Represents a reversed TrimmedCurve. + + When a curve is reversed, its start and end points are swapped, and parameters for evaluations + are handled to provide expected results conforming to the direction of the curve. For example, + evaluating a TrimmedCurve proportionally at 0 would evaluate at the start point of the curve, + but evaluating a ReversedTrimmedCurve proportionally at 0 will evaluate at what was previously + the end point of the curve but is now the start point. + + Parameters + ---------- + edge : Edge + Edge that the TrimmedCurve belongs to. + geometry : Curve + The underlying mathematical representation of the curve. + """ + + def __init__(self, edge: "Edge", geometry: Curve): + """Initialize ``ReversedTrimmedCurve`` class.""" + super().__init__(edge, geometry) + + # Swap start and end points + temp = self._start + self._start = self._end + self._end = temp + + def evaluate_proportion(self, param: Real) -> CurveEvaluation: # noqa: D102 + return self.geometry.evaluate(self.interval.end - self.interval.get_span() * param) diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index a295685ec8..a2e101ae5f 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -29,7 +29,7 @@ class TrimmedSurface: The underlying mathematical representation of the surface. """ - def __init__(self, face: "Face", geometry: Surface) -> None: + def __init__(self, face: "Face", geometry: Surface): """Initialize ``TrimmedSurface`` class.""" self._face = face self._geometry = geometry @@ -65,8 +65,8 @@ def get_proportional_parameters(self, param_uv: ParamUV) -> ParamUV: ParamUV Proportional (from 0-1) UV parameters. """ - bounds_u = self.box_uv.IntervalU - bounds_v = self.box_uv.IntervalV + bounds_u = self.box_uv.interval_u + bounds_v = self.box_uv.interval_v u = param_uv.u v = param_uv.v return ( @@ -122,10 +122,10 @@ def evaluate_proportion(self, u: Real, v: Real) -> SurfaceEvaluation: Returns ------- SurfaceEvaluation - The corresponding surface evaluation. + The resulting surface evaluation. """ - boundsU = self.box_uv.IntervalU - boundsV = self.box_uv.IntervalV + boundsU = self.box_uv.interval_u + boundsV = self.box_uv.interval_v return self.geometry.evaluate( ParamUV( boundsU.start + boundsU.get_span() * u, @@ -151,7 +151,7 @@ class ReversedTrimmedSurface(TrimmedSurface): The underlying mathematical representation of the surface. """ - def __init__(self, face: "Face", geometry: Surface) -> None: + def __init__(self, face: "Face", geometry: Surface): """Initialize ``ReversedTrimmedSurface`` class.""" super().__init__(face, geometry) From 5af0e5ab084177b7fc82e502985bb6b050a4d553 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 14:16:59 +0000 Subject: [PATCH 14/76] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/ansys/geometry/core/geometry/__init__.py | 1 - src/ansys/geometry/core/geometry/box_uv.py | 1 - src/ansys/geometry/core/geometry/curves/circle.py | 1 - src/ansys/geometry/core/geometry/curves/curve.py | 1 - src/ansys/geometry/core/geometry/curves/ellipse.py | 1 - src/ansys/geometry/core/geometry/curves/line.py | 1 - src/ansys/geometry/core/geometry/curves/trimmed_curve.py | 1 - src/ansys/geometry/core/geometry/surfaces/cone.py | 1 - src/ansys/geometry/core/geometry/surfaces/cylinder.py | 1 - src/ansys/geometry/core/geometry/surfaces/plane.py | 1 - src/ansys/geometry/core/geometry/surfaces/sphere.py | 1 - src/ansys/geometry/core/geometry/surfaces/surface.py | 1 - src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py | 1 - src/ansys/geometry/core/geometry/surfaces/torus.py | 1 - src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py | 1 - src/ansys/geometry/core/sketch/circle.py | 1 - src/ansys/geometry/core/sketch/ellipse.py | 1 - src/ansys/geometry/core/sketch/segment.py | 1 - 18 files changed, 18 deletions(-) diff --git a/src/ansys/geometry/core/geometry/__init__.py b/src/ansys/geometry/core/geometry/__init__.py index d0d3fda0d6..03fff51011 100644 --- a/src/ansys/geometry/core/geometry/__init__.py +++ b/src/ansys/geometry/core/geometry/__init__.py @@ -19,7 +19,6 @@ # 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 the PyGeometry ``geometry`` subpackage.""" from ansys.geometry.core.geometry.curves.circle import Circle, CircleEvaluation diff --git a/src/ansys/geometry/core/geometry/box_uv.py b/src/ansys/geometry/core/geometry/box_uv.py index 8ad9c9e9fe..050b4c785e 100644 --- a/src/ansys/geometry/core/geometry/box_uv.py +++ b/src/ansys/geometry/core/geometry/box_uv.py @@ -19,7 +19,6 @@ # 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 the ``BoxUV`` class.""" from enum import Enum diff --git a/src/ansys/geometry/core/geometry/curves/circle.py b/src/ansys/geometry/core/geometry/curves/circle.py index 975b222bbc..2c8d673dff 100644 --- a/src/ansys/geometry/core/geometry/curves/circle.py +++ b/src/ansys/geometry/core/geometry/curves/circle.py @@ -19,7 +19,6 @@ # 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 for creating and managing a circle.""" from functools import cached_property diff --git a/src/ansys/geometry/core/geometry/curves/curve.py b/src/ansys/geometry/core/geometry/curves/curve.py index 3ccf8bf7cc..f3c3d506d1 100644 --- a/src/ansys/geometry/core/geometry/curves/curve.py +++ b/src/ansys/geometry/core/geometry/curves/curve.py @@ -19,7 +19,6 @@ # 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 the ``Curve`` class.""" from abc import ABC, abstractmethod diff --git a/src/ansys/geometry/core/geometry/curves/ellipse.py b/src/ansys/geometry/core/geometry/curves/ellipse.py index c257891ee6..a74a15dc03 100644 --- a/src/ansys/geometry/core/geometry/curves/ellipse.py +++ b/src/ansys/geometry/core/geometry/curves/ellipse.py @@ -19,7 +19,6 @@ # 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 for creating and managing an ellipse.""" from functools import cached_property diff --git a/src/ansys/geometry/core/geometry/curves/line.py b/src/ansys/geometry/core/geometry/curves/line.py index 83ad28da42..399f55d3c7 100644 --- a/src/ansys/geometry/core/geometry/curves/line.py +++ b/src/ansys/geometry/core/geometry/curves/line.py @@ -19,7 +19,6 @@ # 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 for creating and managing a line.""" from functools import cached_property diff --git a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py index d231780481..6b71d940ed 100644 --- a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py +++ b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py @@ -19,7 +19,6 @@ # 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. - """Trimmed curve class.""" from beartype.typing import TYPE_CHECKING from pint import Quantity diff --git a/src/ansys/geometry/core/geometry/surfaces/cone.py b/src/ansys/geometry/core/geometry/surfaces/cone.py index e4a844306d..8b6791fbac 100644 --- a/src/ansys/geometry/core/geometry/surfaces/cone.py +++ b/src/ansys/geometry/core/geometry/surfaces/cone.py @@ -19,7 +19,6 @@ # 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 for creating and managing a cone.""" from functools import cached_property diff --git a/src/ansys/geometry/core/geometry/surfaces/cylinder.py b/src/ansys/geometry/core/geometry/surfaces/cylinder.py index be9675e291..b91c275f68 100644 --- a/src/ansys/geometry/core/geometry/surfaces/cylinder.py +++ b/src/ansys/geometry/core/geometry/surfaces/cylinder.py @@ -19,7 +19,6 @@ # 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 for creating and managing a cylinder.""" from functools import cached_property diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index dbaf316073..587f9b7994 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -19,7 +19,6 @@ # 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. - """The plane surface class.""" from functools import cached_property diff --git a/src/ansys/geometry/core/geometry/surfaces/sphere.py b/src/ansys/geometry/core/geometry/surfaces/sphere.py index a0a32c7827..9a3dab97b6 100644 --- a/src/ansys/geometry/core/geometry/surfaces/sphere.py +++ b/src/ansys/geometry/core/geometry/surfaces/sphere.py @@ -19,7 +19,6 @@ # 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 for creating and managing a sphere.""" from functools import cached_property diff --git a/src/ansys/geometry/core/geometry/surfaces/surface.py b/src/ansys/geometry/core/geometry/surfaces/surface.py index 3bfe981731..55afc7fa30 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface.py @@ -19,7 +19,6 @@ # 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 the ``Surface`` class.""" from abc import ABC, abstractmethod diff --git a/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py b/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py index badab5bdaa..c8a90686c2 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py @@ -19,7 +19,6 @@ # 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 for evaluating a surface.""" from functools import cached_property diff --git a/src/ansys/geometry/core/geometry/surfaces/torus.py b/src/ansys/geometry/core/geometry/surfaces/torus.py index 7a4654c267..79204bc420 100644 --- a/src/ansys/geometry/core/geometry/surfaces/torus.py +++ b/src/ansys/geometry/core/geometry/surfaces/torus.py @@ -19,7 +19,6 @@ # 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 for creating and managing a torus.""" from functools import cached_property diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index b56f6f9176..957fda9dc9 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -19,7 +19,6 @@ # 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 the ``TrimmedSurface`` class.""" from beartype.typing import TYPE_CHECKING diff --git a/src/ansys/geometry/core/sketch/circle.py b/src/ansys/geometry/core/sketch/circle.py index 7599d82c48..485f2c1bd5 100644 --- a/src/ansys/geometry/core/sketch/circle.py +++ b/src/ansys/geometry/core/sketch/circle.py @@ -19,7 +19,6 @@ # 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 for creating and managing a circle.""" from beartype import beartype as check_input_types diff --git a/src/ansys/geometry/core/sketch/ellipse.py b/src/ansys/geometry/core/sketch/ellipse.py index 3112ba2e81..64e4c139d8 100644 --- a/src/ansys/geometry/core/sketch/ellipse.py +++ b/src/ansys/geometry/core/sketch/ellipse.py @@ -19,7 +19,6 @@ # 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 for creating and managing an ellipse.""" from beartype import beartype as check_input_types diff --git a/src/ansys/geometry/core/sketch/segment.py b/src/ansys/geometry/core/sketch/segment.py index 645502634e..afaf28662c 100644 --- a/src/ansys/geometry/core/sketch/segment.py +++ b/src/ansys/geometry/core/sketch/segment.py @@ -19,7 +19,6 @@ # 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 for creating and managing a segment.""" from beartype import beartype as check_input_types From 71c920543eee090e25eab6e0e54b9baa62b323ce Mon Sep 17 00:00:00 2001 From: jonahrb Date: Wed, 4 Oct 2023 10:29:49 -0400 Subject: [PATCH 15/76] refactor TrimmedCurve --- .../geometry/core/connection/__init__.py | 2 + .../geometry/core/connection/conversions.py | 98 ++++++++++++-- src/ansys/geometry/core/designer/edge.py | 23 +++- src/ansys/geometry/core/designer/face.py | 38 +++++- .../core/geometry/curves/trimmed_curve.py | 120 +++++++++++++----- 5 files changed, 226 insertions(+), 55 deletions(-) diff --git a/src/ansys/geometry/core/connection/__init__.py b/src/ansys/geometry/core/connection/__init__.py index ae04c5a1d2..396703d09b 100644 --- a/src/ansys/geometry/core/connection/__init__.py +++ b/src/ansys/geometry/core/connection/__init__.py @@ -24,6 +24,7 @@ from ansys.geometry.core.connection.backend import ApiVersions, BackendType from ansys.geometry.core.connection.client import GrpcClient from ansys.geometry.core.connection.conversions import ( + curve_to_grpc_curve, frame_to_grpc_frame, grpc_curve_to_curve, grpc_frame_to_frame, @@ -33,6 +34,7 @@ point3d_to_grpc_point, sketch_shapes_to_grpc_geometries, tess_to_pd, + trimmed_curve_to_grpc_trimmed_curve, unit_vector_to_grpc_direction, ) from ansys.geometry.core.connection.defaults import ( diff --git a/src/ansys/geometry/core/connection/conversions.py b/src/ansys/geometry/core/connection/conversions.py index 36945f411d..0b04ab813e 100644 --- a/src/ansys/geometry/core/connection/conversions.py +++ b/src/ansys/geometry/core/connection/conversions.py @@ -21,9 +21,9 @@ # SOFTWARE. """Module providing for conversions.""" -from ansys.api.geometry.v0.edges_pb2 import GetCurveResponse from ansys.api.geometry.v0.models_pb2 import Arc as GRPCArc from ansys.api.geometry.v0.models_pb2 import Circle as GRPCCircle +from ansys.api.geometry.v0.models_pb2 import CurveGeometry as GRPCCurve from ansys.api.geometry.v0.models_pb2 import Direction as GRPCDirection from ansys.api.geometry.v0.models_pb2 import Ellipse as GRPCEllipse from ansys.api.geometry.v0.models_pb2 import Frame as GRPCFrame @@ -35,6 +35,7 @@ from ansys.api.geometry.v0.models_pb2 import Polygon as GRPCPolygon from ansys.api.geometry.v0.models_pb2 import Surface as GRPCSurface from ansys.api.geometry.v0.models_pb2 import Tessellation +from ansys.api.geometry.v0.models_pb2 import TrimmedCurve as GRPCTrimmedCurve from beartype.typing import TYPE_CHECKING, List, Optional, Tuple from ansys.geometry.core.geometry import Circle, Cone, Curve, Cylinder, Ellipse, Line @@ -55,7 +56,8 @@ if TYPE_CHECKING: # pragma: no cover from pyvista import PolyData - from ansys.geometry.core.designer import CurveType, SurfaceType + from ansys.geometry.core.designer import SurfaceType + from ansys.geometry.core.geometry.curves.trimmed_curve import TrimmedCurve def unit_vector_to_grpc_direction(unit_vector: UnitVector3D) -> GRPCDirection: @@ -444,7 +446,7 @@ def grpc_surface_to_surface(surface: GRPCSurface, surface_type: "SurfaceType") - Parameters ---------- - surface: GRPCSurface + surface : GRPCSurface Geometry service gRPC surface message. Returns @@ -475,13 +477,13 @@ def grpc_surface_to_surface(surface: GRPCSurface, surface_type: "SurfaceType") - return result -def grpc_curve_to_curve(curve: GetCurveResponse, curve_type: "CurveType") -> Curve: +def grpc_curve_to_curve(curve: GRPCCurve) -> Curve: """ - Convert an ``ansys.api.geometry.GetCurveResponse`` gRPC message to a ``Curve``. + Convert an ``ansys.api.geometry.CurveGeometry`` gRPC message to a ``Curve``. Parameters ---------- - curve: GRPCCurve + curve : GRPCCurve Geometry service gRPC curve message. Returns @@ -489,20 +491,18 @@ def grpc_curve_to_curve(curve: GetCurveResponse, curve_type: "CurveType") -> Cur Curve Resulting converted curve. """ - from ansys.geometry.core.designer import CurveType - origin = Point3D([curve.origin.x, curve.origin.y, curve.origin.z]) try: - axis = UnitVector3D([curve.reference.x, curve.reference.y, curve.reference.z]) - reference = UnitVector3D([curve.axis.x, curve.axis.y, curve.axis.z]) + reference = UnitVector3D([curve.reference.x, curve.reference.y, curve.reference.z]) + axis = UnitVector3D([curve.axis.x, curve.axis.y, curve.axis.z]) except ValueError: + # curve will be a line pass - - if curve_type == CurveType.CURVETYPE_CIRCLE: + if curve.radius != 0: result = Circle(origin, curve.radius, reference, axis) - elif curve_type == CurveType.CURVETYPE_ELLIPSE: + elif curve.major_radius != 0 and curve.minor_radius != 0: result = Ellipse(origin, curve.major_radius, curve.minor_radius, reference, axis) - elif curve_type == CurveType.CURVETYPE_LINE: + elif curve.direction is not None: result = Line( origin, UnitVector3D( @@ -517,3 +517,73 @@ def grpc_curve_to_curve(curve: GetCurveResponse, curve_type: "CurveType") -> Cur result = None return result + + +def curve_to_grpc_curve(curve: Curve) -> GRPCCurve: + """ + Convert a ``Curve``to an ``ansys.api.geometry.CurveGeometry`` gRPC message. + + Parameters + ---------- + curve : Curve + The curve to convert. + + Returns + ------- + GRPCCurve + Geometry service gRPC CurveGeometry message. + """ + grpc_curve = None + origin = point3d_to_grpc_point(curve.origin) + + if isinstance(curve, Line): + direction = unit_vector_to_grpc_direction(curve.direction) + grpc_curve = GRPCCurve(origin=origin, direction=direction) + else: + reference = unit_vector_to_grpc_direction(curve.dir_x) + axis = unit_vector_to_grpc_direction(curve.dir_z) + + if isinstance(curve, Circle): + grpc_curve = GRPCCurve( + origin=origin, reference=reference, axis=axis, radius=curve.radius.m + ) + elif isinstance(curve, Ellipse): + grpc_curve = GRPCCurve( + origin=origin, + reference=reference, + axis=axis, + major_radius=curve.major_radius.m, + minor_radius=curve.minor_radius.m, + ) + + return grpc_curve + + +def trimmed_curve_to_grpc_trimmed_curve(curve: "TrimmedCurve") -> GRPCTrimmedCurve: + """ + Convert a ``TrimmedCurve``to an ``ansys.api.geometry.TrimmedCurve`` gRPC message. + + Parameters + ---------- + curve : TrimmedCurve + The curve to convert. + + Returns + ------- + GRPCTrimmedCurve + Geometry service gRPC TrimmedCurve message. + """ + curve_geometry = curve_to_grpc_curve(curve.geometry) + start = point3d_to_grpc_point(curve.start) + end = point3d_to_grpc_point(curve.end) + i_start = curve.interval.start + i_end = curve.interval.end + + return GRPCTrimmedCurve( + curve=curve_geometry, + start=start, + end=end, + interval_start=i_start, + interval_end=i_end, + length=curve.length.m, + ) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 37b4e7a181..8acfd518d7 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -31,6 +31,8 @@ from ansys.geometry.core.connection import GrpcClient, grpc_curve_to_curve from ansys.geometry.core.errors import protect_grpc from ansys.geometry.core.geometry.curves.trimmed_curve import ReversedTrimmedCurve, TrimmedCurve +from ansys.geometry.core.geometry.parameterization import Interval +from ansys.geometry.core.math.point import Point3D from ansys.geometry.core.misc import DEFAULT_UNITS if TYPE_CHECKING: # pragma: no cover @@ -112,11 +114,22 @@ def shape(self) -> TrimmedCurve: if self._shape is None: self._grpc_client.log.debug("Requesting edge properties from server.") response = self._edges_stub.GetCurve(self._grpc_id) - geometry = grpc_curve_to_curve(response, self.curve_type) + geometry = grpc_curve_to_curve(response) + + response = self._edges_stub.GetStartAndEndPoints(self._grpc_id) + start = Point3D([response.start.x, response.start.y, response.start.z]) + end = Point3D([response.end.x, response.end.y, response.end.z]) + + response = self._edges_stub.GetLength(self._grpc_id) + length = Quantity(response.length, DEFAULT_UNITS.SERVER_LENGTH) + + response = self._edges_stub.GetInterval(self._grpc_id) + interval = Interval(response.start, response.end) + self._shape = ( - ReversedTrimmedCurve(self, geometry) + ReversedTrimmedCurve(geometry, start, end, interval, length) if self.is_reversed - else TrimmedCurve(self, geometry) + else TrimmedCurve(geometry, start, end, interval, length) ) return self._shape @@ -124,9 +137,7 @@ def shape(self) -> TrimmedCurve: @protect_grpc def length(self) -> Quantity: """Calculated length of the edge.""" - self._grpc_client.log.debug("Requesting edge length from server.") - length_response = self._edges_stub.GetLength(self._grpc_id) - return Quantity(length_response.length, DEFAULT_UNITS.SERVER_LENGTH) + return self.shape.length @property def curve_type(self) -> CurveType: diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index 333cf9e93f..0dd44c4ceb 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -31,8 +31,10 @@ from beartype.typing import TYPE_CHECKING, List from pint import Quantity -from ansys.geometry.core.connection import GrpcClient, grpc_surface_to_surface +from ansys.geometry.core.connection import GrpcClient, grpc_curve_to_curve, grpc_surface_to_surface from ansys.geometry.core.errors import protect_grpc +from ansys.geometry.core.geometry.curves.trimmed_curve import TrimmedCurve +from ansys.geometry.core.geometry.parameterization import Interval from ansys.geometry.core.geometry.surfaces.trimmed_surface import ( ReversedTrimmedSurface, TrimmedSurface, @@ -350,9 +352,14 @@ def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List["Edge"]: ) return edges - def create_isoparametric_curve(self, use_u_param: bool, parameter: float): + def create_isoparametric_curves( + self, use_u_param: bool, parameter: float + ) -> List[TrimmedCurve]: """ - Create an isoparametic curve at the given proportional parameter. + Create isoparametic curves at the given proportional parameter. + + Typically, only one curve will be created, but if the face has a hole, it is possible to + create more than one curve. Parameters ---------- @@ -360,8 +367,27 @@ def create_isoparametric_curve(self, use_u_param: bool, parameter: float): Define whether the parameter is the u coordinate or v coordinate. If True, then u parameter is used. If False, then v parameter is used. parameter : float - The proportional [0-1] parameter to create the curve at. + The proportional [0-1] parameter to create the curvse at. + + Returns + ------- + List[TrimmedCurve] + The list of curves that were created. """ - self._faces_stub.CreateIsoParamCurves( + curves = self._faces_stub.CreateIsoParamCurves( CreateIsoParamCurvesRequest(id=self.id, u_dir_curve=use_u_param, proportion=parameter) - ) + ).curves + + trimmed_curves = [] + for c in curves: + geometry = grpc_curve_to_curve(c.curve) + start = Point3D([c.start.x, c.start.y, c.start.z]) + end = Point3D([c.end.x, c.end.y, c.end.z]) + interval = Interval(c.interval_start, c.interval_end) + length = Quantity(c.length, DEFAULT_UNITS.SERVER_LENGTH) + + trimmed_curves.append( + TrimmedCurve(geometry, start, end, interval, length, self._grpc_client) + ) + + return trimmed_curves diff --git a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py index d231780481..c230d6fc33 100644 --- a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py +++ b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py @@ -21,20 +21,20 @@ # SOFTWARE. """Trimmed curve class.""" -from beartype.typing import TYPE_CHECKING +from ansys.api.geometry.v0.commands_pb2 import IntersectCurvesRequest +from ansys.api.geometry.v0.commands_pb2_grpc import CommandsStub +from beartype.typing import List from pint import Quantity +from ansys.geometry.core.connection.client import GrpcClient +from ansys.geometry.core.connection.conversions import trimmed_curve_to_grpc_trimmed_curve from ansys.geometry.core.errors import protect_grpc from ansys.geometry.core.geometry.curves.curve import Curve from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation from ansys.geometry.core.geometry.parameterization import Interval from ansys.geometry.core.math import Point3D -from ansys.geometry.core.misc.measurements import DEFAULT_UNITS from ansys.geometry.core.typing import Real -if TYPE_CHECKING: - from ansys.geometry.core.designer.edge import Edge - class TrimmedCurve: """ @@ -44,26 +44,38 @@ class TrimmedCurve: Parameters ---------- - edge : Edge - Edge that the TrimmedCurve belongs to. geometry : Curve The underlying mathematical representation of the curve. + start : Point3D + The start point of the curve. + end : Point3D + The end point of the curve. + interval : Interval + The parametric interval that bounds the curve. + length : Quantity + The length of the curve. + grpc_client : GrpcClient, default: None + Optional gRPC client that is required for advanced functions such as `intersect_curve()`. """ - def __init__(self, edge: "Edge", geometry: Curve): + def __init__( + self, + geometry: Curve, + start: Point3D, + end: Point3D, + interval: Interval, + length: Quantity, + grpc_client: GrpcClient = None, + ): """Initialize ``TrimmedCurve`` class.""" - self._edge = edge self._geometry = geometry - - self.edge._grpc_client.log.debug("Requesting edge points from server.") - response = self.edge._edges_stub.GetStartAndEndPoints(self._grpc_id) - self._start = Point3D([response.start.x, response.start.y, response.start.z]) - self._end = Point3D([response.end.x, response.end.y, response.end.z]) - - @property - def edge(self) -> "Edge": - """The edge this TrimmedCurve belongs to.""" - return self._edge + self._start = start + self._end = end + self._interval = interval + self._length = length + self._grpc_client = grpc_client + if grpc_client is not None: + self._commands_stub = CommandsStub(self._grpc_client.channel) @property def geometry(self) -> Curve: @@ -84,17 +96,13 @@ def end(self) -> Point3D: @protect_grpc def length(self) -> Quantity: """Calculated length of the edge.""" - self.edge._grpc_client.log.debug("Requesting edge length from server.") - length_response = self.edge._edges_stub.GetLength(self._grpc_id) - return Quantity(length_response.length, DEFAULT_UNITS.SERVER_LENGTH) + return self._length @property @protect_grpc def interval(self) -> Interval: """Interval of the curve that provides its boundary.""" - self.edge._grpc_client.log.debug("Requesting edge interval from server.") - interval = self.edge._edges_stub.GetInterval(self.edge._grpc_id) - return Interval(interval.start, interval.end) + return self._interval def evaluate_proportion(self, param: Real) -> CurveEvaluation: """ @@ -116,6 +124,43 @@ def evaluate_proportion(self, param: Real) -> CurveEvaluation: bounds = self.interval return self.geometry.evaluate(bounds.start + bounds.get_span() * param) + def intersect_curve(self, other: "TrimmedCurve") -> List[Point3D]: + """ + Intersect this trimmed curve with another to receive the points of intersection. + + If the curves do not intersect, an empty list is returned. + + Parameters + ---------- + other : TrimmedCurve + The trimmed curve to intersect with. + + Returns + ------- + List[Point3D] + All points of intersection between the curves. + """ + if self._grpc_client is None: + raise ValueError( + """This TrimmedCurve was not initialized with a grpc client, + so this method cannot be called.""" + ) + first = trimmed_curve_to_grpc_trimmed_curve(self) + second = trimmed_curve_to_grpc_trimmed_curve(other) + res = self._commands_stub.IntersectCurves( + IntersectCurvesRequest(first=first, second=second) + ) + if res.intersect is False: + return [] + return [Point3D([point.x, point.y, point.z]) for point in res.points] + + def __repr__(self) -> str: + """Represent the trimmed curve as a string.""" + return ( + f"TrimmedCurve(geometry: {type(self.geometry)}, start: {self.start}, end: {self.end}, " + f"interval: {self.interval}, length: {self.length})" + ) + class ReversedTrimmedCurve(TrimmedCurve): """ @@ -129,15 +174,31 @@ class ReversedTrimmedCurve(TrimmedCurve): Parameters ---------- - edge : Edge - Edge that the TrimmedCurve belongs to. geometry : Curve The underlying mathematical representation of the curve. + start : Point3D + The original start point of the curve. + end : Point3D + The original end point of the curve. + interval : Interval + The parametric interval that bounds the curve. + length : Quantity + The length of the curve. + grpc_client : GrpcClient, default: None + Optional gRPC client that is required for advanced functions such as `intersect_curve()`. """ - def __init__(self, edge: "Edge", geometry: Curve): + def __init__( + self, + geometry: Curve, + start: Point3D, + end: Point3D, + interval: Interval, + length: Quantity, + grpc_client: GrpcClient = None, + ): """Initialize ``ReversedTrimmedCurve`` class.""" - super().__init__(edge, geometry) + super().__init__(geometry, start, end, interval, length, grpc_client) # Swap start and end points temp = self._start @@ -145,4 +206,5 @@ def __init__(self, edge: "Edge", geometry: Curve): self._end = temp def evaluate_proportion(self, param: Real) -> CurveEvaluation: # noqa: D102 + # Evaluate starting from the end return self.geometry.evaluate(self.interval.end - self.interval.get_span() * param) From e240252d3e4a3112d0c4278793d49163ceb8a153 Mon Sep 17 00:00:00 2001 From: jonahrb Date: Wed, 4 Oct 2023 11:17:03 -0400 Subject: [PATCH 16/76] fix tests, face.point was never proportional.. --- src/ansys/geometry/core/designer/face.py | 4 ++-- src/ansys/geometry/core/plotting/plotter.py | 2 +- tests/integration/test_design.py | 16 ++++++++-------- tests/integration/test_edges.py | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index 0dd44c4ceb..d6bdc00c70 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -218,8 +218,8 @@ def surface_type(self) -> SurfaceType: @protect_grpc def area(self) -> Quantity: """Calculated area of the face.""" - self.face._grpc_client.log.debug("Requesting face area from server.") - area_response = self.face._faces_stub.GetArea(self.face._grpc_id) + self._grpc_client.log.debug("Requesting face area from server.") + area_response = self._faces_stub.GetArea(self._grpc_id) return Quantity(area_response.area, DEFAULT_UNITS.SERVER_AREA) @property diff --git a/src/ansys/geometry/core/plotting/plotter.py b/src/ansys/geometry/core/plotting/plotter.py index 4ce0d00c39..ff38b3f9d0 100644 --- a/src/ansys/geometry/core/plotting/plotter.py +++ b/src/ansys/geometry/core/plotting/plotter.py @@ -250,7 +250,7 @@ def add_body_edges(self, body_plot: GeomObjectPlot, **plotting_options: Optional """ edge_plot_list = [] for edge in body_plot.object.edges: - line = pv.Line(edge.start_point, edge.end_point) + line = pv.Line(edge.shape.start, edge.shape.start) edge_actor = self.scene.add_mesh( line, line_width=10, color=EDGE_COLOR, **plotting_options ) diff --git a/tests/integration/test_design.py b/tests/integration/test_design.py index 7b64ef583b..3636f2eba4 100644 --- a/tests/integration/test_design.py +++ b/tests/integration/test_design.py @@ -17,6 +17,7 @@ ) from ansys.geometry.core.designer.face import FaceLoopType from ansys.geometry.core.errors import GeometryExitedError +from ansys.geometry.core.geometry.parameterization import ParamUV from ansys.geometry.core.materials import Material, MaterialProperty, MaterialPropertyType from ansys.geometry.core.math import ( IDENTITY_MATRIX44, @@ -151,7 +152,7 @@ def test_face_to_body_creation(modeler: Modeler): assert len(nested_component.components) == 0 assert len(nested_component.bodies) == 1 assert surface_body.volume.m == Quantity(0, UNITS.m**3).m - assert surface_body.faces[0].shape.area.m == pytest.approx( + assert surface_body.faces[0].area.m == pytest.approx( Quantity(2e-4, UNITS.m**2).m, rel=1e-6, abs=1e-8 ) @@ -314,16 +315,14 @@ def test_faces_edges(modeler: Modeler): # Build independent components and bodies polygon_comp = design.add_component("PolygonComponent") body_polygon_comp = polygon_comp.extrude_sketch("Polygon", sketch, Quantity(30, UNITS.mm)) - + design.download(r"D:\Work\Projects\PyGeometry\test104.scdocx") # Get all its faces faces = body_polygon_comp.faces assert len(faces) == 7 # top + bottom + sides assert all(face.id is not None for face in faces) assert all(face.surface_type == SurfaceType.SURFACETYPE_PLANE for face in faces) - assert all(face.shape.area > 0.0 for face in faces) - assert ( - abs(faces[0].shape.area.to_base_units().m - sketch.faces[0].area.to_base_units().m) <= 1e-15 - ) + assert all(face.area > 0.0 for face in faces) + assert abs(faces[0].area.to_base_units().m - sketch.faces[0].area.to_base_units().m) <= 1e-15 assert all(face.body.id == body_polygon_comp.id for face in faces) # Get the normal to some of the faces @@ -331,8 +330,9 @@ def test_faces_edges(modeler: Modeler): assert faces[1].normal() == UNITVECTOR3D_Z # Top # Get the central point of some of the surfaces - assert faces[0].point(u=-0.03, v=-0.03) == Point3D([-30, -30, 0], UNITS.mm) - assert faces[1].point(u=-0.03, v=-0.03) == Point3D([-30, -30, 30], UNITS.mm) + assert faces[0].point(0.4472135954999579, 0.5) == Point3D([-30, -30, 0], UNITS.mm) + u, v = faces[1].shape.get_proportional_parameters(ParamUV(-0.03, -0.03)) + assert faces[1].point(u, v) == Point3D([-30, -30, 30], UNITS.mm) loops = faces[0].loops assert len(loops) == 1 diff --git a/tests/integration/test_edges.py b/tests/integration/test_edges.py index a48daab810..316dd6bca0 100644 --- a/tests/integration/test_edges.py +++ b/tests/integration/test_edges.py @@ -15,7 +15,7 @@ def test_edges_startend_prism(modeler: Modeler): body_sketch.box(Point2D([10, 10], UNITS.m), Quantity(5, UNITS.m), Quantity(3, UNITS.m)) prism_body = design.extrude_sketch("JustAPrism", body_sketch, Quantity(13, UNITS.m)) for edge in prism_body.edges: - vec = Vector3D.from_points(edge.start_point, edge.end_point) + vec = Vector3D.from_points(edge.shape.start, edge.shape.end) assert vec.magnitude == edge.length.magnitude @@ -28,4 +28,4 @@ def test_edges_startend_cylinder(modeler: Modeler): cylinder.circle(Point2D([10, 10], UNITS.m), 1.0) cylinder_body = design.extrude_sketch("JustACyl", cylinder, Quantity(10, UNITS.m)) for edge in cylinder_body.edges: - assert edge.start_point == edge.end_point + assert edge.shape.start == edge.shape.end From 8e4a4690ae8711f20e1f9a5b4bb7184ce786cf51 Mon Sep 17 00:00:00 2001 From: Dastan Abdulla Date: Wed, 31 Jan 2024 07:39:30 -0500 Subject: [PATCH 17/76] added trimmed surface and curve tests for hedgehog --- src/ansys/geometry/core/designer/face.py | 2 +- tests/integration/test_design.py | 4 +- tests/integration/test_trimmed_geometry.py | 206 +++++++++++++++++++++ 3 files changed, 209 insertions(+), 3 deletions(-) create mode 100644 tests/integration/test_trimmed_geometry.py diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index 954d022ba9..bbe6b5f5a2 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -227,7 +227,7 @@ def area(self) -> Quantity: @property @protect_grpc @ensure_design_is_active - def edges(self) -> List[Edge]: + def edges(self) -> List["Edge"]: """List of all edges of the face.""" self._grpc_client.log.debug("Requesting face edges from server.") edges_response = self._faces_stub.GetEdges(self._grpc_id) diff --git a/tests/integration/test_design.py b/tests/integration/test_design.py index f14ae0e485..ce9b41b051 100644 --- a/tests/integration/test_design.py +++ b/tests/integration/test_design.py @@ -810,13 +810,13 @@ def test_body_rotation(modeler: Modeler): original_vertices = [] for edge in body.edges: - original_vertices.extend([edge.start_point, edge.end_point]) + original_vertices.extend([edge.shape.start, edge.shape.end]) body.rotate(Point3D([0, 0, 0]), UnitVector3D([0, 0, 1]), np.pi / 4) new_vertices = [] for edge in body.edges: - new_vertices.extend([edge.start_point, edge.end_point]) + new_vertices.extend([edge.shape.start, edge.shape.end]) # Make sure no vertices are in the same position as in before rotation for old_vertex, new_vertex in zip(original_vertices, new_vertices): diff --git a/tests/integration/test_trimmed_geometry.py b/tests/integration/test_trimmed_geometry.py new file mode 100644 index 0000000000..ce31703052 --- /dev/null +++ b/tests/integration/test_trimmed_geometry.py @@ -0,0 +1,206 @@ +from ansys.api.geometry.v0.commands_pb2 import CreateSketchLineRequest +import numpy as np +import pytest + +from ansys.geometry.core.connection.conversions import point3d_to_grpc_point +from ansys.geometry.core.designer.design import Design +from ansys.geometry.core.designer.face import SurfaceType +from ansys.geometry.core.geometry import Circle, Line +from ansys.geometry.core.geometry.box_uv import LocationUV +from ansys.geometry.core.geometry.curves.trimmed_curve import ReversedTrimmedCurve, TrimmedCurve +from ansys.geometry.core.geometry.parameterization import Interval +from ansys.geometry.core.geometry.surfaces.trimmed_surface import ( + ReversedTrimmedSurface, + TrimmedSurface, +) +from ansys.geometry.core.math import Point3D, UnitVector3D +from ansys.geometry.core.math.point import Point2D +from ansys.geometry.core.modeler import Modeler +from ansys.geometry.core.sketch.sketch import Sketch + + +def create_sketch_line(design: Design, p1: Point3D, p2: Point3D): + point1 = point3d_to_grpc_point(p1) + point2 = point3d_to_grpc_point(p2) + design._commands_stub.CreateSketchLine(CreateSketchLineRequest(point1=point1, point2=point2)) + + +def create_hedgehog(modeler: Modeler): + design = modeler.create_design("Hedgehog") + sketch = Sketch().arc_from_three_points( + Point2D([0.01, 0.01]), Point2D([0, -0.005]), Point2D([-0.01, 0.01]) + ) + sketch.arc_from_three_points( + Point2D([0.01, 0.01]), Point2D([0, 0]), Point2D([-0.01, 0.01]) + ).circle(Point2D([0, 0]), 0.02) + body = design.extrude_sketch("Cylinder", sketch, 0.02) + # Add points to edges and corners - no missing corners + points_between_corners = 4 + for edge in body.edges: + total_point_gaps = np.floor(edge.length.m * 1000 / points_between_corners) + current_gap = 0 + while current_gap < total_point_gaps: + design.add_design_point( + f"Point_{current_gap}", + edge.shape.evaluate_proportion(current_gap / total_point_gaps).position, + ) + current_gap += 1 + # Add hedgehog hairs (face-normals) to these points + for face in body.faces: + for edge in face.edges: + total_point_gaps = np.floor(edge.length.m * 1000 / points_between_corners) + current_gap = 0 + while current_gap < total_point_gaps + 1: + p1 = edge.shape.evaluate_proportion(current_gap / total_point_gaps).position + uv = face.shape.project_point(p1).parameter + u, v = face.shape.get_proportional_parameters(uv) + normal = face.normal(u, v) + p2 = design.add_design_point("hair", p1 + normal / 800).value + create_sketch_line(design, p1, p2) + current_gap += 1 + # Add isoparametric curves + param = 0.20 + while param <= 1: + for face in body.faces: + face.create_isoparametric_curves(True, param) # u + face.create_isoparametric_curves(False, param) # v + param += 0.20 + return design + + +@pytest.fixture +def hedgehog_design(modeler: Modeler): + h = create_hedgehog(modeler) + yield h + + +def test_trimmed_surface_properties(hedgehog_design): + hedgehog_body = hedgehog_design.bodies[0] + faces = hedgehog_body.faces + + expected_surface_properties = [ + ( + SurfaceType.SURFACETYPE_CYLINDER, + False, + TrimmedSurface, + (0.0, 6.283185307179586), + (0.0, 0.02), + ), + ( + SurfaceType.SURFACETYPE_PLANE, + True, + ReversedTrimmedSurface, + (-0.02024, 0.02024), + (-0.02024, 0.02024), + ), + ( + SurfaceType.SURFACETYPE_PLANE, + False, + TrimmedSurface, + (-0.02024, 0.02024), + (-0.02024, 0.02024), + ), + ( + SurfaceType.SURFACETYPE_CYLINDER, + True, + ReversedTrimmedSurface, + (2.746801533890032, 6.677976426879348), + (0.0, 0.02), + ), + ( + SurfaceType.SURFACETYPE_CYLINDER, + False, + TrimmedSurface, + (3.141592653589793, 6.283185307179586), + (0.0, 0.02), + ), + ] + + for i, (surface_type, is_reversed, shape_type, interval_u, interval_v) in enumerate( + expected_surface_properties + ): + assert faces[i].surface_type == surface_type + assert faces[i]._is_reversed == is_reversed + assert isinstance(faces[i].shape, shape_type) + assert faces[i].shape.box_uv.interval_u == Interval(start=interval_u[0], end=interval_u[1]) + assert faces[i].shape.box_uv.interval_v == Interval(start=interval_v[0], end=interval_v[1]) + + +def test_trimmed_surface_normals(hedgehog_design): + hedgehog_body = hedgehog_design.bodies[0] + faces = hedgehog_body.faces + # corners to consider + corners = [ + LocationUV.TopLeft, + LocationUV.BottomLeft, + LocationUV.TopRight, + LocationUV.BottomRight, + ] + + expected_normals = [ + ( + UnitVector3D([1.0, 0.0, 0.0]), + UnitVector3D([1.0, 0.0, 0.0]), + UnitVector3D([-0.20700185, 0.97834055, 0.0]), + UnitVector3D([-0.20700185, 0.97834055, 0.0]), + ), + ( + UnitVector3D([-0.0, -0.0, -1.0]), + UnitVector3D([-0.0, -0.0, -1.0]), + UnitVector3D([-0.0, -0.0, -1.0]), + UnitVector3D([-0.0, -0.0, -1.0]), + ), + ( + UnitVector3D([0.0, 0.0, 1.0]), + UnitVector3D([0.0, 0.0, 1.0]), + UnitVector3D([0.0, 0.0, 1.0]), + UnitVector3D([0.0, 0.0, 1.0]), + ), + ( + UnitVector3D([-0.55819453, -0.82971011, -0.0]), + UnitVector3D([-0.55819453, -0.82971011, -0.0]), + UnitVector3D([0.74865795, 0.66295647, 0.0]), + UnitVector3D([0.74865795, 0.66295647, 0.0]), + ), + ( + UnitVector3D([0.90268536, 0.43030122, 0.0]), + UnitVector3D([0.90268536, 0.43030122, 0.0]), + UnitVector3D([-0.62968173, -0.77685322, -0.0]), + UnitVector3D([-0.62968173, -0.77685322, -0.0]), + ), + ] + + for i, (top_left, bottom_left, top_right, bottom_right) in enumerate(expected_normals): + corner_param = faces[i].shape.box_uv.get_corner(corners[0]) + assert np.allclose(faces[i].shape.normal(corner_param.u, corner_param.v), top_left) + corner_param = faces[i].shape.box_uv.get_corner(corners[1]) + assert np.allclose(faces[i].shape.normal(corner_param.u, corner_param.v), bottom_left) + corner_param = faces[i].shape.box_uv.get_corner(corners[2]) + assert np.allclose(faces[i].shape.normal(corner_param.u, corner_param.v), top_right) + corner_param = faces[i].shape.box_uv.get_corner(corners[3]) + assert np.allclose(faces[i].shape.normal(corner_param.u, corner_param.v), bottom_right) + + +def test_trimmed_curve_properties(hedgehog_design): + hedgehog_body = hedgehog_design.bodies[0] + edges = hedgehog_body.edges + + expected_curve_properties = [ + (True, ReversedTrimmedCurve, Circle, [-0.01, 0.01, 0.02], [0.01, 0.01, 0.02]), + (False, TrimmedCurve, Line, [-0.01, 0.01, 0.0], [-0.01, 0.01, 0.02]), + (False, TrimmedCurve, Circle, [0.01, 0.01, 0.02], [-0.01, 0.01, 0.02]), + (False, TrimmedCurve, Line, [0.01, 0.01, 0.0], [0.01, 0.01, 0.02]), + (True, ReversedTrimmedCurve, Circle, [-0.01, 0.01, 0.0], [0.01, 0.01, 0.0]), + (False, TrimmedCurve, Circle, [0.01, 0.01, 0.0], [-0.01, 0.01, 0.0]), + (False, TrimmedCurve, Circle, [0.02, 0.0, 0.02], [0.02, 0.0, 0.02]), + (False, TrimmedCurve, Circle, [0.02, 0.0, 0.0], [0.02, 0.0, 0.0]), + ] + + for i, (is_reversed, shape_type, geometry_type, start, end) in enumerate( + expected_curve_properties + ): + assert edges[i]._is_reversed == is_reversed + assert isinstance(edges[i].shape, shape_type) + assert isinstance(edges[i].shape.geometry, geometry_type) + assert np.allclose(edges[i].shape.start, Point3D(start)) + assert np.allclose(edges[i].shape.end, Point3D(end)) From 7863a5fb7a3bf327601ccf2e5a1dbb1d7493f7a3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:22:50 +0000 Subject: [PATCH 18/76] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/ansys/geometry/core/geometry/box_uv.py | 2 +- .../geometry/core/geometry/curves/curve.py | 2 +- .../core/geometry/curves/trimmed_curve.py | 2 +- .../geometry/core/geometry/surfaces/plane.py | 2 +- .../core/geometry/surfaces/surface.py | 2 +- .../core/geometry/surfaces/trimmed_surface.py | 2 +- tests/integration/test_trimmed_geometry.py | 22 +++++++++++++++++++ 7 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/ansys/geometry/core/geometry/box_uv.py b/src/ansys/geometry/core/geometry/box_uv.py index 050b4c785e..38556ba2db 100644 --- a/src/ansys/geometry/core/geometry/box_uv.py +++ b/src/ansys/geometry/core/geometry/box_uv.py @@ -1,4 +1,4 @@ -# Copyright (C) 2023 ANSYS, Inc. and/or its affiliates. +# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates. # SPDX-License-Identifier: MIT # # diff --git a/src/ansys/geometry/core/geometry/curves/curve.py b/src/ansys/geometry/core/geometry/curves/curve.py index f3c3d506d1..b341efaa93 100644 --- a/src/ansys/geometry/core/geometry/curves/curve.py +++ b/src/ansys/geometry/core/geometry/curves/curve.py @@ -1,4 +1,4 @@ -# Copyright (C) 2023 ANSYS, Inc. and/or its affiliates. +# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates. # SPDX-License-Identifier: MIT # # diff --git a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py index 437381d5bb..779a90d130 100644 --- a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py +++ b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py @@ -1,4 +1,4 @@ -# Copyright (C) 2023 ANSYS, Inc. and/or its affiliates. +# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates. # SPDX-License-Identifier: MIT # # diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index 587f9b7994..9e198c5620 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -1,4 +1,4 @@ -# Copyright (C) 2023 ANSYS, Inc. and/or its affiliates. +# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates. # SPDX-License-Identifier: MIT # # diff --git a/src/ansys/geometry/core/geometry/surfaces/surface.py b/src/ansys/geometry/core/geometry/surfaces/surface.py index 55afc7fa30..ca758ff9c9 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface.py @@ -1,4 +1,4 @@ -# Copyright (C) 2023 ANSYS, Inc. and/or its affiliates. +# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates. # SPDX-License-Identifier: MIT # # diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index 957fda9dc9..7374673168 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -1,4 +1,4 @@ -# Copyright (C) 2023 ANSYS, Inc. and/or its affiliates. +# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates. # SPDX-License-Identifier: MIT # # diff --git a/tests/integration/test_trimmed_geometry.py b/tests/integration/test_trimmed_geometry.py index ce31703052..78fada40e6 100644 --- a/tests/integration/test_trimmed_geometry.py +++ b/tests/integration/test_trimmed_geometry.py @@ -1,3 +1,25 @@ +# 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. + from ansys.api.geometry.v0.commands_pb2 import CreateSketchLineRequest import numpy as np import pytest From 9c6657bb2c2035a5a7fbefdf7190ff99bdeb4e2e Mon Sep 17 00:00:00 2001 From: jonahrb Date: Mon, 12 Feb 2024 10:53:58 -0500 Subject: [PATCH 19/76] Update test_design.py --- tests/integration/test_design.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_design.py b/tests/integration/test_design.py index e92c17f48d..5a54af7090 100644 --- a/tests/integration/test_design.py +++ b/tests/integration/test_design.py @@ -338,7 +338,7 @@ def test_faces_edges(modeler: Modeler): # Build independent components and bodies polygon_comp = design.add_component("PolygonComponent") body_polygon_comp = polygon_comp.extrude_sketch("Polygon", sketch, Quantity(30, UNITS.mm)) - design.download(r"D:\Work\Projects\PyGeometry\test104.scdocx") + # Get all its faces faces = body_polygon_comp.faces assert len(faces) == 7 # top + bottom + sides From 3a207aeb5925742815f6c8c8f6ee9e174eae7cf4 Mon Sep 17 00:00:00 2001 From: jonahrb Date: Mon, 12 Feb 2024 11:28:24 -0500 Subject: [PATCH 20/76] cleanup some errors --- src/ansys/geometry/core/geometry/box_uv.py | 7 ------- tests/integration/test_trimmed_geometry.py | 17 +++++++++-------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/ansys/geometry/core/geometry/box_uv.py b/src/ansys/geometry/core/geometry/box_uv.py index 38556ba2db..4454ecb446 100644 --- a/src/ansys/geometry/core/geometry/box_uv.py +++ b/src/ansys/geometry/core/geometry/box_uv.py @@ -148,13 +148,6 @@ def inflate(self, delta_u: Real, delta_v: Real) -> "BoxUV": raise Exception("Invalid Method On Empty Object Exception" + type(self).__name__) return BoxUV(self.interval_u.inflate(delta_u), self.interval_v.inflate(delta_v)) - def inflate(self, delta: Real) -> "BoxUV": - """Enlarge the BoxUV by a given delta.""" - if self.is_empty(): - # throw Error.InvalidMethodOnEmptyObjectException(GetType()) - raise Exception("Invalid Method On Empty Object Exception" + type(self).__name__) - return BoxUV(self.interval_u.inflate(delta), self.interval_v.inflate(delta)) - def get_corner(self, location: LocationUV) -> ParamUV: """Return the corner location of the BoxUV.""" u = 0 diff --git a/tests/integration/test_trimmed_geometry.py b/tests/integration/test_trimmed_geometry.py index 78fada40e6..ca55dda0d9 100644 --- a/tests/integration/test_trimmed_geometry.py +++ b/tests/integration/test_trimmed_geometry.py @@ -24,7 +24,7 @@ import numpy as np import pytest -from ansys.geometry.core.connection.conversions import point3d_to_grpc_point +from ansys.geometry.core.connection import BackendType, point3d_to_grpc_point from ansys.geometry.core.designer.design import Design from ansys.geometry.core.designer.face import SurfaceType from ansys.geometry.core.geometry import Circle, Line @@ -80,13 +80,14 @@ def create_hedgehog(modeler: Modeler): p2 = design.add_design_point("hair", p1 + normal / 800).value create_sketch_line(design, p1, p2) current_gap += 1 - # Add isoparametric curves - param = 0.20 - while param <= 1: - for face in body.faces: - face.create_isoparametric_curves(True, param) # u - face.create_isoparametric_curves(False, param) # v - param += 0.20 + # Add isoparametric curves, not on linux + if modeler.client.backend_type != BackendType.LINUX_SERVICE: + param = 0.20 + while param <= 1: + for face in body.faces: + face.create_isoparametric_curves(True, param) # u + face.create_isoparametric_curves(False, param) # v + param += 0.20 return design From ad2ec2065345af1df7d3ef2bbc405d0f4007b740 Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Tue, 20 Feb 2024 12:06:46 -0500 Subject: [PATCH 21/76] formatted comment block for interval --- .../core/geometry/parameterization.py | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py index 7e64a35e29..3c035bdc25 100644 --- a/src/ansys/geometry/core/geometry/parameterization.py +++ b/src/ansys/geometry/core/geometry/parameterization.py @@ -210,8 +210,9 @@ def is_empty(self) -> bool: """ If the current interval is empty return true, else return false. - Returns: - Bool + Returns + ------- + bool The value that indicates whether the interval is empty or not. """ return not self.not_empty @@ -237,8 +238,10 @@ def get_relative_val(self, t: Real) -> Real: Args: t (Real): The offset that the interval gets evaluated at. - Returns: - Real: The actual value according to the offset + Returns + ------- + Real + The actual value according to the offset """ return self.start + t * self.get_span() @@ -249,8 +252,10 @@ def is_negative(self, tolerance: Real) -> bool: Args: tolerance (Real): The accepted range since we could be working with doubles - Returns: - bool: True if negative False otherwise + Returns + ------- + bool + True if negative False otherwise """ return Accuracy.compare_with_tolerance(self.get_span(), 0, tolerance, tolerance) @@ -264,7 +269,9 @@ def unite(first: "Interval", second: "Interval") -> "Interval": second (Interval): Second Interval Returns: - Interval: The union of the two intervals + ------- + Interval + The union of the two intervals """ if first.is_empty(): return second @@ -281,8 +288,10 @@ def intersect(first: "Interval", second: "Interval", tolerance: Real) -> "Interv first (Interval): First Interval second (Interval): Second Interval - Returns: - Interval: The intersection of the two intervals + Returns + ------- + Interval + The intersection of the two intervals """ if first.is_empty() or second.is_empty(): return None # supposed to be empty @@ -300,7 +309,9 @@ def contains(self, t: Real, accuracy: Real) -> bool: accuracy (Real): The accepted range of error since we could be working with floats Returns: - bool: True if the interval contains the value, false otherwise + ------- + bool + True if the interval contains the value, false otherwise """ if self.is_empty(): return False @@ -326,8 +337,10 @@ def contains(self, t: Real) -> bool: Args: t (Real): The value of interest - Returns: - bool: True if the interval contains the value, false otherwise + Returns + ------- + bool + True if the interval contains the value, false otherwise """ return self.contains(t, Accuracy.length_accuracy) From b8ed01c89b8074a192c947633478d33c7a6fc344 Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Tue, 20 Feb 2024 12:20:11 -0500 Subject: [PATCH 22/76] fixed 'title underline too short issue for interval' --- src/ansys/geometry/core/geometry/parameterization.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py index 3c035bdc25..227b31763b 100644 --- a/src/ansys/geometry/core/geometry/parameterization.py +++ b/src/ansys/geometry/core/geometry/parameterization.py @@ -268,7 +268,7 @@ def unite(first: "Interval", second: "Interval") -> "Interval": first (Interval): First Interval second (Interval): Second Interval - Returns: + Returns ------- Interval The union of the two intervals @@ -308,7 +308,7 @@ def contains(self, t: Real, accuracy: Real) -> bool: t (Real): The value of interest accuracy (Real): The accepted range of error since we could be working with floats - Returns: + Returns ------- bool True if the interval contains the value, false otherwise From 9432f945fa6237c7e0fe4a6ec1fd0ecc04e0c47d Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Tue, 20 Feb 2024 12:41:49 -0500 Subject: [PATCH 23/76] resolving the duplicate contains docstring --- .../core/geometry/parameterization.py | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py index 227b31763b..b7c447e18b 100644 --- a/src/ansys/geometry/core/geometry/parameterization.py +++ b/src/ansys/geometry/core/geometry/parameterization.py @@ -235,8 +235,10 @@ def get_relative_val(self, t: Real) -> Real: """ Return an evaluation property of the interval, used in BoxUV. - Args: - t (Real): The offset that the interval gets evaluated at. + Parameters + ---------- + t : Real + The offset that the interval gets evaluated at. Returns ------- @@ -249,8 +251,10 @@ def is_negative(self, tolerance: Real) -> bool: """ Boolean value that indicates whether the current interval is negative. - Args: - tolerance (Real): The accepted range since we could be working with doubles + Parameters + ---------- + tolerance : Real + The accepted range since we could be working with doubles Returns ------- @@ -264,9 +268,12 @@ def unite(first: "Interval", second: "Interval") -> "Interval": """ Return the union of two intervals. - Args: - first (Interval): First Interval - second (Interval): Second Interval + Parameters + ---------- + first : Interval + First interval + second : Interval + Second interval Returns ------- @@ -284,9 +291,12 @@ def intersect(first: "Interval", second: "Interval", tolerance: Real) -> "Interv """ Return the intersection of two intervals. - Args: - first (Interval): First Interval - second (Interval): Second Interval + Parameters + ---------- + first : Interval + First interval + second : Interval + Second interval Returns ------- @@ -304,9 +314,12 @@ def contains(self, t: Real, accuracy: Real) -> bool: """ Check whether the current interval contains a value (t). - Args: - t (Real): The value of interest - accuracy (Real): The accepted range of error since we could be working with floats + Parameters + ---------- + t : Real + The value of interest + accuracy: Real + The accepted range of error since we could be working with floats Returns ------- @@ -330,12 +343,12 @@ def contains(self, t: Real, accuracy: Real) -> bool: def contains(self, t: Real) -> bool: """ - Check whether the current interval contains a value (t) using the default. + Check if interval contains t using the default length_accuracy constant. - length_accuracy constant. - - Args: - t (Real): The value of interest + Parameters + ---------- + t : Real + The value of interest Returns ------- From 4d2e2ed05d8b164289385505072b7b461385ac68 Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Tue, 20 Feb 2024 13:09:13 -0500 Subject: [PATCH 24/76] giving the contain functions different names --- src/ansys/geometry/core/geometry/parameterization.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py index b7c447e18b..188c5931bc 100644 --- a/src/ansys/geometry/core/geometry/parameterization.py +++ b/src/ansys/geometry/core/geometry/parameterization.py @@ -310,9 +310,9 @@ def intersect(first: "Interval", second: "Interval", tolerance: Real) -> "Interv return intersection return None # supposed to be empty - def contains(self, t: Real, accuracy: Real) -> bool: + def contains_value(self, t: Real, accuracy: Real) -> bool: """ - Check whether the current interval contains a value (t). + Check if the current interval contains value t given the accuracy range. Parameters ---------- @@ -355,7 +355,7 @@ def contains(self, t: Real) -> bool: bool True if the interval contains the value, false otherwise """ - return self.contains(t, Accuracy.length_accuracy) + return self.contains_value(t, Accuracy.length_accuracy) def inflate(self, delta: Real) -> "Interval": """Enlarge the current interval by the given delta value.""" From 8d633e47e05607bf34f0d1fc980d5c63aa0e8b0d Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Tue, 20 Feb 2024 13:22:32 -0500 Subject: [PATCH 25/76] resolving plane conflict doc --- src/ansys/geometry/core/geometry/surfaces/plane.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index 9e198c5620..fea70e1052 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -19,7 +19,7 @@ # 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. -"""The plane surface class.""" +"""Provides for creating and managing a cylinder.""" from functools import cached_property from beartype import beartype as check_input_types @@ -48,7 +48,7 @@ class Plane(Surface): """ - Provides 3D ``Plane`` representation. + Provides 3D plane representation. Parameters ---------- @@ -145,14 +145,14 @@ def evaluate(self, parameter: ParamUV) -> "PlaneEvaluation": class PlaneEvaluation(SurfaceEvaluation): """ - Provides ``Plane`` evaluation at certain parameters. + Provides evaluation of a plane at given parameters. Parameters ---------- plane: ~ansys.geometry.core.primitives.plane.Plane - The ``Plane`` object to be evaluated. + Plane to evaluated. parameter: ParamUV - The parameters (u, v) at which the ``Plane`` evaluation is requested. + Parameters (u, v) to evaluate the plane at. """ def __init__(self, plane: Plane, parameter: ParamUV) -> None: From f0b11da8bbc5d4138066d333fefedbb6569c66f1 Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Thu, 22 Feb 2024 11:25:04 -0500 Subject: [PATCH 26/76] changed Plane to PlaneSurface --- .../geometry/core/connection/conversions.py | 17 +++++++++++++---- src/ansys/geometry/core/geometry/__init__.py | 2 +- .../geometry/core/geometry/surfaces/plane.py | 14 +++++++------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/ansys/geometry/core/connection/conversions.py b/src/ansys/geometry/core/connection/conversions.py index 656d0d219f..18d393c8d7 100644 --- a/src/ansys/geometry/core/connection/conversions.py +++ b/src/ansys/geometry/core/connection/conversions.py @@ -38,9 +38,18 @@ from ansys.api.geometry.v0.models_pb2 import TrimmedCurve as GRPCTrimmedCurve from beartype.typing import TYPE_CHECKING, List, Optional, Tuple -from ansys.geometry.core.geometry import Circle, Cone, Curve, Cylinder, Ellipse, Line -from ansys.geometry.core.geometry import Plane as SurfacePlane -from ansys.geometry.core.geometry import Sphere, Surface, Torus +from ansys.geometry.core.geometry import ( + Circle, + Cone, + Curve, + Cylinder, + Ellipse, + Line, + PlaneSurface, + Sphere, + Surface, + Torus, +) from ansys.geometry.core.math import Frame, Matrix44, Plane, Point2D, Point3D, UnitVector3D from ansys.geometry.core.misc import DEFAULT_UNITS from ansys.geometry.core.sketch import ( @@ -471,7 +480,7 @@ def grpc_surface_to_surface(surface: GRPCSurface, surface_type: "SurfaceType") - elif surface_type == SurfaceType.SURFACETYPE_TORUS: result = Torus(origin, surface.major_radius, surface.minor_radius, reference, axis) elif surface_type == SurfaceType.SURFACETYPE_PLANE: - result = SurfacePlane(origin, reference, axis) + result = PlaneSurface(origin, reference, axis) else: result = None return result diff --git a/src/ansys/geometry/core/geometry/__init__.py b/src/ansys/geometry/core/geometry/__init__.py index 0ed82feb74..91d891c5c4 100644 --- a/src/ansys/geometry/core/geometry/__init__.py +++ b/src/ansys/geometry/core/geometry/__init__.py @@ -34,7 +34,7 @@ ) from ansys.geometry.core.geometry.surfaces.cone import Cone, ConeEvaluation from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder, CylinderEvaluation -from ansys.geometry.core.geometry.surfaces.plane import Plane, PlaneEvaluation +from ansys.geometry.core.geometry.surfaces.plane import PlaneEvaluation, PlaneSurface from ansys.geometry.core.geometry.surfaces.sphere import Sphere, SphereEvaluation from ansys.geometry.core.geometry.surfaces.surface import Surface from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index fea70e1052..56e33a0ecd 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -46,9 +46,9 @@ from ansys.geometry.core.typing import Real, RealSequence -class Plane(Surface): +class PlaneSurface(Surface): """ - Provides 3D plane representation. + Provides 3D plane surface representation. Parameters ---------- @@ -66,7 +66,7 @@ def __init__( reference: Union[np.ndarray, RealSequence, UnitVector3D, Vector3D] = UNITVECTOR3D_X, axis: Union[np.ndarray, RealSequence, UnitVector3D, Vector3D] = UNITVECTOR3D_Z, ): - """Initialize ``Plane`` class.""" + """Initialize ``PlaneSurface`` class.""" self._origin = Point3D(origin) if not isinstance(origin, Point3D) else origin self._reference = ( @@ -97,7 +97,7 @@ def dir_z(self) -> UnitVector3D: return self._axis @check_input_types - def __eq__(self, other: "Plane") -> bool: + def __eq__(self, other: "PlaneSurface") -> bool: """Check whether two planes are equal.""" return ( self._origin == other._origin @@ -132,7 +132,7 @@ def transformed_copy(self, matrix: Matrix44) -> Surface: new_point = self.origin.transform(matrix) new_reference = self._reference.transform(matrix) new_axis = self._axis.transform(matrix) - return Plane( + return PlaneSurface( new_point, UnitVector3D(new_reference[0:3]), UnitVector3D(new_axis[0:3]), @@ -155,13 +155,13 @@ class PlaneEvaluation(SurfaceEvaluation): Parameters (u, v) to evaluate the plane at. """ - def __init__(self, plane: Plane, parameter: ParamUV) -> None: + def __init__(self, plane: PlaneSurface, parameter: ParamUV) -> None: """``SphereEvaluation`` class constructor.""" self._plane = plane self._parameter = parameter @property - def plane(self) -> Plane: + def plane(self) -> PlaneSurface: """The plane being evaluated.""" return self._plane From 11be80a0f4190303d893acb57d76a2c791b3ecd4 Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Thu, 22 Feb 2024 12:22:56 -0500 Subject: [PATCH 27/76] updated the import location for Sphere and SphereEvaluation --- doc/source/examples/01_getting_started/01_math.mystnb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/examples/01_getting_started/01_math.mystnb b/doc/source/examples/01_getting_started/01_math.mystnb index 9809bd4498..b991af8e35 100644 --- a/doc/source/examples/01_getting_started/01_math.mystnb +++ b/doc/source/examples/01_getting_started/01_math.mystnb @@ -150,7 +150,7 @@ PyAnsys Geometry implements parametric evaluations for some curves and surfaces. Evaluate a sphere. ```{code-cell} ipython3 -from ansys.geometry.core.primitives.sphere import Sphere, SphereEvaluation +from ansys.geometry.core.geometry import Sphere, SphereEvaluation from ansys.geometry.core.math import Point3D from ansys.geometry.core.misc import Distance From 36084da318d4c8ab12080dbe81444722c5c75cad Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Thu, 22 Feb 2024 13:02:28 -0500 Subject: [PATCH 28/76] added init files for curves and surface directory --- .../geometry/core/geometry/curves/__init__.py | 27 +++++++++++++++++ .../core/geometry/surfaces/__init__.py | 29 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/ansys/geometry/core/geometry/curves/__init__.py create mode 100644 src/ansys/geometry/core/geometry/surfaces/__init__.py diff --git a/src/ansys/geometry/core/geometry/curves/__init__.py b/src/ansys/geometry/core/geometry/curves/__init__.py new file mode 100644 index 0000000000..0913b0636f --- /dev/null +++ b/src/ansys/geometry/core/geometry/curves/__init__.py @@ -0,0 +1,27 @@ +# 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 the PyGeometry ``curve`` subpackage.""" +from ansys.geometry.core.geometry.curves.circle import Circle, CircleEvaluation +from ansys.geometry.core.geometry.curves.curve import Curve +from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.geometry.curves.ellipse import Ellipse, EllipseEvaluation +from ansys.geometry.core.geometry.curves.line import Line, LineEvaluation diff --git a/src/ansys/geometry/core/geometry/surfaces/__init__.py b/src/ansys/geometry/core/geometry/surfaces/__init__.py new file mode 100644 index 0000000000..0e1c37030b --- /dev/null +++ b/src/ansys/geometry/core/geometry/surfaces/__init__.py @@ -0,0 +1,29 @@ +# 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 the PyGeometry ``surface`` subpackage.""" +from ansys.geometry.core.geometry.surfaces.cone import Cone, ConeEvaluation +from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder, CylinderEvaluation +from ansys.geometry.core.geometry.surfaces.plane import PlaneEvaluation, PlaneSurface +from ansys.geometry.core.geometry.surfaces.sphere import Sphere, SphereEvaluation +from ansys.geometry.core.geometry.surfaces.surface import Surface +from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation +from ansys.geometry.core.geometry.surfaces.torus import Torus From 6f4ed378a0a52ed858579b231c622e27586b3653 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:50:36 -0500 Subject: [PATCH 29/76] Update src/ansys/geometry/core/geometry/parameterization.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/parameterization.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py index 188c5931bc..ebbdf21f92 100644 --- a/src/ansys/geometry/core/geometry/parameterization.py +++ b/src/ansys/geometry/core/geometry/parameterization.py @@ -343,17 +343,17 @@ def contains_value(self, t: Real, accuracy: Real) -> bool: def contains(self, t: Real) -> bool: """ - Check if interval contains t using the default length_accuracy constant. + Check if the interval contains value ``t`` using the default ``length_accuracy`` constant. Parameters ---------- t : Real - The value of interest + Value of interest. Returns ------- bool - True if the interval contains the value, false otherwise + ``True`` if the interval contains the value, ``False`` otherwise. """ return self.contains_value(t, Accuracy.length_accuracy) From a0e1e2faf0d8d7851c66e0656a315817aec0acd3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 04:50:52 +0000 Subject: [PATCH 30/76] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/ansys/geometry/core/geometry/parameterization.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py index ebbdf21f92..8cb55bbb64 100644 --- a/src/ansys/geometry/core/geometry/parameterization.py +++ b/src/ansys/geometry/core/geometry/parameterization.py @@ -343,7 +343,8 @@ def contains_value(self, t: Real, accuracy: Real) -> bool: def contains(self, t: Real) -> bool: """ - Check if the interval contains value ``t`` using the default ``length_accuracy`` constant. + Check if the interval contains value ``t`` using the default ``length_accuracy`` + constant. Parameters ---------- From 90eb5537e2ada11a67b32fc3b1c8d91918d90f82 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:51:44 -0500 Subject: [PATCH 31/76] Update src/ansys/geometry/core/geometry/surfaces/cone.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/cone.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/cone.py b/src/ansys/geometry/core/geometry/surfaces/cone.py index 501651aa84..a04cfc0391 100644 --- a/src/ansys/geometry/core/geometry/surfaces/cone.py +++ b/src/ansys/geometry/core/geometry/surfaces/cone.py @@ -242,7 +242,7 @@ def project_point(self, point: Point3D) -> "ConeEvaluation": def parameterization(self) -> tuple[Parameterization, Parameterization]: """ - Parameterization of the cone surface as a tuple (U and V respectively). + Parameterize the cone surface as a tuple (U and V respectively). The U parameter specifies the clockwise angle around the axis (right-hand corkscrew law), with a zero parameter at ``dir_x`` and a period of 2*pi. From 844486a17eae15600ebc51bf3e46133b9b06ff31 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:52:01 -0500 Subject: [PATCH 32/76] Update src/ansys/geometry/core/geometry/surfaces/cylinder.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/cylinder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/cylinder.py b/src/ansys/geometry/core/geometry/surfaces/cylinder.py index 7e7224f0c3..48018dbb9c 100644 --- a/src/ansys/geometry/core/geometry/surfaces/cylinder.py +++ b/src/ansys/geometry/core/geometry/surfaces/cylinder.py @@ -253,7 +253,7 @@ def project_point(self, point: Point3D) -> "CylinderEvaluation": def parameterization(self) -> tuple[Parameterization, Parameterization]: """ - Parameterization of the cylinder surface as a tuple (U and V respectively). + Parameterize the cylinder surface as a tuple (U and V respectively). The U parameter specifies the clockwise angle around the axis (right-hand corkscrew law), with a zero parameter at ``dir_x`` and a period of 2*pi. From 8843296faa9789af39ea364c5d489d461dd0ea36 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:52:21 -0500 Subject: [PATCH 33/76] Update src/ansys/geometry/core/geometry/surfaces/plane.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/plane.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index 56e33a0ecd..fe9029ab7f 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -66,7 +66,7 @@ def __init__( reference: Union[np.ndarray, RealSequence, UnitVector3D, Vector3D] = UNITVECTOR3D_X, axis: Union[np.ndarray, RealSequence, UnitVector3D, Vector3D] = UNITVECTOR3D_Z, ): - """Initialize ``PlaneSurface`` class.""" + """Initialize `an instance of a plane surface.""" self._origin = Point3D(origin) if not isinstance(origin, Point3D) else origin self._reference = ( From dd3a421e53105d995d5dfc068a91ad917f7309d0 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:52:39 -0500 Subject: [PATCH 34/76] Update src/ansys/geometry/core/geometry/surfaces/plane.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/plane.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index fe9029ab7f..e805fd9ef1 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -114,7 +114,7 @@ def contains_point(self, point: Point3D) -> bool: raise NotImplementedError("contains_point() is not implemented.") def parameterization(self) -> tuple[Parameterization, Parameterization]: - """Return plane parametrization.""" + """Parametrize the plane.""" u = Parameterization(ParamForm.OPEN, ParamType.LINEAR, Interval(np.NINF, np.inf)) v = Parameterization(ParamForm.OPEN, ParamType.LINEAR, Interval(np.NINF, np.inf)) From 360c83e027eb73561260d34bb0a2ce788e827f55 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:52:51 -0500 Subject: [PATCH 35/76] Update src/ansys/geometry/core/geometry/surfaces/plane.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/plane.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index e805fd9ef1..2af2082f3e 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -128,7 +128,7 @@ def project_point(self, point: Point3D) -> SurfaceEvaluation: return PlaneEvaluation(self, ParamUV(u, v)) def transformed_copy(self, matrix: Matrix44) -> Surface: - """Return transformed version of the plane given the transform matrix.""" + """Get a transformed version of the plane given the transform matrix.""" new_point = self.origin.transform(matrix) new_reference = self._reference.transform(matrix) new_axis = self._axis.transform(matrix) From 234de70fb980a7f11a9e3956a5f17ee7c5293e4c Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:53:01 -0500 Subject: [PATCH 36/76] Update src/ansys/geometry/core/geometry/surfaces/plane.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/plane.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index 2af2082f3e..5777ffb1f1 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -150,7 +150,7 @@ class PlaneEvaluation(SurfaceEvaluation): Parameters ---------- plane: ~ansys.geometry.core.primitives.plane.Plane - Plane to evaluated. + Plane to evaluate. parameter: ParamUV Parameters (u, v) to evaluate the plane at. """ From 8c404a805403d9c377239efe7ad4e0ba7f9939ee Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:53:23 -0500 Subject: [PATCH 37/76] Update src/ansys/geometry/core/geometry/surfaces/plane.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- .../geometry/core/geometry/surfaces/plane.py | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index 5777ffb1f1..ce47b12ba9 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -162,17 +162,17 @@ def __init__(self, plane: PlaneSurface, parameter: ParamUV) -> None: @property def plane(self) -> PlaneSurface: - """The plane being evaluated.""" + """Plane being evaluated.""" return self._plane @property def parameter(self) -> ParamUV: - """The parameter that the evaluation is based upon.""" + """Parameter that the evaluation is based upon.""" return self._parameter @cached_property def position(self) -> Point3D: - """The point on the surface, based on the evaluation.""" + """Point on the surface, based on the evaluation.""" return ( self.plane.origin + self.parameter.u * self.plane.dir_x @@ -181,50 +181,50 @@ def position(self) -> Point3D: @cached_property def normal(self) -> UnitVector3D: - """The normal to the surface.""" + """Normal to the surface.""" return self.plane.dir_z @cached_property def u_derivative(self) -> Vector3D: - """The first derivative with respect to u.""" + """First derivative with respect to u.""" return self.plane.dir_z @cached_property def v_derivative(self) -> Vector3D: - """The first derivative with respect to v.""" + """First derivative with respect to v.""" return self.plane.dir_y @cached_property def uu_derivative(self) -> Vector3D: - """The second derivative with respect to u.""" + """Second derivative with respect to u.""" return Vector3D([0, 0, 0]) @cached_property def uv_derivative(self) -> Vector3D: - """The second derivative with respect to u and v.""" + """Second derivative with respect to u and v.""" return Vector3D([0, 0, 0]) @cached_property def vv_derivative(self) -> Vector3D: - """The second derivative with respect to v.""" + """Second derivative with respect to v.""" return Vector3D([0, 0, 0]) @cached_property def min_curvature(self) -> Real: - """The minimum curvature.""" + """Minimum curvature.""" return 0 @cached_property def min_curvature_direction(self) -> UnitVector3D: - """The minimum curvature direction.""" + """Minimum curvature direction.""" return self.plane.dir_x @cached_property def max_curvature(self) -> Real: - """The maximum curvature.""" + """Maximum curvature.""" return 0 @cached_property def max_curvature_direction(self) -> UnitVector3D: - """The maximum curvature direction.""" + """Maximum curvature direction.""" return self.plane.dir_y From ef73f2673fcf390c4dc8a7b5589bb21e917be62e Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:53:48 -0500 Subject: [PATCH 38/76] Update src/ansys/geometry/core/geometry/surfaces/sphere.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/sphere.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/sphere.py b/src/ansys/geometry/core/geometry/surfaces/sphere.py index 630a9ae6c1..17a9264872 100644 --- a/src/ansys/geometry/core/geometry/surfaces/sphere.py +++ b/src/ansys/geometry/core/geometry/surfaces/sphere.py @@ -216,8 +216,8 @@ def parameterization(self) -> tuple[Parameterization, Parameterization]: ``dir_z`` (right-hand corkscrew law). It has a zero parameter at ``dir_x`` and a period of ``2*pi``. - The V parameter specifies the latitude, increasing North, with a zero parameter - at the equator, and a range of [-pi/2, pi/2]. + The V parameter specifies the latitude, increasing north, with a zero parameter + at the equator and a range of [-pi/2, pi/2]. Returns ------- From 16ee6d42542fbe1f17b51b4b3d091480f994dc18 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:53:58 -0500 Subject: [PATCH 39/76] Update src/ansys/geometry/core/geometry/surfaces/surface.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/surface.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/surface.py b/src/ansys/geometry/core/geometry/surfaces/surface.py index ca758ff9c9..2b9c127b39 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface.py @@ -30,8 +30,6 @@ class Surface(ABC): """ Surface abstract base class. - - Represents a 3D surface. """ @abstractmethod From c057f1f7385cdff02645e5cc4983e326ff585991 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:54:08 -0500 Subject: [PATCH 40/76] Update src/ansys/geometry/core/geometry/surfaces/surface.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/surface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/surface.py b/src/ansys/geometry/core/geometry/surfaces/surface.py index 2b9c127b39..be03c3048d 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface.py @@ -34,7 +34,7 @@ class Surface(ABC): @abstractmethod def parameterization(self) -> tuple[Parameterization, Parameterization]: - """Parameterization of the surface as a tuple (U and V respectively).""" + """Parameterize the surface as a tuple (U and V respectively).""" return @abstractmethod From af1fd8c320feddf1e4ff978c843a44e8750cc28d Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:54:18 -0500 Subject: [PATCH 41/76] Update src/ansys/geometry/core/geometry/surfaces/surface.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/surface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/surface.py b/src/ansys/geometry/core/geometry/surfaces/surface.py index be03c3048d..691aa68459 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface.py @@ -47,7 +47,7 @@ def contains_point(self, point: Point3D) -> bool: """ Test whether the point is contained by the surface. - The point can either lie within it, or on its boundary. + The point can either lie within the surface or on its boundary. """ return From fb158796a9b33ec393c51debde2c3891df8c712f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 04:54:18 +0000 Subject: [PATCH 42/76] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/ansys/geometry/core/geometry/surfaces/surface.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/surface.py b/src/ansys/geometry/core/geometry/surfaces/surface.py index 691aa68459..fd579b5f63 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface.py @@ -28,9 +28,7 @@ class Surface(ABC): - """ - Surface abstract base class. - """ + """Surface abstract base class.""" @abstractmethod def parameterization(self) -> tuple[Parameterization, Parameterization]: From 376191f017d4b2714039a1da967f0511b472fcf5 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:54:39 -0500 Subject: [PATCH 43/76] Update src/ansys/geometry/core/geometry/surfaces/surface.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/surface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/surface.py b/src/ansys/geometry/core/geometry/surfaces/surface.py index fd579b5f63..1028b39fdd 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface.py @@ -69,7 +69,7 @@ def project_point(self, point: Point3D) -> SurfaceEvaluation: """ Project a point to the surface. - This returns the evaluation at the closest point. + This method returns the evaluation at the closest point. """ return From aa508a3b2dd7e56091238feef55207e55110b00f Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:54:47 -0500 Subject: [PATCH 44/76] Update src/ansys/geometry/core/geometry/surfaces/torus.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/torus.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/torus.py b/src/ansys/geometry/core/geometry/surfaces/torus.py index 6967ce6d06..d941b91621 100644 --- a/src/ansys/geometry/core/geometry/surfaces/torus.py +++ b/src/ansys/geometry/core/geometry/surfaces/torus.py @@ -201,7 +201,7 @@ def evaluate(self, parameter: ParamUV) -> "TorusEvaluation": def parameterization(self) -> tuple[Parameterization, Parameterization]: """ - Parameterization of the torus surface as a tuple (U and V respectively). + Parameterize the torus surface as a tuple (U and V respectively). The U parameter specifies the longitude angle, increasing clockwise (east) about the axis (right-hand corkscrew law). It has a zero parameter at From d14d08347542ce1118e308449ed7c481151a3995 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:54:54 -0500 Subject: [PATCH 45/76] Update src/ansys/geometry/core/geometry/surfaces/torus.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/torus.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/torus.py b/src/ansys/geometry/core/geometry/surfaces/torus.py index d941b91621..64ba9cfd00 100644 --- a/src/ansys/geometry/core/geometry/surfaces/torus.py +++ b/src/ansys/geometry/core/geometry/surfaces/torus.py @@ -207,7 +207,7 @@ def parameterization(self) -> tuple[Parameterization, Parameterization]: the axis (right-hand corkscrew law). It has a zero parameter at ``Geometry.Frame.DirX`` and a period of ``2*pi``. - The V parameter specifies the latitude, increasing North, with a zero parameter + The V parameter specifies the latitude, increasing north, with a zero parameter at the equator. For the donut, where the major radius is greater than the minor radius, the range is [-pi, pi] and the parameterization is periodic. For a degenerate torus, the range is restricted From 458aa6a3036346f84b4064bb6bbd2c30e7c11efe Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:55:02 -0500 Subject: [PATCH 46/76] Update src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index 7374673168..8ac73b10bc 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -45,9 +45,9 @@ class TrimmedSurface: Parameters ---------- face : Face - Face that the TrimmedSurface belongs to. + Face that the trimmed surface belongs to. geometry : Surface - The underlying mathematical representation of the surface. + Underlying mathematical representation of the surface. """ def __init__(self, face: "Face", geometry: Surface): From 309fbecd83b7bd3ed2138748eb241598878df240 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:55:09 -0500 Subject: [PATCH 47/76] Update src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index 8ac73b10bc..3d04a89835 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -51,7 +51,7 @@ class TrimmedSurface: """ def __init__(self, face: "Face", geometry: Surface): - """Initialize ``TrimmedSurface`` class.""" + """Initialize an instance of a trimmed surface.""" self._face = face self._geometry = geometry From f764f57b9535de9571b6c0183af79e5d5eba1ead Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:55:22 -0500 Subject: [PATCH 48/76] Update src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- .../geometry/core/geometry/surfaces/trimmed_surface.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index 3d04a89835..d88bb3ccdf 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -57,17 +57,17 @@ def __init__(self, face: "Face", geometry: Surface): @property def face(self) -> "Face": - """The face this TrimmedSurface belongs to.""" + """Face the trimmed surface belongs to.""" return self._face @property def geometry(self) -> Surface: - """The underlying mathematical surface.""" + """Underlying mathematical surface.""" return self._geometry @property def box_uv(self) -> BoxUV: - """The bounding BoxUV of the surface.""" + """Bounding BoxUV of the surface.""" self._face._grpc_client.log.debug("Requesting box UV from server.") box = self._face._faces_stub.GetBoxUV(self.face._grpc_id) return BoxUV(Interval(box.start_u, box.end_u), Interval(box.start_v, box.end_v)) From 6c6bae2a64173c46eac13f8b7b6651cecd78ea5f Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:55:34 -0500 Subject: [PATCH 49/76] Update src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- .../geometry/core/geometry/surfaces/trimmed_surface.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index d88bb3ccdf..befe90f470 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -159,17 +159,17 @@ def evaluate_proportion(self, u: Real, v: Real) -> SurfaceEvaluation: class ReversedTrimmedSurface(TrimmedSurface): """ - Represents a reversed TrimmedSurface. + Represents a reversed trimmed surface. - When a surface is reversed, its normal vector is negated in order to provide the proper + When a surface is reversed, its normal vector is negated to provide the proper outward facing vector. Parameters ---------- face : Face - Face that the TrimmedSurface belongs to. + Face that the trimmed surface belongs to. geometry : Surface - The underlying mathematical representation of the surface. + Underlying mathematical representation of the surface. """ def __init__(self, face: "Face", geometry: Surface): From a1b0220c0961f0977326e18836b5c7c466cf0606 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:55:44 -0500 Subject: [PATCH 50/76] Update src/ansys/geometry/core/misc/accuracy.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/misc/accuracy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/misc/accuracy.py b/src/ansys/geometry/core/misc/accuracy.py index a0cfe0ba70..995daa3b0b 100644 --- a/src/ansys/geometry/core/misc/accuracy.py +++ b/src/ansys/geometry/core/misc/accuracy.py @@ -41,7 +41,7 @@ class Accuracy: @property def length_accuracy() -> Real: - """Return the LENGTH_ACCURACY constant.""" + """Return the ``LENGTH_ACCURACY`` constant.""" return LENGTH_ACCURACY def length_is_equal(comparison_length: Real, reference_length: Real) -> bool: From 61c481502bacddef7402b14a86b96922b9087af0 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:56:51 -0500 Subject: [PATCH 51/76] Update src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index befe90f470..16e2fce921 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -173,7 +173,7 @@ class ReversedTrimmedSurface(TrimmedSurface): """ def __init__(self, face: "Face", geometry: Surface): - """Initialize ``ReversedTrimmedSurface`` class.""" + """Initialize an instance of a reversed trimmed surface.""" super().__init__(face, geometry) def normal(self, u: Real, v: Real) -> UnitVector3D: # noqa: D102 From afb1d42d566f9a8ce2a3a43e499a2cd663b8fc2d Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:58:24 -0500 Subject: [PATCH 52/76] Update src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index 16e2fce921..033434896b 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -143,7 +143,7 @@ def evaluate_proportion(self, u: Real, v: Real) -> SurfaceEvaluation: Returns ------- SurfaceEvaluation - The resulting surface evaluation. + Resulting surface evaluation. """ boundsU = self.box_uv.interval_u boundsV = self.box_uv.interval_v From db4bd9949ed45a39946af4098a9eb68c99dd1dcd Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:59:10 -0500 Subject: [PATCH 53/76] Update src/ansys/geometry/core/connection/conversions.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/connection/conversions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/connection/conversions.py b/src/ansys/geometry/core/connection/conversions.py index 18d393c8d7..3f3ba2b57e 100644 --- a/src/ansys/geometry/core/connection/conversions.py +++ b/src/ansys/geometry/core/connection/conversions.py @@ -535,7 +535,7 @@ def curve_to_grpc_curve(curve: Curve) -> GRPCCurve: Parameters ---------- curve : Curve - The curve to convert. + Curve to convert. Returns ------- From 62dd820b78b703acc746017b1963aada7338d6d6 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:59:46 -0500 Subject: [PATCH 54/76] Update src/ansys/geometry/core/connection/conversions.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/connection/conversions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/connection/conversions.py b/src/ansys/geometry/core/connection/conversions.py index 3f3ba2b57e..07f9d80a52 100644 --- a/src/ansys/geometry/core/connection/conversions.py +++ b/src/ansys/geometry/core/connection/conversions.py @@ -575,7 +575,7 @@ def trimmed_curve_to_grpc_trimmed_curve(curve: "TrimmedCurve") -> GRPCTrimmedCur Parameters ---------- curve : TrimmedCurve - The curve to convert. + Curve to convert. Returns ------- From f68cc3b1b477391d0d8d73f26c159d176a440645 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Mon, 26 Feb 2024 00:17:38 -0500 Subject: [PATCH 55/76] Apply suggestions from code review batching the suggestions and handling the others manually Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/designer/edge.py | 6 +-- src/ansys/geometry/core/designer/face.py | 18 +++---- src/ansys/geometry/core/geometry/box_uv.py | 14 ++--- .../geometry/core/geometry/curves/curve.py | 10 ++-- .../geometry/core/geometry/curves/line.py | 2 +- .../core/geometry/curves/trimmed_curve.py | 54 +++++++++---------- .../core/geometry/parameterization.py | 50 ++++++++--------- 7 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 870c8fdd9a..97efb10f7b 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -79,7 +79,7 @@ def __init__( grpc_client: GrpcClient, is_reversed: bool = False, ): - """Initialize ``Edge`` class.""" + """Initialize the ``Edge`` class.""" self._id = id self._curve_type = curve_type self._body = body @@ -100,7 +100,7 @@ def _grpc_id(self) -> EntityIdentifier: @property def is_reversed(self) -> bool: - """Edge is reversed.""" + """Flag indicating if the edge is reversed.""" return self._is_reversed @property @@ -108,7 +108,7 @@ def shape(self) -> TrimmedCurve: """ Underlying trimmed curve of the edge. - If the edge is reversed, its shape will be a `ReversedTrimmedCurve`, which swaps the + If the edge is reversed, its shape is the ``ReversedTrimmedCurve`` type, which swaps the start and end points of the curve and handles parameters to allow evaluation as if the curve is not reversed. """ diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index 1913bb0e87..b1fc40131e 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -160,7 +160,7 @@ def __init__( grpc_client: GrpcClient, is_reversed: bool = False, ): - """Initialize ``Face`` class.""" + """Initialize the ``Face`` class.""" self._id = id self._surface_type = surface_type self._body = body @@ -184,7 +184,7 @@ def _grpc_id(self) -> EntityIdentifier: @property def is_reversed(self) -> bool: - """Face is reversed.""" + """Flag indicating if the face is reversed.""" return self._is_reversed @property @@ -197,7 +197,7 @@ def shape(self) -> TrimmedSurface: """ Underlying trimmed surface of the face. - If the face is reversed, its shape will be a `ReversedTrimmedSurface`, which handles the + If the face is reversed, its shape is a ``ReversedTrimmedSurface`` type, which handles the direction of the normal vector to ensure it is always facing outward. """ if self._shape is None: @@ -362,21 +362,21 @@ def create_isoparametric_curves( """ Create isoparametic curves at the given proportional parameter. - Typically, only one curve will be created, but if the face has a hole, it is possible to - create more than one curve. + Typically, only one curve is created, but if the face has a hole, it is possible that + more than one curve is created. Parameters ---------- use_u_param : bool - Define whether the parameter is the u coordinate or v coordinate. If True, - then u parameter is used. If False, then v parameter is used. + Whether the parameter is the ``u`` coordinate or ``v`` coordinate. If ``True``, + it is the ``u`` coordinate. If ``False``, it is the ``v`` coordinate. parameter : float - The proportional [0-1] parameter to create the curvse at. + Proportional [0-1] parameter to create the one or more curves at. Returns ------- List[TrimmedCurve] - The list of curves that were created. + List of curves that were created. """ curves = self._faces_stub.CreateIsoParamCurves( CreateIsoParamCurvesRequest(id=self.id, u_dir_curve=use_u_param, proportion=parameter) diff --git a/src/ansys/geometry/core/geometry/box_uv.py b/src/ansys/geometry/core/geometry/box_uv.py index 4454ecb446..3240e25213 100644 --- a/src/ansys/geometry/core/geometry/box_uv.py +++ b/src/ansys/geometry/core/geometry/box_uv.py @@ -27,7 +27,7 @@ class LocationUV(Enum): - """Provides the ``LocationUV`` class to indicate locations for BoxUV.""" + """Provides the enumeration for indicating locations for BoxUV.""" TopLeft = 1 TopCenter = 2 @@ -65,12 +65,12 @@ def from_two_params(cls, param1: ParamUV, param2: ParamUV): @property def interval_u(self) -> Interval: - """Return the u interval.""" + """``u`` interval.""" return self._interval_u @property def interval_v(self) -> Interval: - """Return the v interval.""" + """``v`` interval.""" return self._interval_v def __eq__(self, other: object) -> bool: @@ -90,7 +90,7 @@ def __ne__(self, other: object) -> bool: ) def is_empty(self): - """Return whether this BoxUV is empty.""" + """Check if this BoxUV is empty.""" return self.interval_u.is_empty() or self.interval_v.is_empty() def proportion(self, prop_u: Real, prop_v: Real) -> ParamUV: @@ -111,7 +111,7 @@ def is_negative(self, tolerance_u: Real, tolerance_v: Real) -> bool: @staticmethod def unite(first: "BoxUV", second: "BoxUV") -> "BoxUV": - """Return the union of two BoxUV instances.""" + """Unite of two BoxUV instances.""" if first.is_empty(): return second if second.is_empty(): @@ -123,7 +123,7 @@ def unite(first: "BoxUV", second: "BoxUV") -> "BoxUV": @staticmethod def intersect(first: "BoxUV", second: "BoxUV", tolerance_u: Real, tolerance_v: Real) -> "BoxUV": - """Return the intersection of two BoxUV instances.""" + """Get the intersection of two BoxUV instances.""" if first.is_empty() or second.is_empty(): return None # supposed to be empty intersection = BoxUV( @@ -149,7 +149,7 @@ def inflate(self, delta_u: Real, delta_v: Real) -> "BoxUV": return BoxUV(self.interval_u.inflate(delta_u), self.interval_v.inflate(delta_v)) def get_corner(self, location: LocationUV) -> ParamUV: - """Return the corner location of the BoxUV.""" + """Get the corner location of the BoxUV.""" u = 0 v = 0 if ( diff --git a/src/ansys/geometry/core/geometry/curves/curve.py b/src/ansys/geometry/core/geometry/curves/curve.py index b341efaa93..51473f594d 100644 --- a/src/ansys/geometry/core/geometry/curves/curve.py +++ b/src/ansys/geometry/core/geometry/curves/curve.py @@ -30,14 +30,12 @@ class Curve(ABC): """ - Curve abstract base class. - - Represents a 3D curve. + Provides the abstract base class representing a 3D curve. """ @abstractmethod def parameterization(self) -> Parameterization: - """Parameterization of the curve.""" + """Parameterize the curve.""" return @abstractmethod @@ -50,7 +48,7 @@ def contains_point(self, point: Point3D) -> bool: """ Test whether the point is contained by the curve. - The point can either lie within it, or on its boundary. + The point can either lie within the curve or on its boundary. """ return @@ -74,7 +72,7 @@ def project_point(self, point: Point3D) -> CurveEvaluation: """ Project a point to the curve. - This returns the evaluation at the closest point. + This method returns the evaluation at the closest point. """ return diff --git a/src/ansys/geometry/core/geometry/curves/line.py b/src/ansys/geometry/core/geometry/curves/line.py index b2c14edbfb..176e93696a 100644 --- a/src/ansys/geometry/core/geometry/curves/line.py +++ b/src/ansys/geometry/core/geometry/curves/line.py @@ -200,7 +200,7 @@ def contains_point(self, point: Point3D) -> bool: # noqa: D102 class LineEvaluation(CurveEvaluation): - """Evaluate a line.""" + """Provides for evaluating a line.""" def __init__(self, line: Line, parameter: float = None) -> None: """Initialize the ``LineEvaluation`` class.""" diff --git a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py index 779a90d130..df59120828 100644 --- a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py +++ b/src/ansys/geometry/core/geometry/curves/trimmed_curve.py @@ -39,22 +39,22 @@ class TrimmedCurve: """ Represents a trimmed curve. - A trimmed curve is a curve that has a boundary. This boundary comes in the form of an Interval. + A trimmed curve is a curve that has a boundary. This boundary comes in the form of an interval. Parameters ---------- geometry : Curve - The underlying mathematical representation of the curve. + Underlying mathematical representation of the curve. start : Point3D - The start point of the curve. + Start point of the curve. end : Point3D - The end point of the curve. + End point of the curve. interval : Interval - The parametric interval that bounds the curve. + Parametric interval that bounds the curve. length : Quantity - The length of the curve. + Length of the curve. grpc_client : GrpcClient, default: None - Optional gRPC client that is required for advanced functions such as `intersect_curve()`. + gRPC client that is required for advanced functions such as ``intersect_curve()``. """ def __init__( @@ -78,17 +78,17 @@ def __init__( @property def geometry(self) -> Curve: - """The underlying mathematical curve.""" + """Underlying mathematical curve.""" return self._geometry @property def start(self) -> Point3D: - """The start point of the curve.""" + """Start point of the curve.""" return self._start @property def end(self) -> Point3D: - """The end point of the curve.""" + """End point of the curve.""" return self._end @property @@ -107,8 +107,8 @@ def evaluate_proportion(self, param: Real) -> CurveEvaluation: """ Evaluate the curve at a proportional value. - A parameter of 0 would correspond to the start of the curve, while a parameter of 1 would - correspond to the end of the curve. + A parameter of ``0`` corresponds to the start of the curve, while a parameter of ``1`` + corresponds to the end of the curve. Parameters ---------- @@ -118,7 +118,7 @@ def evaluate_proportion(self, param: Real) -> CurveEvaluation: Returns ------- CurveEvaluation - The resulting curve evaluation. + Resulting curve evaluation. """ bounds = self.interval return self.geometry.evaluate(bounds.start + bounds.get_span() * param) @@ -127,12 +127,12 @@ def intersect_curve(self, other: "TrimmedCurve") -> List[Point3D]: """ Intersect this trimmed curve with another to receive the points of intersection. - If the curves do not intersect, an empty list is returned. + If the two trimmed curves do not intersect, an empty list is returned. Parameters ---------- other : TrimmedCurve - The trimmed curve to intersect with. + Trimmed curve to intersect with. Returns ------- @@ -141,8 +141,8 @@ def intersect_curve(self, other: "TrimmedCurve") -> List[Point3D]: """ if self._grpc_client is None: raise ValueError( - """This TrimmedCurve was not initialized with a grpc client, - so this method cannot be called.""" + """Because this trimmed curve was not initialized with a gRPC client, + the method cannot be called.""" ) first = trimmed_curve_to_grpc_trimmed_curve(self) second = trimmed_curve_to_grpc_trimmed_curve(other) @@ -163,28 +163,28 @@ def __repr__(self) -> str: class ReversedTrimmedCurve(TrimmedCurve): """ - Represents a reversed TrimmedCurve. + Represents a reversed trimmed curve. When a curve is reversed, its start and end points are swapped, and parameters for evaluations are handled to provide expected results conforming to the direction of the curve. For example, - evaluating a TrimmedCurve proportionally at 0 would evaluate at the start point of the curve, - but evaluating a ReversedTrimmedCurve proportionally at 0 will evaluate at what was previously + evaluating a trimmed curve proportionally at 0 evaluates at the start point of the curve, + but evaluating a reversed trimmed curve proportionally at 0 evaluates at what was previously the end point of the curve but is now the start point. Parameters ---------- geometry : Curve - The underlying mathematical representation of the curve. + Underlying mathematical representation of the curve. start : Point3D - The original start point of the curve. + Original start point of the curve. end : Point3D - The original end point of the curve. + Original end point of the curve. interval : Interval - The parametric interval that bounds the curve. + Parametric interval that bounds the curve. length : Quantity - The length of the curve. + Length of the curve. grpc_client : GrpcClient, default: None - Optional gRPC client that is required for advanced functions such as `intersect_curve()`. + gRPC client that is required for advanced functions such as `intersect_curve()`. """ def __init__( @@ -196,7 +196,7 @@ def __init__( length: Quantity, grpc_client: GrpcClient = None, ): - """Initialize ``ReversedTrimmedCurve`` class.""" + """Initialize an instance of a reversed trimmed curve.""" super().__init__(geometry, start, end, interval, length, grpc_client) # Swap start and end points diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py index 8cb55bbb64..a06f42ffad 100644 --- a/src/ansys/geometry/core/geometry/parameterization.py +++ b/src/ansys/geometry/core/geometry/parameterization.py @@ -132,7 +132,7 @@ def __truediv__(self, other: "ParamUV") -> "ParamUV": return ParamUV(self._u / other._u, self._v / other._v) def __iter__(self): - """Iterate a `ParamUV`.""" + """Iterate a ``ParamUV``.""" return iter((self.u, self.v)) def __repr__(self) -> str: @@ -208,18 +208,20 @@ def is_closed(self) -> bool: def is_empty(self) -> bool: """ - If the current interval is empty return true, else return false. + Check if the current interval is empty. Returns ------- bool - The value that indicates whether the interval is empty or not. + ``True`` when the interval is empty, ``False`` otherwise. """ return not self.not_empty def get_span(self) -> Real: """ - Return the quantity contained by the interval. Interval must be closed. + Get the quantity contained by the interval. + + The Interval must be closed. Returns ------- @@ -233,52 +235,52 @@ def get_span(self) -> Real: def get_relative_val(self, t: Real) -> Real: """ - Return an evaluation property of the interval, used in BoxUV. + Get an evaluation property of the interval, used in BoxUV. Parameters ---------- t : Real - The offset that the interval gets evaluated at. + Offset to evaluate the interval at. Returns ------- Real - The actual value according to the offset + Actual value according to the offset. """ return self.start + t * self.get_span() def is_negative(self, tolerance: Real) -> bool: """ - Boolean value that indicates whether the current interval is negative. + Whether the current interval is negative. Parameters ---------- tolerance : Real - The accepted range since we could be working with doubles + Accepted range because the data type of the interval could be in doubles. Returns ------- bool - True if negative False otherwise + ``True`` if the interval is negative, ``False`` otherwise. """ return Accuracy.compare_with_tolerance(self.get_span(), 0, tolerance, tolerance) @staticmethod def unite(first: "Interval", second: "Interval") -> "Interval": """ - Return the union of two intervals. + Unite two intervals. Parameters ---------- first : Interval - First interval + First interval. second : Interval - Second interval + Second interval. Returns ------- Interval - The union of the two intervals + Union of the two intervals. """ if first.is_empty(): return second @@ -289,19 +291,19 @@ def unite(first: "Interval", second: "Interval") -> "Interval": @staticmethod def intersect(first: "Interval", second: "Interval", tolerance: Real) -> "Interval": """ - Return the intersection of two intervals. + Get the intersection of two intervals. Parameters ---------- first : Interval - First interval + First interval. second : Interval - Second interval + Second interval. Returns - ------- + -------- Interval - The intersection of the two intervals + Intersection of the two intervals. """ if first.is_empty() or second.is_empty(): return None # supposed to be empty @@ -312,19 +314,19 @@ def intersect(first: "Interval", second: "Interval", tolerance: Real) -> "Interv def contains_value(self, t: Real, accuracy: Real) -> bool: """ - Check if the current interval contains value t given the accuracy range. + Check if the current interval contains the value ``t`` given the accuracy range. Parameters ---------- t : Real - The value of interest + Value of interest accuracy: Real - The accepted range of error since we could be working with floats + Accepted range of error given that the interval could be in float values. Returns ------- bool - True if the interval contains the value, false otherwise + ``True`` if the interval contains the value, ``False`` otherwise. """ if self.is_empty(): return False @@ -366,7 +368,7 @@ def inflate(self, delta: Real) -> "Interval": return Interval(self.start - delta, self.end + delta) def __repr__(self) -> str: - """Represent the ``Interval`` as a string.""" + """Represent the interval as a string.""" return f"Interval(start={self.start}, end={self.end})" From 63f8973fd6576577cc7cdf6fcf2a54747a5aa7b8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 05:17:54 +0000 Subject: [PATCH 56/76] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/ansys/geometry/core/geometry/curves/curve.py | 4 +--- src/ansys/geometry/core/geometry/parameterization.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ansys/geometry/core/geometry/curves/curve.py b/src/ansys/geometry/core/geometry/curves/curve.py index 51473f594d..b6c0a79d9d 100644 --- a/src/ansys/geometry/core/geometry/curves/curve.py +++ b/src/ansys/geometry/core/geometry/curves/curve.py @@ -29,9 +29,7 @@ class Curve(ABC): - """ - Provides the abstract base class representing a 3D curve. - """ + """Provides the abstract base class representing a 3D curve.""" @abstractmethod def parameterization(self) -> Parameterization: diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py index a06f42ffad..1d956e3d70 100644 --- a/src/ansys/geometry/core/geometry/parameterization.py +++ b/src/ansys/geometry/core/geometry/parameterization.py @@ -220,7 +220,7 @@ def is_empty(self) -> bool: def get_span(self) -> Real: """ Get the quantity contained by the interval. - + The Interval must be closed. Returns From 98dd20cbf8efa1c9a23e77037b4070045aad73d5 Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Thu, 29 Feb 2024 12:45:15 -0500 Subject: [PATCH 57/76] Addressed the comments that required manually changing the files --- src/ansys/geometry/core/connection/conversions.py | 2 +- src/ansys/geometry/core/geometry/box_uv.py | 8 ++++---- src/ansys/geometry/core/geometry/parameterization.py | 7 +++---- src/ansys/geometry/core/geometry/surfaces/plane.py | 4 ++-- src/ansys/geometry/core/geometry/surfaces/surface.py | 2 +- .../geometry/core/geometry/surfaces/trimmed_surface.py | 2 +- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/ansys/geometry/core/connection/conversions.py b/src/ansys/geometry/core/connection/conversions.py index 07f9d80a52..8057261161 100644 --- a/src/ansys/geometry/core/connection/conversions.py +++ b/src/ansys/geometry/core/connection/conversions.py @@ -540,7 +540,7 @@ def curve_to_grpc_curve(curve: Curve) -> GRPCCurve: Returns ------- GRPCCurve - Geometry service gRPC CurveGeometry message. + Return the ``Curve`` as a ``ansys.api.geometry.CurveGeometry`` message. """ grpc_curve = None origin = point3d_to_grpc_point(curve.origin) diff --git a/src/ansys/geometry/core/geometry/box_uv.py b/src/ansys/geometry/core/geometry/box_uv.py index 3240e25213..baaad99ac9 100644 --- a/src/ansys/geometry/core/geometry/box_uv.py +++ b/src/ansys/geometry/core/geometry/box_uv.py @@ -41,7 +41,7 @@ class LocationUV(Enum): class BoxUV: - """BoxUV class.""" + """Provides the implementation for ``BoxUV`` class.""" def __init__(self, range_u: Interval = None, range_v: Interval = None) -> None: """Root constructor for BoxUV.""" @@ -52,12 +52,12 @@ def __init__(self, range_u: Interval = None, range_v: Interval = None) -> None: @classmethod def from_param(cls, param: ParamUV): - """Secondary constructor for BoxUV using a ParamUV object type.""" + """Secondary Constructor for ``BoxUV`` using a ``ParamUV`` object type.""" return cls(Interval(param.u, param.u), Interval(param.v, param.v)) @classmethod def from_two_params(cls, param1: ParamUV, param2: ParamUV): - """Secondary constructor for BoxUV using two ParamUV object types.""" + """Secondary Constructor for ``BoxUV`` using two ``ParamUV`` object types.""" return cls( Interval(min(param1.u, param2.u), max(param1.u, param2.u)), Interval(min(param1.v, param2.v), max(param1.v, param2.v)), @@ -100,7 +100,7 @@ def proportion(self, prop_u: Real, prop_v: Real) -> ParamUV: ) def get_center(self) -> ParamUV: - """Evaluate the BoxUV in the middle.""" + """Evaluate the this ``BoxUV`` in the center.""" return self.proportion(0.5, 0.5) def is_negative(self, tolerance_u: Real, tolerance_v: Real) -> bool: diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/geometry/parameterization.py index 1d956e3d70..b7549da0ac 100644 --- a/src/ansys/geometry/core/geometry/parameterization.py +++ b/src/ansys/geometry/core/geometry/parameterization.py @@ -251,7 +251,7 @@ def get_relative_val(self, t: Real) -> Real: def is_negative(self, tolerance: Real) -> bool: """ - Whether the current interval is negative. + Boolean value that indicates whether the current interval is negative. Parameters ---------- @@ -268,7 +268,7 @@ def is_negative(self, tolerance: Real) -> bool: @staticmethod def unite(first: "Interval", second: "Interval") -> "Interval": """ - Unite two intervals. + Get the union of two intervals. Parameters ---------- @@ -345,8 +345,7 @@ def contains_value(self, t: Real, accuracy: Real) -> bool: def contains(self, t: Real) -> bool: """ - Check if the interval contains value ``t`` using the default ``length_accuracy`` - constant. + Check if interval contains value ``t`` using default ``length_accuracy``. Parameters ---------- diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index ce47b12ba9..19d824eac3 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -53,7 +53,7 @@ class PlaneSurface(Surface): Parameters ---------- origin : Union[~numpy.ndarray, RealSequence, Point3D], - Centered origin of the torus. + Centered origin of the plane. reference : Union[~numpy.ndarray, RealSequence, UnitVector3D, Vector3D] X-axis direction. axis : Union[~numpy.ndarray, RealSequence, UnitVector3D, Vector3D] @@ -106,7 +106,7 @@ def __eq__(self, other: "PlaneSurface") -> bool: ) def contains_param(self, param_uv: ParamUV) -> bool: - """Check whether the plane contains a u and v pair point.""" + """Test whether a ``ParamUV`` is within the parametric range of the surface.""" raise NotImplementedError("contains_param() is not implemented.") def contains_point(self, point: Point3D) -> bool: diff --git a/src/ansys/geometry/core/geometry/surfaces/surface.py b/src/ansys/geometry/core/geometry/surfaces/surface.py index 1028b39fdd..cbaba2ee4c 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface.py @@ -28,7 +28,7 @@ class Surface(ABC): - """Surface abstract base class.""" + """Provides the abstract base class for a 3D surface.""" @abstractmethod def parameterization(self) -> tuple[Parameterization, Parameterization]: diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py index 033434896b..53803bc500 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py @@ -131,7 +131,7 @@ def project_point(self, point: Point3D) -> SurfaceEvaluation: def evaluate_proportion(self, u: Real, v: Real) -> SurfaceEvaluation: """ - Evaluate the surface at proportional u and v values. + Evaluate the surface at proportional u and v parameters. Parameters ---------- From 28fcae040445cc085871d66182c8e1537e399064 Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Thu, 29 Feb 2024 12:49:54 -0500 Subject: [PATCH 58/76] cleaned up BoxUV --- src/ansys/geometry/core/geometry/box_uv.py | 38 ---------------------- 1 file changed, 38 deletions(-) diff --git a/src/ansys/geometry/core/geometry/box_uv.py b/src/ansys/geometry/core/geometry/box_uv.py index baaad99ac9..4ba87e1786 100644 --- a/src/ansys/geometry/core/geometry/box_uv.py +++ b/src/ansys/geometry/core/geometry/box_uv.py @@ -50,19 +50,6 @@ def __init__(self, range_u: Interval = None, range_v: Interval = None) -> None: if range_v is not None: self._interval_v = range_v - @classmethod - def from_param(cls, param: ParamUV): - """Secondary Constructor for ``BoxUV`` using a ``ParamUV`` object type.""" - return cls(Interval(param.u, param.u), Interval(param.v, param.v)) - - @classmethod - def from_two_params(cls, param1: ParamUV, param2: ParamUV): - """Secondary Constructor for ``BoxUV`` using two ``ParamUV`` object types.""" - return cls( - Interval(min(param1.u, param2.u), max(param1.u, param2.u)), - Interval(min(param1.v, param2.v), max(param1.v, param2.v)), - ) - @property def interval_u(self) -> Interval: """``u`` interval.""" @@ -109,31 +96,6 @@ def is_negative(self, tolerance_u: Real, tolerance_v: Real) -> bool: return False return self.interval_u.is_negative(tolerance_u) or self.interval_v.is_negative(tolerance_v) - @staticmethod - def unite(first: "BoxUV", second: "BoxUV") -> "BoxUV": - """Unite of two BoxUV instances.""" - if first.is_empty(): - return second - if second.is_empty(): - return first - return BoxUV( - Interval.unite(first.interval_u, second.interval_u), - Interval.unite(first.interval_v, second.interval_v), - ) - - @staticmethod - def intersect(first: "BoxUV", second: "BoxUV", tolerance_u: Real, tolerance_v: Real) -> "BoxUV": - """Get the intersection of two BoxUV instances.""" - if first.is_empty() or second.is_empty(): - return None # supposed to be empty - intersection = BoxUV( - Interval.intersect(first.interval_u, second.interval_u, tolerance_u), - Interval.intersect(first.interval_v, second.interval_v, tolerance_v), - ) - if not intersection.is_negative(tolerance_u, tolerance_v): - return intersection - return None # supposed to be empty - def contains(self, param: ParamUV) -> bool: """Check whether the BoxUV contains a given u and v pair parameter.""" if self.is_empty(): From 343434e6ca9a7e031a56a8e6a8a55346607623fa Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Sun, 3 Mar 2024 01:41:25 -0500 Subject: [PATCH 59/76] Apply suggestions from code review Co-authored-by: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> --- src/ansys/geometry/core/geometry/__init__.py | 2 +- src/ansys/geometry/core/misc/accuracy.py | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ansys/geometry/core/geometry/__init__.py b/src/ansys/geometry/core/geometry/__init__.py index 91d891c5c4..e7eaebdda1 100644 --- a/src/ansys/geometry/core/geometry/__init__.py +++ b/src/ansys/geometry/core/geometry/__init__.py @@ -19,7 +19,7 @@ # 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 the PyGeometry ``geometry`` subpackage.""" +"""Provides the PyAnsys Geometry ``geometry`` subpackage.""" from ansys.geometry.core.geometry.curves.circle import Circle, CircleEvaluation from ansys.geometry.core.geometry.curves.curve import Curve diff --git a/src/ansys/geometry/core/misc/accuracy.py b/src/ansys/geometry/core/misc/accuracy.py index 995daa3b0b..d89dd1fe25 100644 --- a/src/ansys/geometry/core/misc/accuracy.py +++ b/src/ansys/geometry/core/misc/accuracy.py @@ -72,10 +72,8 @@ def compare_with_tolerance( """Compare two doubles given the relative and absolute tolerances.""" if Accuracy.is_within_tolerance(a, b, relative_tolerance, absolute_tolerance): return 0 - if a < b: + elif a < b: return -1 - elif a == b: - return 0 else: return 1 From d0c3eddd9bdf17a3e2db63d7c37f231beb6b1b75 Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Sun, 3 Mar 2024 02:27:20 -0500 Subject: [PATCH 60/76] implemented Rob's recommended changes --- .../geometry/core/connection/conversions.py | 40 +++++++++---------- src/ansys/geometry/core/designer/edge.py | 2 + src/ansys/geometry/core/designer/face.py | 2 +- src/ansys/geometry/core/geometry/__init__.py | 2 +- .../geometry/core/geometry/curves/__init__.py | 2 +- .../core/geometry/surfaces/__init__.py | 2 +- .../geometry/core/geometry/surfaces/cone.py | 6 +-- .../core/geometry/surfaces/cylinder.py | 6 +-- .../geometry/core/geometry/surfaces/plane.py | 4 +- .../geometry/core/geometry/surfaces/sphere.py | 6 +-- .../core/geometry/surfaces/surface.py | 4 +- .../geometry/core/geometry/surfaces/torus.py | 6 +-- src/ansys/geometry/core/sketch/circle.py | 2 +- tests/integration/test_trimmed_geometry.py | 19 ++++++++- 14 files changed, 60 insertions(+), 43 deletions(-) diff --git a/src/ansys/geometry/core/connection/conversions.py b/src/ansys/geometry/core/connection/conversions.py index 8057261161..751be70146 100644 --- a/src/ansys/geometry/core/connection/conversions.py +++ b/src/ansys/geometry/core/connection/conversions.py @@ -38,29 +38,25 @@ from ansys.api.geometry.v0.models_pb2 import TrimmedCurve as GRPCTrimmedCurve from beartype.typing import TYPE_CHECKING, List, Optional, Tuple -from ansys.geometry.core.geometry import ( - Circle, - Cone, - Curve, - Cylinder, - Ellipse, - Line, - PlaneSurface, - Sphere, - Surface, - Torus, -) +from ansys.geometry.core.geometry.curves.circle import Circle +from ansys.geometry.core.geometry.curves.curve import Curve +from ansys.geometry.core.geometry.curves.ellipse import Ellipse +from ansys.geometry.core.geometry.curves.line import Line +from ansys.geometry.core.geometry.surfaces.cone import Cone +from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder +from ansys.geometry.core.geometry.surfaces.plane import PlaneSurface +from ansys.geometry.core.geometry.surfaces.sphere import Sphere +from ansys.geometry.core.geometry.surfaces.surface import Surface +from ansys.geometry.core.geometry.surfaces.torus import Torus from ansys.geometry.core.math import Frame, Matrix44, Plane, Point2D, Point3D, UnitVector3D from ansys.geometry.core.misc import DEFAULT_UNITS -from ansys.geometry.core.sketch import ( - Arc, - Polygon, - SketchCircle, - SketchEdge, - SketchEllipse, - SketchFace, - SketchSegment, -) +from ansys.geometry.core.sketch.arc import Arc +from ansys.geometry.core.sketch.circle import SketchCircle +from ansys.geometry.core.sketch.edge import SketchEdge +from ansys.geometry.core.sketch.ellipse import SketchEllipse +from ansys.geometry.core.sketch.face import SketchFace +from ansys.geometry.core.sketch.polygon import Polygon +from ansys.geometry.core.sketch.segment import SketchSegment if TYPE_CHECKING: # pragma: no cover from pyvista import PolyData @@ -540,7 +536,7 @@ def curve_to_grpc_curve(curve: Curve) -> GRPCCurve: Returns ------- GRPCCurve - Return the ``Curve`` as a ``ansys.api.geometry.CurveGeometry`` message. + Return ``Curve`` as a ``ansys.api.geometry.CurveGeometry`` message. """ grpc_curve = None origin = point3d_to_grpc_point(curve.origin) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 97efb10f7b..93473fe56f 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -69,6 +69,8 @@ class Edge: Parent body that the edge constructs. grpc_client : GrpcClient Active supporting Geometry service instance for design modeling. + is_reversed : bool + Direction of the edge. """ def __init__( diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index b1fc40131e..170ae01587 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -40,8 +40,8 @@ TrimmedSurface, ) from ansys.geometry.core.math import Point3D, UnitVector3D -from ansys.geometry.core.misc import DEFAULT_UNITS from ansys.geometry.core.misc.checks import ensure_design_is_active +from ansys.geometry.core.misc.measurements import DEFAULT_UNITS if TYPE_CHECKING: # pragma: no cover from ansys.geometry.core.designer.body import Body diff --git a/src/ansys/geometry/core/geometry/__init__.py b/src/ansys/geometry/core/geometry/__init__.py index 91d891c5c4..e7eaebdda1 100644 --- a/src/ansys/geometry/core/geometry/__init__.py +++ b/src/ansys/geometry/core/geometry/__init__.py @@ -19,7 +19,7 @@ # 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 the PyGeometry ``geometry`` subpackage.""" +"""Provides the PyAnsys Geometry ``geometry`` subpackage.""" from ansys.geometry.core.geometry.curves.circle import Circle, CircleEvaluation from ansys.geometry.core.geometry.curves.curve import Curve diff --git a/src/ansys/geometry/core/geometry/curves/__init__.py b/src/ansys/geometry/core/geometry/curves/__init__.py index 0913b0636f..b170b36c91 100644 --- a/src/ansys/geometry/core/geometry/curves/__init__.py +++ b/src/ansys/geometry/core/geometry/curves/__init__.py @@ -19,7 +19,7 @@ # 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 the PyGeometry ``curve`` subpackage.""" +"""Provides the PyAnsys Geometry ``curve`` subpackage.""" from ansys.geometry.core.geometry.curves.circle import Circle, CircleEvaluation from ansys.geometry.core.geometry.curves.curve import Curve from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation diff --git a/src/ansys/geometry/core/geometry/surfaces/__init__.py b/src/ansys/geometry/core/geometry/surfaces/__init__.py index 0e1c37030b..aeb872263b 100644 --- a/src/ansys/geometry/core/geometry/surfaces/__init__.py +++ b/src/ansys/geometry/core/geometry/surfaces/__init__.py @@ -19,7 +19,7 @@ # 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 the PyGeometry ``surface`` subpackage.""" +"""Provides the PyAnsys Geometry ``surface`` subpackage.""" from ansys.geometry.core.geometry.surfaces.cone import Cone, ConeEvaluation from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder, CylinderEvaluation from ansys.geometry.core.geometry.surfaces.plane import PlaneEvaluation, PlaneSurface diff --git a/src/ansys/geometry/core/geometry/surfaces/cone.py b/src/ansys/geometry/core/geometry/surfaces/cone.py index a04cfc0391..254d9b0dac 100644 --- a/src/ansys/geometry/core/geometry/surfaces/cone.py +++ b/src/ansys/geometry/core/geometry/surfaces/cone.py @@ -24,7 +24,7 @@ from functools import cached_property from beartype import beartype as check_input_types -from beartype.typing import Union +from beartype.typing import Tuple, Union import numpy as np from pint import Quantity @@ -240,7 +240,7 @@ def project_point(self, point: Point3D) -> "ConeEvaluation": return ConeEvaluation(self, ParamUV(u, v)) - def parameterization(self) -> tuple[Parameterization, Parameterization]: + def parameterization(self) -> Tuple[Parameterization, Parameterization]: """ Parameterize the cone surface as a tuple (U and V respectively). @@ -252,7 +252,7 @@ def parameterization(self) -> tuple[Parameterization, Parameterization]: Returns ------- - tuple[Parameterization, Parameterization] + Tuple[Parameterization, Parameterization] Information about how a cone's u and v parameters are parameterized, respectively. """ u = Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) diff --git a/src/ansys/geometry/core/geometry/surfaces/cylinder.py b/src/ansys/geometry/core/geometry/surfaces/cylinder.py index 48018dbb9c..459cc85e15 100644 --- a/src/ansys/geometry/core/geometry/surfaces/cylinder.py +++ b/src/ansys/geometry/core/geometry/surfaces/cylinder.py @@ -24,7 +24,7 @@ from functools import cached_property from beartype import beartype as check_input_types -from beartype.typing import Union +from beartype.typing import Tuple, Union import numpy as np from pint import Quantity @@ -251,7 +251,7 @@ def project_point(self, point: Point3D) -> "CylinderEvaluation": return CylinderEvaluation(self, ParamUV(u, v)) - def parameterization(self) -> tuple[Parameterization, Parameterization]: + def parameterization(self) -> Tuple[Parameterization, Parameterization]: """ Parameterize the cylinder surface as a tuple (U and V respectively). @@ -263,7 +263,7 @@ def parameterization(self) -> tuple[Parameterization, Parameterization]: Returns ------- - tuple[Parameterization, Parameterization] + Tuple[Parameterization, Parameterization] Information about how a cylinder's u and v parameters are parameterized, respectively. """ u = Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/geometry/surfaces/plane.py index 19d824eac3..6cd83ae0d1 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/geometry/surfaces/plane.py @@ -23,7 +23,7 @@ from functools import cached_property from beartype import beartype as check_input_types -from beartype.typing import Union +from beartype.typing import Tuple, Union import numpy as np from ansys.geometry.core.geometry.parameterization import ( @@ -113,7 +113,7 @@ def contains_point(self, point: Point3D) -> bool: """Check whether the plane contains a 3D point.""" raise NotImplementedError("contains_point() is not implemented.") - def parameterization(self) -> tuple[Parameterization, Parameterization]: + def parameterization(self) -> Tuple[Parameterization, Parameterization]: """Parametrize the plane.""" u = Parameterization(ParamForm.OPEN, ParamType.LINEAR, Interval(np.NINF, np.inf)) v = Parameterization(ParamForm.OPEN, ParamType.LINEAR, Interval(np.NINF, np.inf)) diff --git a/src/ansys/geometry/core/geometry/surfaces/sphere.py b/src/ansys/geometry/core/geometry/surfaces/sphere.py index 17a9264872..24c401c7bd 100644 --- a/src/ansys/geometry/core/geometry/surfaces/sphere.py +++ b/src/ansys/geometry/core/geometry/surfaces/sphere.py @@ -24,7 +24,7 @@ from functools import cached_property from beartype import beartype as check_input_types -from beartype.typing import Union +from beartype.typing import Tuple, Union import numpy as np from pint import Quantity @@ -208,7 +208,7 @@ def project_point(self, point: Point3D) -> "SphereEvaluation": v = np.arctan2(z, np.sqrt(x * x + y * y)) return SphereEvaluation(self, ParamUV(u, v)) - def parameterization(self) -> tuple[Parameterization, Parameterization]: + def parameterization(self) -> Tuple[Parameterization, Parameterization]: """ Parameterization of the sphere surface as a tuple (U and V respectively). @@ -221,7 +221,7 @@ def parameterization(self) -> tuple[Parameterization, Parameterization]: Returns ------- - tuple[Parameterization, Parameterization] + Tuple[Parameterization, Parameterization] Information about how a sphere's u and v parameters are parameterized, respectively. """ u = Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) diff --git a/src/ansys/geometry/core/geometry/surfaces/surface.py b/src/ansys/geometry/core/geometry/surfaces/surface.py index cbaba2ee4c..1ec681aec9 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface.py +++ b/src/ansys/geometry/core/geometry/surfaces/surface.py @@ -22,6 +22,8 @@ """Provides the ``Surface`` class.""" from abc import ABC, abstractmethod +from beartype.typing import Tuple + from ansys.geometry.core.geometry.parameterization import Parameterization, ParamUV from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import Matrix44, Point3D @@ -31,7 +33,7 @@ class Surface(ABC): """Provides the abstract base class for a 3D surface.""" @abstractmethod - def parameterization(self) -> tuple[Parameterization, Parameterization]: + def parameterization(self) -> Tuple[Parameterization, Parameterization]: """Parameterize the surface as a tuple (U and V respectively).""" return diff --git a/src/ansys/geometry/core/geometry/surfaces/torus.py b/src/ansys/geometry/core/geometry/surfaces/torus.py index 64ba9cfd00..9c2a860e95 100644 --- a/src/ansys/geometry/core/geometry/surfaces/torus.py +++ b/src/ansys/geometry/core/geometry/surfaces/torus.py @@ -25,7 +25,7 @@ from typing import Tuple from beartype import beartype as check_input_types -from beartype.typing import Union +from beartype.typing import Tuple, Union import numpy as np from pint import Quantity @@ -199,7 +199,7 @@ def evaluate(self, parameter: ParamUV) -> "TorusEvaluation": """ return TorusEvaluation(self, parameter) - def parameterization(self) -> tuple[Parameterization, Parameterization]: + def parameterization(self) -> Tuple[Parameterization, Parameterization]: """ Parameterize the torus surface as a tuple (U and V respectively). @@ -215,7 +215,7 @@ def parameterization(self) -> tuple[Parameterization, Parameterization]: Returns ------- - tuple[Parameterization, Parameterization] + Tuple[Parameterization, Parameterization] Information about how a torus's u and v parameters are parameterized, respectively. """ u = Parameterization(ParamForm.PERIODIC, ParamType.CIRCULAR, Interval(0, 2 * np.pi)) diff --git a/src/ansys/geometry/core/sketch/circle.py b/src/ansys/geometry/core/sketch/circle.py index f9038db2fe..85cc516a8d 100644 --- a/src/ansys/geometry/core/sketch/circle.py +++ b/src/ansys/geometry/core/sketch/circle.py @@ -26,7 +26,7 @@ from pint import Quantity import pyvista as pv -from ansys.geometry.core.geometry import Circle +from ansys.geometry.core.geometry.curves.circle import Circle from ansys.geometry.core.math import Plane, Point2D, Point3D from ansys.geometry.core.misc import DEFAULT_UNITS, Distance from ansys.geometry.core.sketch.face import SketchFace diff --git a/tests/integration/test_trimmed_geometry.py b/tests/integration/test_trimmed_geometry.py index ca55dda0d9..9ab6e2a597 100644 --- a/tests/integration/test_trimmed_geometry.py +++ b/tests/integration/test_trimmed_geometry.py @@ -19,7 +19,7 @@ # 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. - +"""Tests trimmed geometry.""" from ansys.api.geometry.v0.commands_pb2 import CreateSketchLineRequest import numpy as np import pytest @@ -40,6 +40,8 @@ from ansys.geometry.core.modeler import Modeler from ansys.geometry.core.sketch.sketch import Sketch +"""A Helper function to create a sktech line given two points and a ``Design``.""" + def create_sketch_line(design: Design, p1: Point3D, p2: Point3D): point1 = point3d_to_grpc_point(p1) @@ -47,6 +49,9 @@ def create_sketch_line(design: Design, p1: Point3D, p2: Point3D): design._commands_stub.CreateSketchLine(CreateSketchLineRequest(point1=point1, point2=point2)) +"""A Helper function that creates the Hedgehog model.""" + + def create_hedgehog(modeler: Modeler): design = modeler.create_design("Hedgehog") sketch = Sketch().arc_from_three_points( @@ -91,12 +96,18 @@ def create_hedgehog(modeler: Modeler): return design +"""A fixture of the hedgehog design to test the surface and curve properties individually.""" + + @pytest.fixture def hedgehog_design(modeler: Modeler): h = create_hedgehog(modeler) yield h +"""Tests the surface properties for hedgehog""" + + def test_trimmed_surface_properties(hedgehog_design): hedgehog_body = hedgehog_design.bodies[0] faces = hedgehog_body.faces @@ -149,6 +160,9 @@ def test_trimmed_surface_properties(hedgehog_design): assert faces[i].shape.box_uv.interval_v == Interval(start=interval_v[0], end=interval_v[1]) +"""Tests the normal vectors for hedgehog by using the ``BoxUV`` coordinates.""" + + def test_trimmed_surface_normals(hedgehog_design): hedgehog_body = hedgehog_design.bodies[0] faces = hedgehog_body.faces @@ -204,6 +218,9 @@ def test_trimmed_surface_normals(hedgehog_design): assert np.allclose(faces[i].shape.normal(corner_param.u, corner_param.v), bottom_right) +"""Tests the curve properties for hedgehog""" + + def test_trimmed_curve_properties(hedgehog_design): hedgehog_body = hedgehog_design.bodies[0] edges = hedgehog_body.edges From fa8c4b8a6a9ce459fde3eee97abd380b53664fea Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Sun, 3 Mar 2024 02:42:57 -0500 Subject: [PATCH 61/76] renamed geometry submodule to shapes to avoid conflicts --- .../geometry/core/connection/conversions.py | 22 ++++++++--------- src/ansys/geometry/core/designer/edge.py | 4 ++-- src/ansys/geometry/core/designer/face.py | 12 +++++----- .../core/{geometry => shapes}/__init__.py | 24 +++++++++---------- .../core/{geometry => shapes}/box_uv.py | 2 +- .../{geometry => shapes}/curves/__init__.py | 10 ++++---- .../{geometry => shapes}/curves/circle.py | 16 ++++++------- .../core/{geometry => shapes}/curves/curve.py | 4 ++-- .../curves/curve_evaluation.py | 0 .../{geometry => shapes}/curves/ellipse.py | 16 ++++++------- .../core/{geometry => shapes}/curves/line.py | 10 ++++---- .../curves/trimmed_curve.py | 6 ++--- .../{geometry => shapes}/parameterization.py | 0 .../{geometry => shapes}/surfaces/__init__.py | 14 +++++------ .../{geometry => shapes}/surfaces/cone.py | 20 ++++++++-------- .../{geometry => shapes}/surfaces/cylinder.py | 22 ++++++++--------- .../{geometry => shapes}/surfaces/plane.py | 18 +++++++------- .../{geometry => shapes}/surfaces/sphere.py | 18 +++++++------- .../{geometry => shapes}/surfaces/surface.py | 4 ++-- .../surfaces/surface_evaluation.py | 2 +- .../{geometry => shapes}/surfaces/torus.py | 18 +++++++------- .../surfaces/trimmed_surface.py | 8 +++---- src/ansys/geometry/core/sketch/circle.py | 2 +- src/ansys/geometry/core/sketch/ellipse.py | 2 +- src/ansys/geometry/core/sketch/segment.py | 2 +- tests/integration/test_design.py | 2 +- tests/integration/test_trimmed_geometry.py | 16 ++++++------- tests/test_parameterization.py | 2 +- tests/test_primitives.py | 11 +-------- 29 files changed, 139 insertions(+), 148 deletions(-) rename src/ansys/geometry/core/{geometry => shapes}/__init__.py (59%) rename src/ansys/geometry/core/{geometry => shapes}/box_uv.py (98%) rename src/ansys/geometry/core/{geometry => shapes}/curves/__init__.py (76%) rename src/ansys/geometry/core/{geometry => shapes}/curves/circle.py (98%) rename src/ansys/geometry/core/{geometry => shapes}/curves/curve.py (94%) rename src/ansys/geometry/core/{geometry => shapes}/curves/curve_evaluation.py (100%) rename src/ansys/geometry/core/{geometry => shapes}/curves/ellipse.py (98%) rename src/ansys/geometry/core/{geometry => shapes}/curves/line.py (97%) rename src/ansys/geometry/core/{geometry => shapes}/curves/trimmed_curve.py (97%) rename src/ansys/geometry/core/{geometry => shapes}/parameterization.py (100%) rename src/ansys/geometry/core/{geometry => shapes}/surfaces/__init__.py (68%) rename src/ansys/geometry/core/{geometry => shapes}/surfaces/cone.py (98%) rename src/ansys/geometry/core/{geometry => shapes}/surfaces/cylinder.py (97%) rename src/ansys/geometry/core/{geometry => shapes}/surfaces/plane.py (97%) rename src/ansys/geometry/core/{geometry => shapes}/surfaces/sphere.py (98%) rename src/ansys/geometry/core/{geometry => shapes}/surfaces/surface.py (94%) rename src/ansys/geometry/core/{geometry => shapes}/surfaces/surface_evaluation.py (98%) rename src/ansys/geometry/core/{geometry => shapes}/surfaces/torus.py (98%) rename src/ansys/geometry/core/{geometry => shapes}/surfaces/trimmed_surface.py (95%) diff --git a/src/ansys/geometry/core/connection/conversions.py b/src/ansys/geometry/core/connection/conversions.py index 751be70146..4ea8266a50 100644 --- a/src/ansys/geometry/core/connection/conversions.py +++ b/src/ansys/geometry/core/connection/conversions.py @@ -38,18 +38,18 @@ from ansys.api.geometry.v0.models_pb2 import TrimmedCurve as GRPCTrimmedCurve from beartype.typing import TYPE_CHECKING, List, Optional, Tuple -from ansys.geometry.core.geometry.curves.circle import Circle -from ansys.geometry.core.geometry.curves.curve import Curve -from ansys.geometry.core.geometry.curves.ellipse import Ellipse -from ansys.geometry.core.geometry.curves.line import Line -from ansys.geometry.core.geometry.surfaces.cone import Cone -from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder -from ansys.geometry.core.geometry.surfaces.plane import PlaneSurface -from ansys.geometry.core.geometry.surfaces.sphere import Sphere -from ansys.geometry.core.geometry.surfaces.surface import Surface -from ansys.geometry.core.geometry.surfaces.torus import Torus from ansys.geometry.core.math import Frame, Matrix44, Plane, Point2D, Point3D, UnitVector3D from ansys.geometry.core.misc import DEFAULT_UNITS +from ansys.geometry.core.shapes.curves.circle import Circle +from ansys.geometry.core.shapes.curves.curve import Curve +from ansys.geometry.core.shapes.curves.ellipse import Ellipse +from ansys.geometry.core.shapes.curves.line import Line +from ansys.geometry.core.shapes.surfaces.cone import Cone +from ansys.geometry.core.shapes.surfaces.cylinder import Cylinder +from ansys.geometry.core.shapes.surfaces.plane import PlaneSurface +from ansys.geometry.core.shapes.surfaces.sphere import Sphere +from ansys.geometry.core.shapes.surfaces.surface import Surface +from ansys.geometry.core.shapes.surfaces.torus import Torus from ansys.geometry.core.sketch.arc import Arc from ansys.geometry.core.sketch.circle import SketchCircle from ansys.geometry.core.sketch.edge import SketchEdge @@ -62,7 +62,7 @@ from pyvista import PolyData from ansys.geometry.core.designer import SurfaceType - from ansys.geometry.core.geometry.curves.trimmed_curve import TrimmedCurve + from ansys.geometry.core.shapes.curves.trimmed_curve import TrimmedCurve def unit_vector_to_grpc_direction(unit_vector: UnitVector3D) -> GRPCDirection: diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 93473fe56f..e617c61ee3 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -30,11 +30,11 @@ from ansys.geometry.core.connection import GrpcClient, grpc_curve_to_curve from ansys.geometry.core.errors import protect_grpc -from ansys.geometry.core.geometry.curves.trimmed_curve import ReversedTrimmedCurve, TrimmedCurve -from ansys.geometry.core.geometry.parameterization import Interval from ansys.geometry.core.math.point import Point3D from ansys.geometry.core.misc.checks import ensure_design_is_active from ansys.geometry.core.misc.measurements import DEFAULT_UNITS +from ansys.geometry.core.shapes.curves.trimmed_curve import ReversedTrimmedCurve, TrimmedCurve +from ansys.geometry.core.shapes.parameterization import Interval if TYPE_CHECKING: # pragma: no cover from ansys.geometry.core.designer.body import Body diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index 170ae01587..994226b1bc 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -33,15 +33,15 @@ from ansys.geometry.core.connection import GrpcClient, grpc_curve_to_curve, grpc_surface_to_surface from ansys.geometry.core.errors import protect_grpc -from ansys.geometry.core.geometry.curves.trimmed_curve import TrimmedCurve -from ansys.geometry.core.geometry.parameterization import Interval -from ansys.geometry.core.geometry.surfaces.trimmed_surface import ( - ReversedTrimmedSurface, - TrimmedSurface, -) from ansys.geometry.core.math import Point3D, UnitVector3D from ansys.geometry.core.misc.checks import ensure_design_is_active from ansys.geometry.core.misc.measurements import DEFAULT_UNITS +from ansys.geometry.core.shapes.curves.trimmed_curve import TrimmedCurve +from ansys.geometry.core.shapes.parameterization import Interval +from ansys.geometry.core.shapes.surfaces.trimmed_surface import ( + ReversedTrimmedSurface, + TrimmedSurface, +) if TYPE_CHECKING: # pragma: no cover from ansys.geometry.core.designer.body import Body diff --git a/src/ansys/geometry/core/geometry/__init__.py b/src/ansys/geometry/core/shapes/__init__.py similarity index 59% rename from src/ansys/geometry/core/geometry/__init__.py rename to src/ansys/geometry/core/shapes/__init__.py index e7eaebdda1..45f4ca4e28 100644 --- a/src/ansys/geometry/core/geometry/__init__.py +++ b/src/ansys/geometry/core/shapes/__init__.py @@ -21,21 +21,21 @@ # SOFTWARE. """Provides the PyAnsys Geometry ``geometry`` subpackage.""" -from ansys.geometry.core.geometry.curves.circle import Circle, CircleEvaluation -from ansys.geometry.core.geometry.curves.curve import Curve -from ansys.geometry.core.geometry.curves.ellipse import Ellipse, EllipseEvaluation -from ansys.geometry.core.geometry.curves.line import Line, LineEvaluation -from ansys.geometry.core.geometry.parameterization import ( +from ansys.geometry.core.shapes.curves.circle import Circle, CircleEvaluation +from ansys.geometry.core.shapes.curves.curve import Curve +from ansys.geometry.core.shapes.curves.ellipse import Ellipse, EllipseEvaluation +from ansys.geometry.core.shapes.curves.line import Line, LineEvaluation +from ansys.geometry.core.shapes.parameterization import ( Interval, Parameterization, ParamForm, ParamType, ParamUV, ) -from ansys.geometry.core.geometry.surfaces.cone import Cone, ConeEvaluation -from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder, CylinderEvaluation -from ansys.geometry.core.geometry.surfaces.plane import PlaneEvaluation, PlaneSurface -from ansys.geometry.core.geometry.surfaces.sphere import Sphere, SphereEvaluation -from ansys.geometry.core.geometry.surfaces.surface import Surface -from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation -from ansys.geometry.core.geometry.surfaces.torus import Torus +from ansys.geometry.core.shapes.surfaces.cone import Cone, ConeEvaluation +from ansys.geometry.core.shapes.surfaces.cylinder import Cylinder, CylinderEvaluation +from ansys.geometry.core.shapes.surfaces.plane import PlaneEvaluation, PlaneSurface +from ansys.geometry.core.shapes.surfaces.sphere import Sphere, SphereEvaluation +from ansys.geometry.core.shapes.surfaces.surface import Surface +from ansys.geometry.core.shapes.surfaces.surface_evaluation import SurfaceEvaluation +from ansys.geometry.core.shapes.surfaces.torus import Torus diff --git a/src/ansys/geometry/core/geometry/box_uv.py b/src/ansys/geometry/core/shapes/box_uv.py similarity index 98% rename from src/ansys/geometry/core/geometry/box_uv.py rename to src/ansys/geometry/core/shapes/box_uv.py index 4ba87e1786..ae0e01e0b3 100644 --- a/src/ansys/geometry/core/geometry/box_uv.py +++ b/src/ansys/geometry/core/shapes/box_uv.py @@ -22,7 +22,7 @@ """Provides the ``BoxUV`` class.""" from enum import Enum -from ansys.geometry.core.geometry.parameterization import Interval, ParamUV +from ansys.geometry.core.shapes.parameterization import Interval, ParamUV from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/geometry/curves/__init__.py b/src/ansys/geometry/core/shapes/curves/__init__.py similarity index 76% rename from src/ansys/geometry/core/geometry/curves/__init__.py rename to src/ansys/geometry/core/shapes/curves/__init__.py index b170b36c91..a0b8e02f4f 100644 --- a/src/ansys/geometry/core/geometry/curves/__init__.py +++ b/src/ansys/geometry/core/shapes/curves/__init__.py @@ -20,8 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. """Provides the PyAnsys Geometry ``curve`` subpackage.""" -from ansys.geometry.core.geometry.curves.circle import Circle, CircleEvaluation -from ansys.geometry.core.geometry.curves.curve import Curve -from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation -from ansys.geometry.core.geometry.curves.ellipse import Ellipse, EllipseEvaluation -from ansys.geometry.core.geometry.curves.line import Line, LineEvaluation +from ansys.geometry.core.shapes.curves.circle import Circle, CircleEvaluation +from ansys.geometry.core.shapes.curves.curve import Curve +from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.shapes.curves.ellipse import Ellipse, EllipseEvaluation +from ansys.geometry.core.shapes.curves.line import Line, LineEvaluation diff --git a/src/ansys/geometry/core/geometry/curves/circle.py b/src/ansys/geometry/core/shapes/curves/circle.py similarity index 98% rename from src/ansys/geometry/core/geometry/curves/circle.py rename to src/ansys/geometry/core/shapes/curves/circle.py index 825a0bfa70..09adaa7686 100644 --- a/src/ansys/geometry/core/geometry/curves/circle.py +++ b/src/ansys/geometry/core/shapes/curves/circle.py @@ -27,14 +27,6 @@ import numpy as np from pint import Quantity -from ansys.geometry.core.geometry.curves.curve import Curve -from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation -from ansys.geometry.core.geometry.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, -) from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -44,6 +36,14 @@ Vector3D, ) from ansys.geometry.core.misc import Accuracy, Distance +from ansys.geometry.core.shapes.curves.curve import Curve +from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.shapes.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, +) from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/geometry/curves/curve.py b/src/ansys/geometry/core/shapes/curves/curve.py similarity index 94% rename from src/ansys/geometry/core/geometry/curves/curve.py rename to src/ansys/geometry/core/shapes/curves/curve.py index b6c0a79d9d..cda8583b0a 100644 --- a/src/ansys/geometry/core/geometry/curves/curve.py +++ b/src/ansys/geometry/core/shapes/curves/curve.py @@ -22,9 +22,9 @@ """Provides the ``Curve`` class.""" from abc import ABC, abstractmethod -from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation -from ansys.geometry.core.geometry.parameterization import Parameterization from ansys.geometry.core.math import Matrix44, Point3D +from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.shapes.parameterization import Parameterization from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/geometry/curves/curve_evaluation.py b/src/ansys/geometry/core/shapes/curves/curve_evaluation.py similarity index 100% rename from src/ansys/geometry/core/geometry/curves/curve_evaluation.py rename to src/ansys/geometry/core/shapes/curves/curve_evaluation.py diff --git a/src/ansys/geometry/core/geometry/curves/ellipse.py b/src/ansys/geometry/core/shapes/curves/ellipse.py similarity index 98% rename from src/ansys/geometry/core/geometry/curves/ellipse.py rename to src/ansys/geometry/core/shapes/curves/ellipse.py index 3fae9ef8b9..27684c5670 100644 --- a/src/ansys/geometry/core/geometry/curves/ellipse.py +++ b/src/ansys/geometry/core/shapes/curves/ellipse.py @@ -29,14 +29,6 @@ from pint import Quantity from scipy.integrate import quad -from ansys.geometry.core.geometry.curves.curve import Curve -from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation -from ansys.geometry.core.geometry.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, -) from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -46,6 +38,14 @@ Vector3D, ) from ansys.geometry.core.misc import Accuracy, Distance +from ansys.geometry.core.shapes.curves.curve import Curve +from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.shapes.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, +) from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/geometry/curves/line.py b/src/ansys/geometry/core/shapes/curves/line.py similarity index 97% rename from src/ansys/geometry/core/geometry/curves/line.py rename to src/ansys/geometry/core/shapes/curves/line.py index 176e93696a..ad95244e6c 100644 --- a/src/ansys/geometry/core/geometry/curves/line.py +++ b/src/ansys/geometry/core/shapes/curves/line.py @@ -28,16 +28,16 @@ from beartype.typing import Union import numpy as np -from ansys.geometry.core.geometry.curves.curve import Curve -from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation -from ansys.geometry.core.geometry.parameterization import ( +from ansys.geometry.core.math import Matrix44, Point3D, UnitVector3D, Vector3D +from ansys.geometry.core.misc.accuracy import LENGTH_ACCURACY +from ansys.geometry.core.shapes.curves.curve import Curve +from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.shapes.parameterization import ( Interval, Parameterization, ParamForm, ParamType, ) -from ansys.geometry.core.math import Matrix44, Point3D, UnitVector3D, Vector3D -from ansys.geometry.core.misc.accuracy import LENGTH_ACCURACY from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py b/src/ansys/geometry/core/shapes/curves/trimmed_curve.py similarity index 97% rename from src/ansys/geometry/core/geometry/curves/trimmed_curve.py rename to src/ansys/geometry/core/shapes/curves/trimmed_curve.py index df59120828..ff3d81b429 100644 --- a/src/ansys/geometry/core/geometry/curves/trimmed_curve.py +++ b/src/ansys/geometry/core/shapes/curves/trimmed_curve.py @@ -28,10 +28,10 @@ from ansys.geometry.core.connection.client import GrpcClient from ansys.geometry.core.connection.conversions import trimmed_curve_to_grpc_trimmed_curve from ansys.geometry.core.errors import protect_grpc -from ansys.geometry.core.geometry.curves.curve import Curve -from ansys.geometry.core.geometry.curves.curve_evaluation import CurveEvaluation -from ansys.geometry.core.geometry.parameterization import Interval from ansys.geometry.core.math import Point3D +from ansys.geometry.core.shapes.curves.curve import Curve +from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation +from ansys.geometry.core.shapes.parameterization import Interval from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/geometry/parameterization.py b/src/ansys/geometry/core/shapes/parameterization.py similarity index 100% rename from src/ansys/geometry/core/geometry/parameterization.py rename to src/ansys/geometry/core/shapes/parameterization.py diff --git a/src/ansys/geometry/core/geometry/surfaces/__init__.py b/src/ansys/geometry/core/shapes/surfaces/__init__.py similarity index 68% rename from src/ansys/geometry/core/geometry/surfaces/__init__.py rename to src/ansys/geometry/core/shapes/surfaces/__init__.py index aeb872263b..fcba4132e1 100644 --- a/src/ansys/geometry/core/geometry/surfaces/__init__.py +++ b/src/ansys/geometry/core/shapes/surfaces/__init__.py @@ -20,10 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. """Provides the PyAnsys Geometry ``surface`` subpackage.""" -from ansys.geometry.core.geometry.surfaces.cone import Cone, ConeEvaluation -from ansys.geometry.core.geometry.surfaces.cylinder import Cylinder, CylinderEvaluation -from ansys.geometry.core.geometry.surfaces.plane import PlaneEvaluation, PlaneSurface -from ansys.geometry.core.geometry.surfaces.sphere import Sphere, SphereEvaluation -from ansys.geometry.core.geometry.surfaces.surface import Surface -from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation -from ansys.geometry.core.geometry.surfaces.torus import Torus +from ansys.geometry.core.shapes.surfaces.cone import Cone, ConeEvaluation +from ansys.geometry.core.shapes.surfaces.cylinder import Cylinder, CylinderEvaluation +from ansys.geometry.core.shapes.surfaces.plane import PlaneEvaluation, PlaneSurface +from ansys.geometry.core.shapes.surfaces.sphere import Sphere, SphereEvaluation +from ansys.geometry.core.shapes.surfaces.surface import Surface +from ansys.geometry.core.shapes.surfaces.surface_evaluation import SurfaceEvaluation +from ansys.geometry.core.shapes.surfaces.torus import Torus diff --git a/src/ansys/geometry/core/geometry/surfaces/cone.py b/src/ansys/geometry/core/shapes/surfaces/cone.py similarity index 98% rename from src/ansys/geometry/core/geometry/surfaces/cone.py rename to src/ansys/geometry/core/shapes/surfaces/cone.py index 254d9b0dac..d757b066b2 100644 --- a/src/ansys/geometry/core/geometry/surfaces/cone.py +++ b/src/ansys/geometry/core/shapes/surfaces/cone.py @@ -28,16 +28,6 @@ import numpy as np from pint import Quantity -from ansys.geometry.core.geometry.curves.line import Line -from ansys.geometry.core.geometry.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, - ParamUV, -) -from ansys.geometry.core.geometry.surfaces.surface import Surface -from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -47,6 +37,16 @@ Vector3D, ) from ansys.geometry.core.misc import Angle, Distance +from ansys.geometry.core.shapes.curves.line import Line +from ansys.geometry.core.shapes.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, + ParamUV, +) +from ansys.geometry.core.shapes.surfaces.surface import Surface +from ansys.geometry.core.shapes.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/geometry/surfaces/cylinder.py b/src/ansys/geometry/core/shapes/surfaces/cylinder.py similarity index 97% rename from src/ansys/geometry/core/geometry/surfaces/cylinder.py rename to src/ansys/geometry/core/shapes/surfaces/cylinder.py index 459cc85e15..226ceb198f 100644 --- a/src/ansys/geometry/core/geometry/surfaces/cylinder.py +++ b/src/ansys/geometry/core/shapes/surfaces/cylinder.py @@ -28,17 +28,6 @@ import numpy as np from pint import Quantity -from ansys.geometry.core.geometry.curves.circle import Circle -from ansys.geometry.core.geometry.curves.line import Line -from ansys.geometry.core.geometry.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, - ParamUV, -) -from ansys.geometry.core.geometry.surfaces.surface import Surface -from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -48,6 +37,17 @@ Vector3D, ) from ansys.geometry.core.misc import Distance +from ansys.geometry.core.shapes.curves.circle import Circle +from ansys.geometry.core.shapes.curves.line import Line +from ansys.geometry.core.shapes.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, + ParamUV, +) +from ansys.geometry.core.shapes.surfaces.surface import Surface +from ansys.geometry.core.shapes.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/geometry/surfaces/plane.py b/src/ansys/geometry/core/shapes/surfaces/plane.py similarity index 97% rename from src/ansys/geometry/core/geometry/surfaces/plane.py rename to src/ansys/geometry/core/shapes/surfaces/plane.py index 6cd83ae0d1..9d3f4fd8cd 100644 --- a/src/ansys/geometry/core/geometry/surfaces/plane.py +++ b/src/ansys/geometry/core/shapes/surfaces/plane.py @@ -26,15 +26,6 @@ from beartype.typing import Tuple, Union import numpy as np -from ansys.geometry.core.geometry.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, - ParamUV, -) -from ansys.geometry.core.geometry.surfaces.surface import Surface -from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -43,6 +34,15 @@ UnitVector3D, Vector3D, ) +from ansys.geometry.core.shapes.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, + ParamUV, +) +from ansys.geometry.core.shapes.surfaces.surface import Surface +from ansys.geometry.core.shapes.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/geometry/surfaces/sphere.py b/src/ansys/geometry/core/shapes/surfaces/sphere.py similarity index 98% rename from src/ansys/geometry/core/geometry/surfaces/sphere.py rename to src/ansys/geometry/core/shapes/surfaces/sphere.py index 24c401c7bd..a889333aee 100644 --- a/src/ansys/geometry/core/geometry/surfaces/sphere.py +++ b/src/ansys/geometry/core/shapes/surfaces/sphere.py @@ -28,15 +28,6 @@ import numpy as np from pint import Quantity -from ansys.geometry.core.geometry.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, - ParamUV, -) -from ansys.geometry.core.geometry.surfaces.surface import Surface -from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -46,6 +37,15 @@ Vector3D, ) from ansys.geometry.core.misc import Distance +from ansys.geometry.core.shapes.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, + ParamUV, +) +from ansys.geometry.core.shapes.surfaces.surface import Surface +from ansys.geometry.core.shapes.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/geometry/surfaces/surface.py b/src/ansys/geometry/core/shapes/surfaces/surface.py similarity index 94% rename from src/ansys/geometry/core/geometry/surfaces/surface.py rename to src/ansys/geometry/core/shapes/surfaces/surface.py index 1ec681aec9..6715aab96f 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface.py +++ b/src/ansys/geometry/core/shapes/surfaces/surface.py @@ -24,9 +24,9 @@ from beartype.typing import Tuple -from ansys.geometry.core.geometry.parameterization import Parameterization, ParamUV -from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import Matrix44, Point3D +from ansys.geometry.core.shapes.parameterization import Parameterization, ParamUV +from ansys.geometry.core.shapes.surfaces.surface_evaluation import SurfaceEvaluation class Surface(ABC): diff --git a/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py b/src/ansys/geometry/core/shapes/surfaces/surface_evaluation.py similarity index 98% rename from src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py rename to src/ansys/geometry/core/shapes/surfaces/surface_evaluation.py index 913780dfb5..6ab8cbf8c1 100644 --- a/src/ansys/geometry/core/geometry/surfaces/surface_evaluation.py +++ b/src/ansys/geometry/core/shapes/surfaces/surface_evaluation.py @@ -23,8 +23,8 @@ from functools import cached_property -from ansys.geometry.core.geometry.parameterization import ParamUV from ansys.geometry.core.math import Point3D, UnitVector3D, Vector3D +from ansys.geometry.core.shapes.parameterization import ParamUV from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/geometry/surfaces/torus.py b/src/ansys/geometry/core/shapes/surfaces/torus.py similarity index 98% rename from src/ansys/geometry/core/geometry/surfaces/torus.py rename to src/ansys/geometry/core/shapes/surfaces/torus.py index 9c2a860e95..ccfd99abe8 100644 --- a/src/ansys/geometry/core/geometry/surfaces/torus.py +++ b/src/ansys/geometry/core/shapes/surfaces/torus.py @@ -29,15 +29,6 @@ import numpy as np from pint import Quantity -from ansys.geometry.core.geometry.parameterization import ( - Interval, - Parameterization, - ParamForm, - ParamType, - ParamUV, -) -from ansys.geometry.core.geometry.surfaces.surface import Surface -from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Z, @@ -47,6 +38,15 @@ Vector3D, ) from ansys.geometry.core.misc import Distance +from ansys.geometry.core.shapes.parameterization import ( + Interval, + Parameterization, + ParamForm, + ParamType, + ParamUV, +) +from ansys.geometry.core.shapes.surfaces.surface import Surface +from ansys.geometry.core.shapes.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.typing import Real, RealSequence diff --git a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py b/src/ansys/geometry/core/shapes/surfaces/trimmed_surface.py similarity index 95% rename from src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py rename to src/ansys/geometry/core/shapes/surfaces/trimmed_surface.py index 53803bc500..19a6216f18 100644 --- a/src/ansys/geometry/core/geometry/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/shapes/surfaces/trimmed_surface.py @@ -23,12 +23,12 @@ from beartype.typing import TYPE_CHECKING -from ansys.geometry.core.geometry.box_uv import BoxUV -from ansys.geometry.core.geometry.parameterization import Interval, ParamUV -from ansys.geometry.core.geometry.surfaces.surface import Surface -from ansys.geometry.core.geometry.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.math import Point3D from ansys.geometry.core.math.vector import UnitVector3D +from ansys.geometry.core.shapes.box_uv import BoxUV +from ansys.geometry.core.shapes.parameterization import Interval, ParamUV +from ansys.geometry.core.shapes.surfaces.surface import Surface +from ansys.geometry.core.shapes.surfaces.surface_evaluation import SurfaceEvaluation from ansys.geometry.core.typing import Real if TYPE_CHECKING: diff --git a/src/ansys/geometry/core/sketch/circle.py b/src/ansys/geometry/core/sketch/circle.py index 85cc516a8d..d5e826690c 100644 --- a/src/ansys/geometry/core/sketch/circle.py +++ b/src/ansys/geometry/core/sketch/circle.py @@ -26,9 +26,9 @@ from pint import Quantity import pyvista as pv -from ansys.geometry.core.geometry.curves.circle import Circle from ansys.geometry.core.math import Plane, Point2D, Point3D from ansys.geometry.core.misc import DEFAULT_UNITS, Distance +from ansys.geometry.core.shapes.curves.circle import Circle from ansys.geometry.core.sketch.face import SketchFace from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/sketch/ellipse.py b/src/ansys/geometry/core/sketch/ellipse.py index d359e038da..203a28c4ea 100644 --- a/src/ansys/geometry/core/sketch/ellipse.py +++ b/src/ansys/geometry/core/sketch/ellipse.py @@ -28,9 +28,9 @@ import pyvista as pv from scipy.spatial.transform import Rotation as spatial_rotation -from ansys.geometry.core.geometry import Ellipse from ansys.geometry.core.math import Matrix33, Matrix44, Plane, Point2D, Point3D, Vector3D from ansys.geometry.core.misc import DEFAULT_UNITS, UNITS, Angle, Distance +from ansys.geometry.core.shapes import Ellipse from ansys.geometry.core.sketch.face import SketchFace from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/sketch/segment.py b/src/ansys/geometry/core/sketch/segment.py index cf4486fde0..2cb36e6226 100644 --- a/src/ansys/geometry/core/sketch/segment.py +++ b/src/ansys/geometry/core/sketch/segment.py @@ -26,9 +26,9 @@ from pint import Quantity import pyvista as pv -from ansys.geometry.core.geometry import Line from ansys.geometry.core.math import Plane, Point2D, Point3D, UnitVector3D from ansys.geometry.core.misc import DEFAULT_UNITS, check_ndarray_is_all_nan +from ansys.geometry.core.shapes import Line from ansys.geometry.core.sketch.edge import SketchEdge diff --git a/tests/integration/test_design.py b/tests/integration/test_design.py index c71b40a3e3..37e5d52e01 100644 --- a/tests/integration/test_design.py +++ b/tests/integration/test_design.py @@ -41,7 +41,6 @@ from ansys.geometry.core.designer.body import CollisionType from ansys.geometry.core.designer.face import FaceLoopType from ansys.geometry.core.errors import GeometryExitedError -from ansys.geometry.core.geometry.parameterization import ParamUV from ansys.geometry.core.materials import Material, MaterialProperty, MaterialPropertyType from ansys.geometry.core.math import ( IDENTITY_MATRIX44, @@ -56,6 +55,7 @@ Vector3D, ) from ansys.geometry.core.misc import DEFAULT_UNITS, UNITS, Accuracy, Distance +from ansys.geometry.core.shapes.parameterization import ParamUV from ansys.geometry.core.sketch import Sketch diff --git a/tests/integration/test_trimmed_geometry.py b/tests/integration/test_trimmed_geometry.py index 9ab6e2a597..20b4bc4a94 100644 --- a/tests/integration/test_trimmed_geometry.py +++ b/tests/integration/test_trimmed_geometry.py @@ -27,17 +27,17 @@ from ansys.geometry.core.connection import BackendType, point3d_to_grpc_point from ansys.geometry.core.designer.design import Design from ansys.geometry.core.designer.face import SurfaceType -from ansys.geometry.core.geometry import Circle, Line -from ansys.geometry.core.geometry.box_uv import LocationUV -from ansys.geometry.core.geometry.curves.trimmed_curve import ReversedTrimmedCurve, TrimmedCurve -from ansys.geometry.core.geometry.parameterization import Interval -from ansys.geometry.core.geometry.surfaces.trimmed_surface import ( - ReversedTrimmedSurface, - TrimmedSurface, -) from ansys.geometry.core.math import Point3D, UnitVector3D from ansys.geometry.core.math.point import Point2D from ansys.geometry.core.modeler import Modeler +from ansys.geometry.core.shapes import Circle, Line +from ansys.geometry.core.shapes.box_uv import LocationUV +from ansys.geometry.core.shapes.curves.trimmed_curve import ReversedTrimmedCurve, TrimmedCurve +from ansys.geometry.core.shapes.parameterization import Interval +from ansys.geometry.core.shapes.surfaces.trimmed_surface import ( + ReversedTrimmedSurface, + TrimmedSurface, +) from ansys.geometry.core.sketch.sketch import Sketch """A Helper function to create a sktech line given two points and a ``Design``.""" diff --git a/tests/test_parameterization.py b/tests/test_parameterization.py index 75edc90fbb..89ad4efef3 100644 --- a/tests/test_parameterization.py +++ b/tests/test_parameterization.py @@ -24,8 +24,8 @@ import numpy as np import pytest -from ansys.geometry.core.geometry import Interval, Parameterization, ParamForm, ParamType, ParamUV from ansys.geometry.core.misc.accuracy import Accuracy +from ansys.geometry.core.shapes import Interval, Parameterization, ParamForm, ParamType, ParamUV def test_param_uv(): diff --git a/tests/test_primitives.py b/tests/test_primitives.py index 5b19415f1d..9d5ed82308 100644 --- a/tests/test_primitives.py +++ b/tests/test_primitives.py @@ -25,16 +25,6 @@ from pint import Quantity import pytest -from ansys.geometry.core.geometry import ( - Circle, - Cone, - Cylinder, - Ellipse, - Line, - ParamUV, - Sphere, - Torus, -) from ansys.geometry.core.math import ( UNITVECTOR3D_X, UNITVECTOR3D_Y, @@ -45,6 +35,7 @@ Vector3D, ) from ansys.geometry.core.misc import DEFAULT_UNITS, UNITS, Accuracy, Distance +from ansys.geometry.core.shapes import Circle, Cone, Cylinder, Ellipse, Line, ParamUV, Sphere, Torus def test_cylinder(): From 748c416cd4b33857720f67cc3244f862dd752fb9 Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Tue, 12 Mar 2024 04:12:23 -0400 Subject: [PATCH 62/76] Apply suggestions from code review Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/connection/conversions.py | 4 ++-- src/ansys/geometry/core/designer/face.py | 2 +- src/ansys/geometry/core/shapes/box_uv.py | 2 +- src/ansys/geometry/core/shapes/parameterization.py | 2 +- src/ansys/geometry/core/shapes/surfaces/plane.py | 2 +- .../geometry/core/shapes/surfaces/trimmed_surface.py | 2 +- tests/integration/test_trimmed_geometry.py | 10 +++++----- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ansys/geometry/core/connection/conversions.py b/src/ansys/geometry/core/connection/conversions.py index 4ea8266a50..9828c70a02 100644 --- a/src/ansys/geometry/core/connection/conversions.py +++ b/src/ansys/geometry/core/connection/conversions.py @@ -526,7 +526,7 @@ def grpc_curve_to_curve(curve: GRPCCurve) -> Curve: def curve_to_grpc_curve(curve: Curve) -> GRPCCurve: """ - Convert a ``Curve``to an ``ansys.api.geometry.CurveGeometry`` gRPC message. + Convert a ``Curve`` to an ``ansys.api.geometry.CurveGeometry`` gRPC message. Parameters ---------- @@ -576,7 +576,7 @@ def trimmed_curve_to_grpc_trimmed_curve(curve: "TrimmedCurve") -> GRPCTrimmedCur Returns ------- GRPCTrimmedCurve - Geometry service gRPC TrimmedCurve message. + Geometry service gRPC ``TrimmedCurve`` message. """ curve_geometry = curve_to_grpc_curve(curve.geometry) start = point3d_to_grpc_point(curve.start) diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index 994226b1bc..2bc4a3f3ae 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -179,7 +179,7 @@ def id(self) -> str: @property def _grpc_id(self) -> EntityIdentifier: - """Entity identifier of this face on the server side.""" + """Entity ID of this face on the server side.""" return EntityIdentifier(id=self._id) @property diff --git a/src/ansys/geometry/core/shapes/box_uv.py b/src/ansys/geometry/core/shapes/box_uv.py index ae0e01e0b3..dcfc2dd2f1 100644 --- a/src/ansys/geometry/core/shapes/box_uv.py +++ b/src/ansys/geometry/core/shapes/box_uv.py @@ -87,7 +87,7 @@ def proportion(self, prop_u: Real, prop_v: Real) -> ParamUV: ) def get_center(self) -> ParamUV: - """Evaluate the this ``BoxUV`` in the center.""" + """Evaluate the this BoxUV in the center.""" return self.proportion(0.5, 0.5) def is_negative(self, tolerance_u: Real, tolerance_v: Real) -> bool: diff --git a/src/ansys/geometry/core/shapes/parameterization.py b/src/ansys/geometry/core/shapes/parameterization.py index b7549da0ac..40e6df2ab1 100644 --- a/src/ansys/geometry/core/shapes/parameterization.py +++ b/src/ansys/geometry/core/shapes/parameterization.py @@ -221,7 +221,7 @@ def get_span(self) -> Real: """ Get the quantity contained by the interval. - The Interval must be closed. + The interval must be closed. Returns ------- diff --git a/src/ansys/geometry/core/shapes/surfaces/plane.py b/src/ansys/geometry/core/shapes/surfaces/plane.py index 9d3f4fd8cd..357c64f548 100644 --- a/src/ansys/geometry/core/shapes/surfaces/plane.py +++ b/src/ansys/geometry/core/shapes/surfaces/plane.py @@ -66,7 +66,7 @@ def __init__( reference: Union[np.ndarray, RealSequence, UnitVector3D, Vector3D] = UNITVECTOR3D_X, axis: Union[np.ndarray, RealSequence, UnitVector3D, Vector3D] = UNITVECTOR3D_Z, ): - """Initialize `an instance of a plane surface.""" + """Initialize an instance of a plane surface.""" self._origin = Point3D(origin) if not isinstance(origin, Point3D) else origin self._reference = ( diff --git a/src/ansys/geometry/core/shapes/surfaces/trimmed_surface.py b/src/ansys/geometry/core/shapes/surfaces/trimmed_surface.py index 19a6216f18..f954436673 100644 --- a/src/ansys/geometry/core/shapes/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/shapes/surfaces/trimmed_surface.py @@ -109,7 +109,7 @@ def normal(self, u: Real, v: Real) -> UnitVector3D: Returns ------- UnitVector3D - This unit vector is normal to the surface at the given UV coordinates. + Unit vector is normal to the surface at the given UV coordinates. """ return self.evaluate_proportion(u, v).normal diff --git a/tests/integration/test_trimmed_geometry.py b/tests/integration/test_trimmed_geometry.py index 20b4bc4a94..97735fe0aa 100644 --- a/tests/integration/test_trimmed_geometry.py +++ b/tests/integration/test_trimmed_geometry.py @@ -40,7 +40,7 @@ ) from ansys.geometry.core.sketch.sketch import Sketch -"""A Helper function to create a sktech line given two points and a ``Design``.""" +"""A helper function to create a sketch line given two points and a design.""" def create_sketch_line(design: Design, p1: Point3D, p2: Point3D): @@ -49,7 +49,7 @@ def create_sketch_line(design: Design, p1: Point3D, p2: Point3D): design._commands_stub.CreateSketchLine(CreateSketchLineRequest(point1=point1, point2=point2)) -"""A Helper function that creates the Hedgehog model.""" +"""A helper function that creates the Hedgehog model.""" def create_hedgehog(modeler: Modeler): @@ -105,7 +105,7 @@ def hedgehog_design(modeler: Modeler): yield h -"""Tests the surface properties for hedgehog""" +"""Tests the surface properties for the hedgehog design.""" def test_trimmed_surface_properties(hedgehog_design): @@ -160,7 +160,7 @@ def test_trimmed_surface_properties(hedgehog_design): assert faces[i].shape.box_uv.interval_v == Interval(start=interval_v[0], end=interval_v[1]) -"""Tests the normal vectors for hedgehog by using the ``BoxUV`` coordinates.""" +"""Tests the normal vectors for the hedgehog design using the BoxUV coordinates.""" def test_trimmed_surface_normals(hedgehog_design): @@ -218,7 +218,7 @@ def test_trimmed_surface_normals(hedgehog_design): assert np.allclose(faces[i].shape.normal(corner_param.u, corner_param.v), bottom_right) -"""Tests the curve properties for hedgehog""" +"""Tests the curve properties for the hedgehog design.""" def test_trimmed_curve_properties(hedgehog_design): From 294da8514f03d2d7975021982484b07e93e15dcd Mon Sep 17 00:00:00 2001 From: dastan-ansys <132925889+dastan-ansys@users.noreply.github.com> Date: Tue, 12 Mar 2024 04:21:42 -0400 Subject: [PATCH 63/76] Update src/ansys/geometry/core/designer/edge.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- src/ansys/geometry/core/designer/edge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index e617c61ee3..6386331e33 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -97,7 +97,7 @@ def id(self) -> str: @property def _grpc_id(self) -> EntityIdentifier: - """Entity identifier of this edge on the server side.""" + """Entity ID of this edge on the server side.""" return EntityIdentifier(id=self._id) @property From 9adf944f23cbc4627ab5165977df0650bc31238e Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Tue, 12 Mar 2024 04:35:20 -0400 Subject: [PATCH 64/76] added implemented changes manually --- src/ansys/geometry/core/designer/face.py | 2 +- src/ansys/geometry/core/shapes/box_uv.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index 2bc4a3f3ae..f05b7c4d7d 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -32,6 +32,7 @@ from pint import Quantity from ansys.geometry.core.connection import GrpcClient, grpc_curve_to_curve, grpc_surface_to_surface +from ansys.geometry.core.designer.edge import Edge from ansys.geometry.core.errors import protect_grpc from ansys.geometry.core.math import Point3D, UnitVector3D from ansys.geometry.core.misc.checks import ensure_design_is_active @@ -45,7 +46,6 @@ if TYPE_CHECKING: # pragma: no cover from ansys.geometry.core.designer.body import Body - from ansys.geometry.core.designer.edge import Edge @unique diff --git a/src/ansys/geometry/core/shapes/box_uv.py b/src/ansys/geometry/core/shapes/box_uv.py index dcfc2dd2f1..93a42b3140 100644 --- a/src/ansys/geometry/core/shapes/box_uv.py +++ b/src/ansys/geometry/core/shapes/box_uv.py @@ -99,15 +99,15 @@ def is_negative(self, tolerance_u: Real, tolerance_v: Real) -> bool: def contains(self, param: ParamUV) -> bool: """Check whether the BoxUV contains a given u and v pair parameter.""" if self.is_empty(): - # throw Error.InvalidMethodOnEmptyObjectException(GetType()) - raise Exception("Invalid Method On Empty Object Exception" + type(self).__name__) + # Cannot check contains for an empty box uv. + raise RuntimeError("Cannot check contains for an empty box uv.") return self.interval_u.contains(param.u) and self.interval_v.contains(param.v) def inflate(self, delta_u: Real, delta_v: Real) -> "BoxUV": """Enlarge the BoxUV u and v intervals by delta_u and delta_v respectively.""" if self.is_empty(): - # throw Error.InvalidMethodOnEmptyObjectException(GetType()) - raise Exception("Invalid Method On Empty Object Exception" + type(self).__name__) + # Cannot inflate an empty box uv. + raise RuntimeError("Cannot inflate an empty box uv.") return BoxUV(self.interval_u.inflate(delta_u), self.interval_v.inflate(delta_v)) def get_corner(self, location: LocationUV) -> ParamUV: From d463fcafc6df43f7c6ce41b6bf809be87c8e3fca Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Tue, 12 Mar 2024 05:14:32 -0400 Subject: [PATCH 65/76] updated docstring in plane --- src/ansys/geometry/core/shapes/surfaces/plane.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/shapes/surfaces/plane.py b/src/ansys/geometry/core/shapes/surfaces/plane.py index 357c64f548..e740ea9560 100644 --- a/src/ansys/geometry/core/shapes/surfaces/plane.py +++ b/src/ansys/geometry/core/shapes/surfaces/plane.py @@ -110,7 +110,7 @@ def contains_param(self, param_uv: ParamUV) -> bool: raise NotImplementedError("contains_param() is not implemented.") def contains_point(self, point: Point3D) -> bool: - """Check whether the plane contains a 3D point.""" + """Check whether a 3D point is in the domain of the plane.""" raise NotImplementedError("contains_point() is not implemented.") def parameterization(self) -> Tuple[Parameterization, Parameterization]: From 05e7eb05930d359568c1be7974c959d1c11aa3ab Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Tue, 12 Mar 2024 05:27:55 -0400 Subject: [PATCH 66/76] changed face_normal() to normal() in test_design.py --- tests/integration/test_design.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/integration/test_design.py b/tests/integration/test_design.py index 1137391d13..c529bdf425 100644 --- a/tests/integration/test_design.py +++ b/tests/integration/test_design.py @@ -201,13 +201,13 @@ def test_extrude_negative_sketch(modeler: Modeler): neg = design.extrude_sketch("negative", sk, 10, direction="-") # Verify that the negative extrusion is in the negative direction - assert neg.faces[0].face_normal() != pos.faces[0].face_normal() - assert np.isclose(neg.faces[0].face_normal().dot(pos.faces[0].face_normal()), -1.0) + assert neg.faces[0].normal() != pos.faces[0].normal() + assert np.isclose(neg.faces[0].normal().dot(pos.faces[0].normal()), -1.0) # If an invalid direction is given, it should default to the positive direction invalid_neg = design.extrude_sketch("invalid", sk, 10, direction="z") - assert invalid_neg.faces[0].face_normal() == pos.faces[0].face_normal() - assert np.isclose(invalid_neg.faces[0].face_normal().dot(pos.faces[0].face_normal()), 1.0) + assert invalid_neg.faces[0].normal() == pos.faces[0].normal() + assert np.isclose(invalid_neg.faces[0].normal().dot(pos.faces[0].normal()), 1.0) def test_extrude_negative_sketch_face(modeler: Modeler): @@ -225,13 +225,13 @@ def test_extrude_negative_sketch_face(modeler: Modeler): neg = design.extrude_face("negative_face", body.faces[0], 10, direction="-") # Verify that the negative extrusion is in the negative direction - assert neg.faces[0].face_normal() != pos.faces[0].face_normal() - assert np.isclose(neg.faces[0].face_normal().dot(pos.faces[0].face_normal()), -1.0) + assert neg.faces[0].normal() != pos.faces[0].normal() + assert np.isclose(neg.faces[0].normal().dot(pos.faces[0].normal()), -1.0) # If an invalid direction is given, it should default to the positive direction invalid_neg = design.extrude_face("invalid_negative_face", body.faces[0], 10, direction="z") - assert invalid_neg.faces[0].face_normal() == pos.faces[0].face_normal() - assert np.isclose(invalid_neg.faces[0].face_normal().dot(pos.faces[0].face_normal()), 1.0) + assert invalid_neg.faces[0].normal() == pos.faces[0].normal() + assert np.isclose(invalid_neg.faces[0].normal().dot(pos.faces[0].normal()), 1.0) def test_modeler(modeler: Modeler): From 5bc34f2969499f11ed70743affa5ca3f2fd1a658 Mon Sep 17 00:00:00 2001 From: dastan-ansys Date: Tue, 12 Mar 2024 05:39:35 -0400 Subject: [PATCH 67/76] changed ansys.geometry.core.geometry to ansys.geometry.core.shapes in example notebook 1 --- doc/source/examples/01_getting_started/01_math.mystnb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/examples/01_getting_started/01_math.mystnb b/doc/source/examples/01_getting_started/01_math.mystnb index b991af8e35..d1b16a5ace 100644 --- a/doc/source/examples/01_getting_started/01_math.mystnb +++ b/doc/source/examples/01_getting_started/01_math.mystnb @@ -150,7 +150,7 @@ PyAnsys Geometry implements parametric evaluations for some curves and surfaces. Evaluate a sphere. ```{code-cell} ipython3 -from ansys.geometry.core.geometry import Sphere, SphereEvaluation +from ansys.geometry.core.shapes import Sphere, SphereEvaluation from ansys.geometry.core.math import Point3D from ansys.geometry.core.misc import Distance From 856770f3b6537ba3f7793f6a30872c7e94241f79 Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:00:24 +0100 Subject: [PATCH 68/76] feat: validate also accept args --- src/ansys/geometry/core/connection/validate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ansys/geometry/core/connection/validate.py b/src/ansys/geometry/core/connection/validate.py index 4a6c16249f..8e6ac3023a 100644 --- a/src/ansys/geometry/core/connection/validate.py +++ b/src/ansys/geometry/core/connection/validate.py @@ -34,7 +34,7 @@ from ansys.geometry.core.connection.client import GrpcClient -def validate(): # pragma: no cover +def validate(*args, **kwargs): # pragma: no cover """Create a client using the default settings and validate it.""" - print(GrpcClient()) + print(GrpcClient(*args, **kwargs)) # TODO: consider adding additional server stat reporting From a4d5d200dd85668f06c34168a72fc67808c506d8 Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:19:21 +0100 Subject: [PATCH 69/76] feat: accuracy independent tests and changes --- src/ansys/geometry/core/misc/accuracy.py | 30 ++++++++++++-- .../geometry/core/shapes/parameterization.py | 2 +- tests/test_misc_accuracy.py | 41 +++++++++++++++++++ 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/ansys/geometry/core/misc/accuracy.py b/src/ansys/geometry/core/misc/accuracy.py index d89dd1fe25..f398e0f34e 100644 --- a/src/ansys/geometry/core/misc/accuracy.py +++ b/src/ansys/geometry/core/misc/accuracy.py @@ -26,24 +26,35 @@ from ansys.geometry.core.typing import Real -LENGTH_ACCURACY = 1e-8 +LENGTH_ACCURACY: Real = 1e-8 """Constant for decimal accuracy in length comparisons.""" -ANGLE_ACCURACY = 1e-6 +ANGLE_ACCURACY: Real = 1e-6 """Constant for decimal accuracy in angle comparisons.""" -DOUBLE_ACCURACY = 1e-13 +DOUBLE_ACCURACY: Real = 1e-13 """Constant for double accuracy.""" class Accuracy: """Provides decimal precision evaluations for actions such as equivalency.""" - @property + @staticmethod def length_accuracy() -> Real: """Return the ``LENGTH_ACCURACY`` constant.""" return LENGTH_ACCURACY + @staticmethod + def angle_accuracy() -> Real: + """Return the ``ANGLE_ACCURACY`` constant.""" + return ANGLE_ACCURACY + + @staticmethod + def double_accuracy() -> Real: + """Return the ``DOUBLE_ACCURACY`` constant.""" + return DOUBLE_ACCURACY + + @staticmethod def length_is_equal(comparison_length: Real, reference_length: Real) -> bool: """ Check if the comparison length is equal to the reference length. @@ -62,10 +73,12 @@ def length_is_equal(comparison_length: Real, reference_length: Real) -> bool: comparison_length, reference_length, LENGTH_ACCURACY, LENGTH_ACCURACY ) + @staticmethod def equal_doubles(a: Real, b: Real): """Compare two double values.""" return Accuracy.is_within_tolerance(a, b, DOUBLE_ACCURACY, DOUBLE_ACCURACY) + @staticmethod def compare_with_tolerance( a: Real, b: Real, relative_tolerance: Real, absolute_tolerance: Real ) -> Real: @@ -77,6 +90,7 @@ def compare_with_tolerance( else: return 1 + @staticmethod def length_is_greater_than_or_equal(comparison_length: Real, reference_length: Real) -> bool: """ Check if the comparison length is greater than the reference length. @@ -96,6 +110,7 @@ def length_is_greater_than_or_equal(comparison_length: Real, reference_length: R or Accuracy.length_is_equal(comparison_length, reference_length) ) + @staticmethod def length_is_less_than_or_equal(comparison_length: Real, reference_length: Real) -> bool: """ Check if the comparison length is less than or equal to the reference length. @@ -115,6 +130,7 @@ def length_is_less_than_or_equal(comparison_length: Real, reference_length: Real or Accuracy.length_is_equal(comparison_length, reference_length) ) + @staticmethod def length_is_zero(length: Real) -> bool: """ Check if the length is within the length accuracy of exact zero. @@ -127,6 +143,7 @@ def length_is_zero(length: Real) -> bool: """ return bool(length <= LENGTH_ACCURACY and length >= -LENGTH_ACCURACY) + @staticmethod def length_is_negative(length: Real) -> bool: """ Check if the length is below a negative length accuracy. @@ -139,6 +156,7 @@ def length_is_negative(length: Real) -> bool: """ return bool(length < -LENGTH_ACCURACY) + @staticmethod def length_is_positive(length: Real) -> bool: """ Check if the length is above a positive length accuracy. @@ -151,6 +169,7 @@ def length_is_positive(length: Real) -> bool: """ return bool(length > LENGTH_ACCURACY) + @staticmethod def angle_is_zero(angle: Real) -> bool: """ Check if the length is within the angle accuracy of exact zero. @@ -163,6 +182,7 @@ def angle_is_zero(angle: Real) -> bool: """ return bool(abs(angle) < ANGLE_ACCURACY) + @staticmethod def angle_is_negative(angle: Real) -> bool: """ Check if the angle is below a negative angle accuracy. @@ -175,6 +195,7 @@ def angle_is_negative(angle: Real) -> bool: """ return bool(angle <= -ANGLE_ACCURACY) + @staticmethod def angle_is_positive(angle: Real) -> bool: """ Check if the angle is above a positive angle accuracy. @@ -187,6 +208,7 @@ def angle_is_positive(angle: Real) -> bool: """ return bool(angle >= ANGLE_ACCURACY) + @staticmethod def is_within_tolerance( a: Real, b: Real, relative_tolerance: Real, absolute_tolerance: Real ) -> bool: diff --git a/src/ansys/geometry/core/shapes/parameterization.py b/src/ansys/geometry/core/shapes/parameterization.py index 40e6df2ab1..9632c6eeeb 100644 --- a/src/ansys/geometry/core/shapes/parameterization.py +++ b/src/ansys/geometry/core/shapes/parameterization.py @@ -357,7 +357,7 @@ def contains(self, t: Real) -> bool: bool ``True`` if the interval contains the value, ``False`` otherwise. """ - return self.contains_value(t, Accuracy.length_accuracy) + return self.contains_value(t, Accuracy.length_accuracy()) def inflate(self, delta: Real) -> "Interval": """Enlarge the current interval by the given delta value.""" diff --git a/tests/test_misc_accuracy.py b/tests/test_misc_accuracy.py index 08a7abb403..7252fecd8f 100644 --- a/tests/test_misc_accuracy.py +++ b/tests/test_misc_accuracy.py @@ -132,3 +132,44 @@ def test_length_reference_equality(): assert Accuracy.length_is_greater_than_or_equal(-5 - 1e-10, -5) assert Accuracy.length_is_greater_than_or_equal(-5 - 1e-9, -5) assert Accuracy.length_is_greater_than_or_equal(-5 + 1e-9, -5) + + +def test_properties_accuracy_class(): + """Test properties of the accuracy class.""" + + import ansys.geometry.core.misc.accuracy as accuracy_module + + # Initialize the accuracy class + accuracy_class = Accuracy() + + # Check the properties + assert accuracy_class.length_accuracy() == accuracy_module.LENGTH_ACCURACY + assert accuracy_class.angle_accuracy() == accuracy_module.ANGLE_ACCURACY + assert accuracy_class.double_accuracy() == accuracy_module.DOUBLE_ACCURACY + + +def test_double_comps(): + """Test double comparisons.""" + + # Test equal doubles + assert Accuracy.equal_doubles(5, 5) + assert Accuracy.equal_doubles(5 + 1e-13, 5) + assert Accuracy.equal_doubles(5 - 1e-13, 5) + assert not Accuracy.equal_doubles(5, 10) + assert not Accuracy.equal_doubles(5 + 1e-12, 5) + assert not Accuracy.equal_doubles(5 - 1e-12, 5) + + # Test compare with tolerance + assert Accuracy.compare_with_tolerance(5, 5, 1e-13, 1e-13) == 0 + assert Accuracy.compare_with_tolerance(5 + 1e-13, 5, 1e-13, 1e-13) == 0 + assert Accuracy.compare_with_tolerance(5 - 1e-13, 5, 1e-13, 1e-13) == 0 + assert Accuracy.compare_with_tolerance(5, 10, 1e-13, 1e-13) == -1 + assert Accuracy.compare_with_tolerance(5 + 1e-12, 5, 1e-13, 1e-13) == 1 + assert Accuracy.compare_with_tolerance(5 - 1e-12, 5, 1e-13, 1e-13) == -1 + assert Accuracy.compare_with_tolerance(5, 5, 1e-12, 1e-12) == 0 + assert Accuracy.compare_with_tolerance(5 + 1e-12, 5, 1e-12, 1e-12) == 0 + assert Accuracy.compare_with_tolerance(5 - 1e-12, 5, 1e-12, 1e-12) == 0 + assert Accuracy.compare_with_tolerance(5, 10, 1e-12, 1e-12) == -1 + assert Accuracy.compare_with_tolerance(5 + 1e-11, 5, 1e-12, 1e-12) == 1 + assert Accuracy.compare_with_tolerance(5 - 1e-11, 5, 1e-12, 1e-12) == -1 + assert Accuracy.compare_with_tolerance(5, 5, 1e-11, 1e-11) == 0 From 76f248f6a7158bf21223ac881245827f2b77119e Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:33:06 +0100 Subject: [PATCH 70/76] fix: library imports --- src/ansys/geometry/core/connection/conversions.py | 12 ++++++++---- src/ansys/geometry/core/designer/edge.py | 3 ++- src/ansys/geometry/core/designer/face.py | 6 ++++-- src/ansys/geometry/core/math/matrix.py | 2 +- src/ansys/geometry/core/misc/checks.py | 2 +- src/ansys/geometry/core/shapes/curves/circle.py | 15 ++++++--------- src/ansys/geometry/core/shapes/curves/curve.py | 3 ++- src/ansys/geometry/core/shapes/curves/ellipse.py | 15 ++++++--------- src/ansys/geometry/core/shapes/curves/line.py | 4 +++- .../geometry/core/shapes/curves/trimmed_curve.py | 2 +- src/ansys/geometry/core/shapes/surfaces/cone.py | 14 +++++--------- .../geometry/core/shapes/surfaces/cylinder.py | 14 +++++--------- src/ansys/geometry/core/shapes/surfaces/plane.py | 12 ++++-------- src/ansys/geometry/core/shapes/surfaces/sphere.py | 14 +++++--------- .../geometry/core/shapes/surfaces/surface.py | 3 ++- .../core/shapes/surfaces/surface_evaluation.py | 3 ++- src/ansys/geometry/core/shapes/surfaces/torus.py | 14 +++++--------- .../core/shapes/surfaces/trimmed_surface.py | 2 +- src/ansys/geometry/core/sketch/circle.py | 5 +++-- src/ansys/geometry/core/sketch/ellipse.py | 10 +++++++--- src/ansys/geometry/core/sketch/segment.py | 9 ++++++--- src/ansys/geometry/core/tools/problem_areas.py | 4 ++-- src/ansys/geometry/core/tools/repair_tools.py | 2 +- 23 files changed, 82 insertions(+), 88 deletions(-) diff --git a/src/ansys/geometry/core/connection/conversions.py b/src/ansys/geometry/core/connection/conversions.py index 9828c70a02..cda75e9a9f 100644 --- a/src/ansys/geometry/core/connection/conversions.py +++ b/src/ansys/geometry/core/connection/conversions.py @@ -38,8 +38,12 @@ from ansys.api.geometry.v0.models_pb2 import TrimmedCurve as GRPCTrimmedCurve from beartype.typing import TYPE_CHECKING, List, Optional, Tuple -from ansys.geometry.core.math import Frame, Matrix44, Plane, Point2D, Point3D, UnitVector3D -from ansys.geometry.core.misc import DEFAULT_UNITS +from ansys.geometry.core.math.frame import Frame +from ansys.geometry.core.math.matrix import Matrix44 +from ansys.geometry.core.math.plane import Plane +from ansys.geometry.core.math.point import Point2D, Point3D +from ansys.geometry.core.math.vector import UnitVector3D +from ansys.geometry.core.misc.measurements import DEFAULT_UNITS from ansys.geometry.core.shapes.curves.circle import Circle from ansys.geometry.core.shapes.curves.curve import Curve from ansys.geometry.core.shapes.curves.ellipse import Ellipse @@ -61,7 +65,7 @@ if TYPE_CHECKING: # pragma: no cover from pyvista import PolyData - from ansys.geometry.core.designer import SurfaceType + from ansys.geometry.core.designer.face import SurfaceType from ansys.geometry.core.shapes.curves.trimmed_curve import TrimmedCurve @@ -459,7 +463,7 @@ def grpc_surface_to_surface(surface: GRPCSurface, surface_type: "SurfaceType") - Surface Resulting converted surface. """ - from ansys.geometry.core.designer import SurfaceType + from ansys.geometry.core.designer.face import SurfaceType origin = Point3D( [surface.origin.x, surface.origin.y, surface.origin.z], DEFAULT_UNITS.SERVER_LENGTH diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 6386331e33..95cc2b6349 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -28,7 +28,8 @@ from beartype.typing import TYPE_CHECKING, List from pint import Quantity -from ansys.geometry.core.connection import GrpcClient, grpc_curve_to_curve +from ansys.geometry.core.connection.client import GrpcClient +from ansys.geometry.core.connection.conversions import grpc_curve_to_curve from ansys.geometry.core.errors import protect_grpc from ansys.geometry.core.math.point import Point3D from ansys.geometry.core.misc.checks import ensure_design_is_active diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index f05b7c4d7d..740056212d 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -31,10 +31,12 @@ from beartype.typing import TYPE_CHECKING, List from pint import Quantity -from ansys.geometry.core.connection import GrpcClient, grpc_curve_to_curve, grpc_surface_to_surface +from ansys.geometry.core.connection.client import GrpcClient +from ansys.geometry.core.connection.conversions import grpc_curve_to_curve, grpc_surface_to_surface from ansys.geometry.core.designer.edge import Edge from ansys.geometry.core.errors import protect_grpc -from ansys.geometry.core.math import Point3D, UnitVector3D +from ansys.geometry.core.math.point import Point3D +from ansys.geometry.core.math.vector import UnitVector3D from ansys.geometry.core.misc.checks import ensure_design_is_active from ansys.geometry.core.misc.measurements import DEFAULT_UNITS from ansys.geometry.core.shapes.curves.trimmed_curve import TrimmedCurve diff --git a/src/ansys/geometry/core/math/matrix.py b/src/ansys/geometry/core/math/matrix.py index 2d3145b420..4a7ad1921e 100644 --- a/src/ansys/geometry/core/math/matrix.py +++ b/src/ansys/geometry/core/math/matrix.py @@ -24,7 +24,7 @@ from beartype.typing import Optional, Union import numpy as np -from ansys.geometry.core.misc import check_ndarray_is_float_int +from ansys.geometry.core.misc.checks import check_ndarray_is_float_int from ansys.geometry.core.typing import Real, RealSequence DEFAULT_MATRIX33 = np.identity(3) diff --git a/src/ansys/geometry/core/misc/checks.py b/src/ansys/geometry/core/misc/checks.py index 65ebd409e6..f9737f43b8 100644 --- a/src/ansys/geometry/core/misc/checks.py +++ b/src/ansys/geometry/core/misc/checks.py @@ -26,7 +26,7 @@ import semver if TYPE_CHECKING: # pragma: no cover - from ansys.geometry.core.designer import Design + from ansys.geometry.core.designer.design import Design def ensure_design_is_active(method): diff --git a/src/ansys/geometry/core/shapes/curves/circle.py b/src/ansys/geometry/core/shapes/curves/circle.py index 09adaa7686..81b1a2c235 100644 --- a/src/ansys/geometry/core/shapes/curves/circle.py +++ b/src/ansys/geometry/core/shapes/curves/circle.py @@ -27,15 +27,12 @@ import numpy as np from pint import Quantity -from ansys.geometry.core.math import ( - UNITVECTOR3D_X, - UNITVECTOR3D_Z, - Matrix44, - Point3D, - UnitVector3D, - Vector3D, -) -from ansys.geometry.core.misc import Accuracy, Distance +from ansys.geometry.core.math.constants import UNITVECTOR3D_X, UNITVECTOR3D_Z +from ansys.geometry.core.math.matrix import Matrix44 +from ansys.geometry.core.math.point import Point3D +from ansys.geometry.core.math.vector import UnitVector3D, Vector3D +from ansys.geometry.core.misc.accuracy import Accuracy +from ansys.geometry.core.misc.measurements import Distance from ansys.geometry.core.shapes.curves.curve import Curve from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation from ansys.geometry.core.shapes.parameterization import ( diff --git a/src/ansys/geometry/core/shapes/curves/curve.py b/src/ansys/geometry/core/shapes/curves/curve.py index cda8583b0a..efed569628 100644 --- a/src/ansys/geometry/core/shapes/curves/curve.py +++ b/src/ansys/geometry/core/shapes/curves/curve.py @@ -22,7 +22,8 @@ """Provides the ``Curve`` class.""" from abc import ABC, abstractmethod -from ansys.geometry.core.math import Matrix44, Point3D +from ansys.geometry.core.math.matrix import Matrix44 +from ansys.geometry.core.math.point import Point3D from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation from ansys.geometry.core.shapes.parameterization import Parameterization from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/shapes/curves/ellipse.py b/src/ansys/geometry/core/shapes/curves/ellipse.py index 27684c5670..ecd4d9fb85 100644 --- a/src/ansys/geometry/core/shapes/curves/ellipse.py +++ b/src/ansys/geometry/core/shapes/curves/ellipse.py @@ -29,15 +29,12 @@ from pint import Quantity from scipy.integrate import quad -from ansys.geometry.core.math import ( - UNITVECTOR3D_X, - UNITVECTOR3D_Z, - Matrix44, - Point3D, - UnitVector3D, - Vector3D, -) -from ansys.geometry.core.misc import Accuracy, Distance +from ansys.geometry.core.math.constants import UNITVECTOR3D_X, UNITVECTOR3D_Z +from ansys.geometry.core.math.matrix import Matrix44 +from ansys.geometry.core.math.point import Point3D +from ansys.geometry.core.math.vector import UnitVector3D, Vector3D +from ansys.geometry.core.misc.accuracy import Accuracy +from ansys.geometry.core.misc.measurements import Distance from ansys.geometry.core.shapes.curves.curve import Curve from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation from ansys.geometry.core.shapes.parameterization import ( diff --git a/src/ansys/geometry/core/shapes/curves/line.py b/src/ansys/geometry/core/shapes/curves/line.py index ad95244e6c..da29b91c18 100644 --- a/src/ansys/geometry/core/shapes/curves/line.py +++ b/src/ansys/geometry/core/shapes/curves/line.py @@ -28,7 +28,9 @@ from beartype.typing import Union import numpy as np -from ansys.geometry.core.math import Matrix44, Point3D, UnitVector3D, Vector3D +from ansys.geometry.core.math.matrix import Matrix44 +from ansys.geometry.core.math.point import Point3D +from ansys.geometry.core.math.vector import UnitVector3D, Vector3D from ansys.geometry.core.misc.accuracy import LENGTH_ACCURACY from ansys.geometry.core.shapes.curves.curve import Curve from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation diff --git a/src/ansys/geometry/core/shapes/curves/trimmed_curve.py b/src/ansys/geometry/core/shapes/curves/trimmed_curve.py index ff3d81b429..7852f8bceb 100644 --- a/src/ansys/geometry/core/shapes/curves/trimmed_curve.py +++ b/src/ansys/geometry/core/shapes/curves/trimmed_curve.py @@ -28,7 +28,7 @@ from ansys.geometry.core.connection.client import GrpcClient from ansys.geometry.core.connection.conversions import trimmed_curve_to_grpc_trimmed_curve from ansys.geometry.core.errors import protect_grpc -from ansys.geometry.core.math import Point3D +from ansys.geometry.core.math.point import Point3D from ansys.geometry.core.shapes.curves.curve import Curve from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation from ansys.geometry.core.shapes.parameterization import Interval diff --git a/src/ansys/geometry/core/shapes/surfaces/cone.py b/src/ansys/geometry/core/shapes/surfaces/cone.py index d757b066b2..63e5df5877 100644 --- a/src/ansys/geometry/core/shapes/surfaces/cone.py +++ b/src/ansys/geometry/core/shapes/surfaces/cone.py @@ -28,15 +28,11 @@ import numpy as np from pint import Quantity -from ansys.geometry.core.math import ( - UNITVECTOR3D_X, - UNITVECTOR3D_Z, - Matrix44, - Point3D, - UnitVector3D, - Vector3D, -) -from ansys.geometry.core.misc import Angle, Distance +from ansys.geometry.core.math.constants import UNITVECTOR3D_X, UNITVECTOR3D_Z +from ansys.geometry.core.math.matrix import Matrix44 +from ansys.geometry.core.math.point import Point3D +from ansys.geometry.core.math.vector import UnitVector3D, Vector3D +from ansys.geometry.core.misc.measurements import Angle, Distance from ansys.geometry.core.shapes.curves.line import Line from ansys.geometry.core.shapes.parameterization import ( Interval, diff --git a/src/ansys/geometry/core/shapes/surfaces/cylinder.py b/src/ansys/geometry/core/shapes/surfaces/cylinder.py index 226ceb198f..1d40f43f8c 100644 --- a/src/ansys/geometry/core/shapes/surfaces/cylinder.py +++ b/src/ansys/geometry/core/shapes/surfaces/cylinder.py @@ -28,15 +28,11 @@ import numpy as np from pint import Quantity -from ansys.geometry.core.math import ( - UNITVECTOR3D_X, - UNITVECTOR3D_Z, - Matrix44, - Point3D, - UnitVector3D, - Vector3D, -) -from ansys.geometry.core.misc import Distance +from ansys.geometry.core.math.constants import UNITVECTOR3D_X, UNITVECTOR3D_Z +from ansys.geometry.core.math.matrix import Matrix44 +from ansys.geometry.core.math.point import Point3D +from ansys.geometry.core.math.vector import UnitVector3D, Vector3D +from ansys.geometry.core.misc.measurements import Distance from ansys.geometry.core.shapes.curves.circle import Circle from ansys.geometry.core.shapes.curves.line import Line from ansys.geometry.core.shapes.parameterization import ( diff --git a/src/ansys/geometry/core/shapes/surfaces/plane.py b/src/ansys/geometry/core/shapes/surfaces/plane.py index e740ea9560..a5d08b7dc8 100644 --- a/src/ansys/geometry/core/shapes/surfaces/plane.py +++ b/src/ansys/geometry/core/shapes/surfaces/plane.py @@ -26,14 +26,10 @@ from beartype.typing import Tuple, Union import numpy as np -from ansys.geometry.core.math import ( - UNITVECTOR3D_X, - UNITVECTOR3D_Z, - Matrix44, - Point3D, - UnitVector3D, - Vector3D, -) +from ansys.geometry.core.math.constants import UNITVECTOR3D_X, UNITVECTOR3D_Z +from ansys.geometry.core.math.matrix import Matrix44 +from ansys.geometry.core.math.point import Point3D +from ansys.geometry.core.math.vector import UnitVector3D, Vector3D from ansys.geometry.core.shapes.parameterization import ( Interval, Parameterization, diff --git a/src/ansys/geometry/core/shapes/surfaces/sphere.py b/src/ansys/geometry/core/shapes/surfaces/sphere.py index a889333aee..8be18cccaa 100644 --- a/src/ansys/geometry/core/shapes/surfaces/sphere.py +++ b/src/ansys/geometry/core/shapes/surfaces/sphere.py @@ -28,15 +28,11 @@ import numpy as np from pint import Quantity -from ansys.geometry.core.math import ( - UNITVECTOR3D_X, - UNITVECTOR3D_Z, - Matrix44, - Point3D, - UnitVector3D, - Vector3D, -) -from ansys.geometry.core.misc import Distance +from ansys.geometry.core.math.constants import UNITVECTOR3D_X, UNITVECTOR3D_Z +from ansys.geometry.core.math.matrix import Matrix44 +from ansys.geometry.core.math.point import Point3D +from ansys.geometry.core.math.vector import UnitVector3D, Vector3D +from ansys.geometry.core.misc.measurements import Distance from ansys.geometry.core.shapes.parameterization import ( Interval, Parameterization, diff --git a/src/ansys/geometry/core/shapes/surfaces/surface.py b/src/ansys/geometry/core/shapes/surfaces/surface.py index 6715aab96f..51ad35b598 100644 --- a/src/ansys/geometry/core/shapes/surfaces/surface.py +++ b/src/ansys/geometry/core/shapes/surfaces/surface.py @@ -24,7 +24,8 @@ from beartype.typing import Tuple -from ansys.geometry.core.math import Matrix44, Point3D +from ansys.geometry.core.math.matrix import Matrix44 +from ansys.geometry.core.math.point import Point3D from ansys.geometry.core.shapes.parameterization import Parameterization, ParamUV from ansys.geometry.core.shapes.surfaces.surface_evaluation import SurfaceEvaluation diff --git a/src/ansys/geometry/core/shapes/surfaces/surface_evaluation.py b/src/ansys/geometry/core/shapes/surfaces/surface_evaluation.py index 6ab8cbf8c1..833828031a 100644 --- a/src/ansys/geometry/core/shapes/surfaces/surface_evaluation.py +++ b/src/ansys/geometry/core/shapes/surfaces/surface_evaluation.py @@ -23,7 +23,8 @@ from functools import cached_property -from ansys.geometry.core.math import Point3D, UnitVector3D, Vector3D +from ansys.geometry.core.math.point import Point3D +from ansys.geometry.core.math.vector import UnitVector3D, Vector3D from ansys.geometry.core.shapes.parameterization import ParamUV from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/shapes/surfaces/torus.py b/src/ansys/geometry/core/shapes/surfaces/torus.py index ccfd99abe8..58dc7ec80b 100644 --- a/src/ansys/geometry/core/shapes/surfaces/torus.py +++ b/src/ansys/geometry/core/shapes/surfaces/torus.py @@ -29,15 +29,11 @@ import numpy as np from pint import Quantity -from ansys.geometry.core.math import ( - UNITVECTOR3D_X, - UNITVECTOR3D_Z, - Matrix44, - Point3D, - UnitVector3D, - Vector3D, -) -from ansys.geometry.core.misc import Distance +from ansys.geometry.core.math.constants import UNITVECTOR3D_X, UNITVECTOR3D_Z +from ansys.geometry.core.math.matrix import Matrix44 +from ansys.geometry.core.math.point import Point3D +from ansys.geometry.core.math.vector import UnitVector3D, Vector3D +from ansys.geometry.core.misc.measurements import Distance from ansys.geometry.core.shapes.parameterization import ( Interval, Parameterization, diff --git a/src/ansys/geometry/core/shapes/surfaces/trimmed_surface.py b/src/ansys/geometry/core/shapes/surfaces/trimmed_surface.py index f954436673..66978e0b4e 100644 --- a/src/ansys/geometry/core/shapes/surfaces/trimmed_surface.py +++ b/src/ansys/geometry/core/shapes/surfaces/trimmed_surface.py @@ -23,7 +23,7 @@ from beartype.typing import TYPE_CHECKING -from ansys.geometry.core.math import Point3D +from ansys.geometry.core.math.point import Point3D from ansys.geometry.core.math.vector import UnitVector3D from ansys.geometry.core.shapes.box_uv import BoxUV from ansys.geometry.core.shapes.parameterization import Interval, ParamUV diff --git a/src/ansys/geometry/core/sketch/circle.py b/src/ansys/geometry/core/sketch/circle.py index d5e826690c..dbe6428197 100644 --- a/src/ansys/geometry/core/sketch/circle.py +++ b/src/ansys/geometry/core/sketch/circle.py @@ -26,8 +26,9 @@ from pint import Quantity import pyvista as pv -from ansys.geometry.core.math import Plane, Point2D, Point3D -from ansys.geometry.core.misc import DEFAULT_UNITS, Distance +from ansys.geometry.core.math.plane import Plane +from ansys.geometry.core.math.point import Point2D, Point3D +from ansys.geometry.core.misc.measurements import DEFAULT_UNITS, Distance from ansys.geometry.core.shapes.curves.circle import Circle from ansys.geometry.core.sketch.face import SketchFace from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/sketch/ellipse.py b/src/ansys/geometry/core/sketch/ellipse.py index 203a28c4ea..94899cfc78 100644 --- a/src/ansys/geometry/core/sketch/ellipse.py +++ b/src/ansys/geometry/core/sketch/ellipse.py @@ -28,9 +28,13 @@ import pyvista as pv from scipy.spatial.transform import Rotation as spatial_rotation -from ansys.geometry.core.math import Matrix33, Matrix44, Plane, Point2D, Point3D, Vector3D -from ansys.geometry.core.misc import DEFAULT_UNITS, UNITS, Angle, Distance -from ansys.geometry.core.shapes import Ellipse +from ansys.geometry.core.math.matrix import Matrix33, Matrix44 +from ansys.geometry.core.math.plane import Plane +from ansys.geometry.core.math.point import Point2D, Point3D +from ansys.geometry.core.math.vector import Vector3D +from ansys.geometry.core.misc.measurements import DEFAULT_UNITS, Angle, Distance +from ansys.geometry.core.misc.units import UNITS +from ansys.geometry.core.shapes.curves.ellipse import Ellipse from ansys.geometry.core.sketch.face import SketchFace from ansys.geometry.core.typing import Real diff --git a/src/ansys/geometry/core/sketch/segment.py b/src/ansys/geometry/core/sketch/segment.py index 2cb36e6226..236714881f 100644 --- a/src/ansys/geometry/core/sketch/segment.py +++ b/src/ansys/geometry/core/sketch/segment.py @@ -26,9 +26,12 @@ from pint import Quantity import pyvista as pv -from ansys.geometry.core.math import Plane, Point2D, Point3D, UnitVector3D -from ansys.geometry.core.misc import DEFAULT_UNITS, check_ndarray_is_all_nan -from ansys.geometry.core.shapes import Line +from ansys.geometry.core.math.plane import Plane +from ansys.geometry.core.math.point import Point2D, Point3D +from ansys.geometry.core.math.vector import UnitVector3D +from ansys.geometry.core.misc.checks import check_ndarray_is_all_nan +from ansys.geometry.core.misc.measurements import DEFAULT_UNITS +from ansys.geometry.core.shapes.curves.line import Line from ansys.geometry.core.sketch.edge import SketchEdge diff --git a/src/ansys/geometry/core/tools/problem_areas.py b/src/ansys/geometry/core/tools/problem_areas.py index bf449b6857..a38746cacd 100644 --- a/src/ansys/geometry/core/tools/problem_areas.py +++ b/src/ansys/geometry/core/tools/problem_areas.py @@ -35,12 +35,12 @@ from google.protobuf.wrappers_pb2 import Int32Value from ansys.geometry.core.connection import GrpcClient -from ansys.geometry.core.misc import ( - check_type_all_elements_in_iterable, +from ansys.geometry.core.misc.auxiliary import ( get_design_from_body, get_design_from_edge, get_design_from_face, ) +from ansys.geometry.core.misc.checks import check_type_all_elements_in_iterable from ansys.geometry.core.tools.repair_tool_message import RepairToolMessage if TYPE_CHECKING: # pragma: no cover diff --git a/src/ansys/geometry/core/tools/repair_tools.py b/src/ansys/geometry/core/tools/repair_tools.py index 113de6282e..c2fbc47b3c 100644 --- a/src/ansys/geometry/core/tools/repair_tools.py +++ b/src/ansys/geometry/core/tools/repair_tools.py @@ -35,7 +35,7 @@ from google.protobuf.wrappers_pb2 import DoubleValue from ansys.geometry.core.connection import GrpcClient -from ansys.geometry.core.misc import ( +from ansys.geometry.core.misc.auxiliary import ( get_bodies_from_ids, get_design_from_body, get_edges_from_ids, From 7c2a6e6eff74c5304fcc2729f23f7b14af7cb9c4 Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:41:18 +0100 Subject: [PATCH 71/76] fix: various old primitives references --- doc/source/user_guide/index.rst | 4 ++-- doc/source/user_guide/primitives.rst | 6 ++++-- src/ansys/geometry/core/shapes/curves/circle.py | 2 +- src/ansys/geometry/core/shapes/curves/ellipse.py | 2 +- src/ansys/geometry/core/shapes/surfaces/cone.py | 2 +- src/ansys/geometry/core/shapes/surfaces/cylinder.py | 2 +- src/ansys/geometry/core/shapes/surfaces/plane.py | 2 +- src/ansys/geometry/core/shapes/surfaces/sphere.py | 2 +- src/ansys/geometry/core/shapes/surfaces/torus.py | 2 +- 9 files changed, 13 insertions(+), 11 deletions(-) diff --git a/doc/source/user_guide/index.rst b/doc/source/user_guide/index.rst index 7dbd7da82d..0b9393bbe2 100644 --- a/doc/source/user_guide/index.rst +++ b/doc/source/user_guide/index.rst @@ -53,8 +53,8 @@ Create geometry model --------------------- Once an instance has started, you can create a -geometry model by initializing the :ref:`Sketch ` subpackage and using the -:ref:`Primitives ` subpackage. +geometry model by initializing the :ref:`sketch ` subpackage and using the +:ref:`shapes ` subpackage. .. code:: python diff --git a/doc/source/user_guide/primitives.rst b/doc/source/user_guide/primitives.rst index 446bdaea27..75624c5871 100644 --- a/doc/source/user_guide/primitives.rst +++ b/doc/source/user_guide/primitives.rst @@ -3,11 +3,13 @@ Primitives ********** -The PyAnsys Geometry :class:`primitives ` subpackage consists +The PyAnsys Geometry :class:`math ` subpackage consists of primitive representations of basic geometric objects, such as a point, vector, and matrix. To operate and manipulate physical quantities, this subpackage uses `Pint `_, a third-party open source software -that other PyAnsys libraries also use. +that other PyAnsys libraries also use. It also uses its :class:`shapes ` +subpackage to evaluate and represent geometric shapes (both curves and surfaces), +such as lines, circles, cones, spheres and torus. This table shows PyAnsys Geometry names and base values for the physical quantities: diff --git a/src/ansys/geometry/core/shapes/curves/circle.py b/src/ansys/geometry/core/shapes/curves/circle.py index 81b1a2c235..91ff1aae98 100644 --- a/src/ansys/geometry/core/shapes/curves/circle.py +++ b/src/ansys/geometry/core/shapes/curves/circle.py @@ -256,7 +256,7 @@ class CircleEvaluation(CurveEvaluation): Parameters ---------- - circle: ~ansys.geometry.core.primitives.circle.Circle + circle: ~ansys.geometry.core.shapes.curves.circle.Circle Circle to evaluate. parameter: Real Parameter to evaluate the circle at. diff --git a/src/ansys/geometry/core/shapes/curves/ellipse.py b/src/ansys/geometry/core/shapes/curves/ellipse.py index ecd4d9fb85..5558a62019 100644 --- a/src/ansys/geometry/core/shapes/curves/ellipse.py +++ b/src/ansys/geometry/core/shapes/curves/ellipse.py @@ -317,7 +317,7 @@ class EllipseEvaluation(CurveEvaluation): Parameters ---------- - ellipse: ~ansys.geometry.core.primitives.ellipse.Ellipse + ellipse: ~ansys.geometry.core.shapes.curves.ellipse.Ellipse Ellipse to evaluate. parameter: float, int Parameter to evaluate the ellipse at. diff --git a/src/ansys/geometry/core/shapes/surfaces/cone.py b/src/ansys/geometry/core/shapes/surfaces/cone.py index 63e5df5877..eac0f01b72 100644 --- a/src/ansys/geometry/core/shapes/surfaces/cone.py +++ b/src/ansys/geometry/core/shapes/surfaces/cone.py @@ -273,7 +273,7 @@ class ConeEvaluation(SurfaceEvaluation): Parameters ---------- - cone: ~ansys.geometry.core.primitives.cone.Cone + cone: ~ansys.geometry.core.shapes.surfaces.cone.Cone Cone to evaluate. parameter: ParamUV Pparameters (u, v) to evaluate the cone at. diff --git a/src/ansys/geometry/core/shapes/surfaces/cylinder.py b/src/ansys/geometry/core/shapes/surfaces/cylinder.py index 1d40f43f8c..c062e18246 100644 --- a/src/ansys/geometry/core/shapes/surfaces/cylinder.py +++ b/src/ansys/geometry/core/shapes/surfaces/cylinder.py @@ -280,7 +280,7 @@ class CylinderEvaluation(SurfaceEvaluation): Parameters ---------- - cylinder: ~ansys.geometry.core.primitives.cylinder.Cylinder + cylinder: ~ansys.geometry.core.shapes.surfaces.cylinder.Cylinder Cylinder to evaluate. parameter: ParamUV Parameters (u, v) to evaluate the cylinder at. diff --git a/src/ansys/geometry/core/shapes/surfaces/plane.py b/src/ansys/geometry/core/shapes/surfaces/plane.py index a5d08b7dc8..e251ed1664 100644 --- a/src/ansys/geometry/core/shapes/surfaces/plane.py +++ b/src/ansys/geometry/core/shapes/surfaces/plane.py @@ -145,7 +145,7 @@ class PlaneEvaluation(SurfaceEvaluation): Parameters ---------- - plane: ~ansys.geometry.core.primitives.plane.Plane + plane: ~ansys.geometry.core.shapes.surfaces.plane.PlaneSurface Plane to evaluate. parameter: ParamUV Parameters (u, v) to evaluate the plane at. diff --git a/src/ansys/geometry/core/shapes/surfaces/sphere.py b/src/ansys/geometry/core/shapes/surfaces/sphere.py index 8be18cccaa..0cca33d4a9 100644 --- a/src/ansys/geometry/core/shapes/surfaces/sphere.py +++ b/src/ansys/geometry/core/shapes/surfaces/sphere.py @@ -238,7 +238,7 @@ class SphereEvaluation(SurfaceEvaluation): Parameters ---------- - sphere: ~ansys.geometry.core.primitives.sphere.Sphere + sphere: ~ansys.geometry.core.shapes.surfaces.sphere.Sphere Sphere to evaluate. parameter: ParamUV Parameters (u, v) to evaluate the sphere at. diff --git a/src/ansys/geometry/core/shapes/surfaces/torus.py b/src/ansys/geometry/core/shapes/surfaces/torus.py index 58dc7ec80b..7ef5096c29 100644 --- a/src/ansys/geometry/core/shapes/surfaces/torus.py +++ b/src/ansys/geometry/core/shapes/surfaces/torus.py @@ -268,7 +268,7 @@ class TorusEvaluation(SurfaceEvaluation): Parameters ---------- - Torus: ~ansys.geometry.core.primitives.torus.Torus + Torus: ~ansys.geometry.core.shapes.surfaces.torus.Torus Torust to evaluate. parameter: ParamUV Parameters (u, v) to evaluate the torus at. From 2470125f3773ac829be726c1d7834c6d91de68d8 Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:00:25 +0100 Subject: [PATCH 72/76] fix: no circular import on face module --- src/ansys/geometry/core/designer/face.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index 740056212d..2e87bc2bd2 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -101,7 +101,7 @@ def __init__( length: Quantity, min_bbox: Point3D, max_bbox: Point3D, - edges: List["Edge"], + edges: List[Edge], ): """Initialize ``FaceLoop`` class.""" self._type = type @@ -131,7 +131,7 @@ def max_bbox(self) -> Point3D: return self._max_bbox @property - def edges(self) -> List["Edge"]: + def edges(self) -> List[Edge]: """Edges contained in the loop.""" return self._edges @@ -229,7 +229,7 @@ def area(self) -> Quantity: @property @protect_grpc @ensure_design_is_active - def edges(self) -> List["Edge"]: + def edges(self) -> List[Edge]: """List of all edges of the face.""" self._grpc_client.log.debug("Requesting face edges from server.") edges_response = self._faces_stub.GetEdges(self._grpc_id) @@ -329,7 +329,7 @@ def point(self, u: float = 0.5, v: float = 0.5) -> Point3D: """ return self.shape.evaluate_proportion(u, v).position - def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List["Edge"]: + def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List[Edge]: """ Transform a list of gRPC edge messages into actual ``Edge`` objects. From a222feb4125e8178a1635b102651fa6b0151001a Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:02:33 +0100 Subject: [PATCH 73/76] fix: typo --- src/ansys/geometry/core/shapes/curves/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/shapes/curves/__init__.py b/src/ansys/geometry/core/shapes/curves/__init__.py index a0b8e02f4f..ee2e523fd8 100644 --- a/src/ansys/geometry/core/shapes/curves/__init__.py +++ b/src/ansys/geometry/core/shapes/curves/__init__.py @@ -19,7 +19,7 @@ # 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 the PyAnsys Geometry ``curve`` subpackage.""" +"""Provides the PyAnsys Geometry ``curves`` subpackage.""" from ansys.geometry.core.shapes.curves.circle import Circle, CircleEvaluation from ansys.geometry.core.shapes.curves.curve import Curve from ansys.geometry.core.shapes.curves.curve_evaluation import CurveEvaluation From 4afe6e9eb01b95e64aaec6e84add521aece9f01c Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:04:44 +0100 Subject: [PATCH 74/76] fix: remove unnecessary TODO - already reported as an issue --- src/ansys/geometry/core/shapes/curves/curve.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/ansys/geometry/core/shapes/curves/curve.py b/src/ansys/geometry/core/shapes/curves/curve.py index efed569628..e15e4eee7f 100644 --- a/src/ansys/geometry/core/shapes/curves/curve.py +++ b/src/ansys/geometry/core/shapes/curves/curve.py @@ -74,10 +74,3 @@ def project_point(self, point: Point3D) -> CurveEvaluation: This method returns the evaluation at the closest point. """ return - - # TODO: Implement more curve methods - # as_spline - # get_length - # get_polyline - # intersect_curve - # is_coincident From 0ec22b29cc12b876c57917a41e229675cb380e6d Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:05:08 +0100 Subject: [PATCH 75/76] feat: adding self_unite and self_intersect --- .../geometry/core/shapes/parameterization.py | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/ansys/geometry/core/shapes/parameterization.py b/src/ansys/geometry/core/shapes/parameterization.py index 9632c6eeeb..e8ab9780cd 100644 --- a/src/ansys/geometry/core/shapes/parameterization.py +++ b/src/ansys/geometry/core/shapes/parameterization.py @@ -288,6 +288,17 @@ def unite(first: "Interval", second: "Interval") -> "Interval": return first return Interval(min(first.start, second.start), max(first.end, second.end)) + def self_unite(self, other: "Interval") -> None: + """ + Get the union of two intervals and update the current interval. + + Parameters + ---------- + other : Interval + Interval to unite with. + """ + self = Interval.unite(self, other) + @staticmethod def intersect(first: "Interval", second: "Interval", tolerance: Real) -> "Interval": """ @@ -312,6 +323,19 @@ def intersect(first: "Interval", second: "Interval", tolerance: Real) -> "Interv return intersection return None # supposed to be empty + def self_intersect(self, other: "Interval", tolerance: Real) -> None: + """ + Get the intersection of two intervals and update the current interval. + + Parameters + ---------- + other : Interval + Interval to intersect with. + tolerance : Real + Accepted range of error given that the interval could be in float values. + """ + self = Interval.intersect(self, other, tolerance) + def contains_value(self, t: Real, accuracy: Real) -> bool: """ Check if the current interval contains the value ``t`` given the accuracy range. @@ -319,8 +343,8 @@ def contains_value(self, t: Real, accuracy: Real) -> bool: Parameters ---------- t : Real - Value of interest - accuracy: Real + Value of interest. + accuracy : Real Accepted range of error given that the interval could be in float values. Returns From de18487ae0c78614798c3bbb8705f576832ca284 Mon Sep 17 00:00:00 2001 From: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:07:28 +0100 Subject: [PATCH 76/76] fix: remove unnecessary todos --- src/ansys/geometry/core/shapes/surfaces/surface.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/ansys/geometry/core/shapes/surfaces/surface.py b/src/ansys/geometry/core/shapes/surfaces/surface.py index 51ad35b598..fae48d4556 100644 --- a/src/ansys/geometry/core/shapes/surfaces/surface.py +++ b/src/ansys/geometry/core/shapes/surfaces/surface.py @@ -75,11 +75,3 @@ def project_point(self, point: Point3D) -> SurfaceEvaluation: This method returns the evaluation at the closest point. """ return - - # TODO: Implement more surface methods - # is_ruled - # is_singular - # get_length - # intersect_curve - # intersect_surface - # is_coincident