From 94ffc46e8a497d94409116b68dc92c51a577455d Mon Sep 17 00:00:00 2001 From: afernand Date: Tue, 26 Sep 2023 11:00:20 +0200 Subject: [PATCH 1/7] feat: Add polydata conversors to edges and faces --- src/ansys/geometry/core/designer/edge.py | 21 +++++++++++++++- src/ansys/geometry/core/designer/face.py | 32 +++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index ffbd8afb87..c5f57c4ece 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -25,11 +25,13 @@ from ansys.api.dbu.v0.dbumodels_pb2 import EntityIdentifier from ansys.api.geometry.v0.edges_pb2_grpc import EdgesStub -from beartype.typing import TYPE_CHECKING, List +from beartype.typing import TYPE_CHECKING, List, Union from pint import Quantity +import pyvista as pv from ansys.geometry.core.connection.client import GrpcClient from ansys.geometry.core.errors import protect_grpc +from ansys.geometry.core.logger import LOG from ansys.geometry.core.math.point import Point3D from ansys.geometry.core.misc.measurements import DEFAULT_UNITS @@ -127,3 +129,20 @@ def end_point(self) -> Point3D: self._grpc_client.log.debug("Requesting edge points from server.") point = self._edges_stub.GetStartAndEndPoints(self._grpc_id).end return Point3D([point.x, point.y, point.z]) + + def to_polydata(self) -> Union[pv.PolyData, None]: + """ + Return the edge as polydata. + + This is useful to represent the edge in a PyVista plotter. + + Returns + ------- + Union[pv.PolyData, None] + Edge as polydata + """ + if self._curve_type == CurveType.CURVETYPE_UNKNOWN or CurveType.CURVETYPE_LINE: + return pv.Line(pointa=self.start_point(), pointb=self.end_point) + else: + LOG.warning("Non linear edges not supported.") + return None diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index 64bd5a6014..b42ac0f9d9 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -28,12 +28,14 @@ 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 beartype.typing import TYPE_CHECKING, List +from beartype.typing import TYPE_CHECKING, List, Union from pint import Quantity +import pyvista as pv from ansys.geometry.core.connection.client import GrpcClient from ansys.geometry.core.designer.edge import CurveType, Edge from ansys.geometry.core.errors import protect_grpc +from ansys.geometry.core.logger import LOG from ansys.geometry.core.math.point import Point3D from ansys.geometry.core.math.vector import UnitVector3D from ansys.geometry.core.misc.measurements import DEFAULT_UNITS @@ -308,3 +310,31 @@ def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List[Edge]: Edge(edge_grpc.id, CurveType(edge_grpc.curve_type), self._body, self._grpc_client) ) return edges + + def to_polydata(self) -> Union[pv.PolyData, None]: + """ + Return the face as polydata. + + This is useful to represent the face in a PyVista plotter. + + Returns + ------- + Union[pv.PolyData, None] + Face as polydata + """ + if self.surface_type != SurfaceType.SURFACETYPE_PLANE: + LOG.warning("Only planes surfaces are supported") + return None + else: + # get vertices from edges + vertices = [ + vertice + for edge in self.edges + for vertice in [edge.start_point.flat, edge.end_point.flat] + ] + # TODO remove duplicate vertices + # build the PyVista face + vertices_order = [len(vertices)] + vertices_order.extend(range(len(vertices))) + + return pv.PolyData(vertices, faces=vertices_order, n_faces=1) From dab83c9ac6516f148339e831dcd0e77260d57675 Mon Sep 17 00:00:00 2001 From: afernand Date: Tue, 26 Sep 2023 15:26:27 +0200 Subject: [PATCH 2/7] Add return to selections --- src/ansys/geometry/core/designer/edge.py | 4 ++-- src/ansys/geometry/core/designer/face.py | 2 +- src/ansys/geometry/core/designer/selection.py | 10 ++++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index c5f57c4ece..ed82d64ae3 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -130,7 +130,7 @@ def end_point(self) -> Point3D: point = self._edges_stub.GetStartAndEndPoints(self._grpc_id).end return Point3D([point.x, point.y, point.z]) - def to_polydata(self) -> Union[pv.PolyData, None]: + def _to_polydata(self) -> Union[pv.PolyData, None]: """ Return the edge as polydata. @@ -142,7 +142,7 @@ def to_polydata(self) -> Union[pv.PolyData, None]: Edge as polydata """ if self._curve_type == CurveType.CURVETYPE_UNKNOWN or CurveType.CURVETYPE_LINE: - return pv.Line(pointa=self.start_point(), pointb=self.end_point) + return pv.Line(pointa=self.start_point, pointb=self.end_point) else: LOG.warning("Non linear edges not supported.") return None diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index b42ac0f9d9..cdc8218c08 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -311,7 +311,7 @@ def __grpc_edges_to_edges(self, edges_grpc: List[GRPCEdge]) -> List[Edge]: ) return edges - def to_polydata(self) -> Union[pv.PolyData, None]: + def _to_polydata(self) -> Union[pv.PolyData, None]: """ Return the face as polydata. diff --git a/src/ansys/geometry/core/designer/selection.py b/src/ansys/geometry/core/designer/selection.py index e947f4897f..38bd59ba6a 100644 --- a/src/ansys/geometry/core/designer/selection.py +++ b/src/ansys/geometry/core/designer/selection.py @@ -105,12 +105,22 @@ def __init__( [ids.add(beam.id) for beam in beams] [ids.add(dp.id) for dp in design_points] + self._selections = [bodies, faces, edges, beams, design_points] + + # flatten list + self._selections = [item for sublist in self._selections for item in sublist] + named_selection_request = CreateRequest(name=name, members=ids) self._grpc_client.log.debug("Requesting creation of named selection.") new_named_selection = self._named_selections_stub.Create(named_selection_request) self._id = new_named_selection.id self._name = new_named_selection.name + @property + def selections(self): + """Return all the selected elements.""" + return self._selections + @property def id(self) -> str: """ID of the named selection.""" From f6e5bca96814923c6290c2229d621b84060b2e59 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:36:51 +0000 Subject: [PATCH 3/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/ansys/geometry/core/designer/edge.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 0e35c505ca..db962a5437 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -205,4 +205,3 @@ def _to_polydata(self) -> Union[pv.PolyData, None]: else: LOG.warning("Non linear edges not supported.") return None - From a00e06f7b2f48f622b4cf130bda6148a44c61161 Mon Sep 17 00:00:00 2001 From: afernand Date: Wed, 13 Mar 2024 16:55:32 +0100 Subject: [PATCH 4/7] feat(wip): Add circles and ellipses polydata to edges --- src/ansys/geometry/core/designer/edge.py | 42 +++++++++++++----------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 0e35c505ca..30da492ee2 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -42,6 +42,8 @@ if TYPE_CHECKING: # pragma: no cover from ansys.geometry.core.designer.body import Body from ansys.geometry.core.designer.face import Face + from ansys.geometry.core.shapes.curves.circle import Circle + from ansys.geometry.core.shapes.curves.ellipse import Ellipse @unique @@ -171,24 +173,6 @@ def faces(self) -> List["Face"]: for grpc_face in grpc_faces ] - @property - @protect_grpc - @ensure_design_is_active - def start_point(self) -> Point3D: - """Edge start point.""" - self._grpc_client.log.debug("Requesting edge points from server.") - point = self._edges_stub.GetStartAndEndPoints(self._grpc_id).start - return Point3D([point.x, point.y, point.z]) - - @property - @protect_grpc - @ensure_design_is_active - def end_point(self) -> Point3D: - """Edge end point.""" - self._grpc_client.log.debug("Requesting edge points from server.") - point = self._edges_stub.GetStartAndEndPoints(self._grpc_id).end - return Point3D([point.x, point.y, point.z]) - def _to_polydata(self) -> Union[pv.PolyData, None]: """ Return the edge as polydata. @@ -202,7 +186,27 @@ def _to_polydata(self) -> Union[pv.PolyData, None]: """ if self._curve_type == CurveType.CURVETYPE_UNKNOWN or CurveType.CURVETYPE_LINE: return pv.Line(pointa=self.start_point, pointb=self.end_point) + elif self._curve_type == CurveType.CURVETYPE_CIRCLE: + self.shape.geometry: Circle + point_a = self.shape.geometry.evaluate(0) + point_b = self.shape.geometry.evaluate(1) + half_a = pv.CircularArc( + center=self.shape.geometry.center, + pointa=point_a, + pointb=point_b, + ) + half_b = pv.CircularArc( + center=self.shape.geometry.center, + pointa=point_a, + pointb=point_b, + negative=True, + ) + pv_circle = pv.MultiBlock([half_a, half_b]) + return pv_circle + + elif self._curve_type == CurveType.CURVETYPE_ELLIPSE: + self.shape.geometry: Ellipse + else: LOG.warning("Non linear edges not supported.") return None - From fa807822b22ed349df4b792f3e4d92ef713c4e4c Mon Sep 17 00:00:00 2001 From: afernand Date: Fri, 15 Mar 2024 16:41:41 +0100 Subject: [PATCH 5/7] feat(wip): Circle edges working --- src/ansys/geometry/core/designer/edge.py | 81 +++++++++++++++---- src/ansys/geometry/core/plotting/plotter.py | 5 +- .../geometry/core/plotting/plotter_helper.py | 17 ++-- 3 files changed, 77 insertions(+), 26 deletions(-) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 30da492ee2..8e8c7c1742 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -28,14 +28,17 @@ from beartype.typing import TYPE_CHECKING, List, Union from pint import Quantity import pyvista as pv +from scipy.spatial.transform import Rotation as spatial_rotation 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.logger import LOG +from ansys.geometry.core.math.matrix import Matrix33, Matrix44 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.misc.units import UNITS from ansys.geometry.core.shapes.curves.trimmed_curve import ReversedTrimmedCurve, TrimmedCurve from ansys.geometry.core.shapes.parameterization import Interval @@ -173,7 +176,56 @@ def faces(self) -> List["Face"]: for grpc_face in grpc_faces ] - def _to_polydata(self) -> Union[pv.PolyData, None]: + + def _get_rotation_matrix_ellipse(self, ellipse) -> Matrix44: + """Return the rotation matrix for the edge.""" + rotation = Matrix33( + spatial_rotation.from_euler( + "xyz", [0, 0, self.shape.geometry.angle_offset.value.m_as(UNITS.radian)], degrees=False + ).as_matrix() + ) + transformation_matrix = Matrix44( + [ + [ + rotation[0, 0], + rotation[0, 1], + rotation[0, 2], + self.shape.geometry.origin, + ], + [ + rotation[1, 0], + rotation[1, 1], + rotation[1, 2], + self.center.y.m_as(DEFAULT_UNITS.LENGTH), + ], + [ + rotation[2, 0], + rotation[2, 1], + rotation[2, 2], + 0, + ], + [0, 0, 0, 1], + ] + ) + return transformation_matrix + + @property + @protect_grpc + def start_point(self) -> Point3D: + """Edge start point.""" + self._grpc_client.log.debug("Requesting edge points from server.") + point = self._edges_stub.GetStartAndEndPoints(self._grpc_id).start + return Point3D([point.x, point.y, point.z]) + + @property + @protect_grpc + def end_point(self) -> Point3D: + """Edge end point.""" + self._grpc_client.log.debug("Requesting edge points from server.") + point = self._edges_stub.GetStartAndEndPoints(self._grpc_id).end + return Point3D([point.x, point.y, point.z]) + + def to_polydata(self) -> Union[pv.PolyData, None]: """ Return the edge as polydata. @@ -184,29 +236,28 @@ def _to_polydata(self) -> Union[pv.PolyData, None]: Union[pv.PolyData, None] Edge as polydata """ - if self._curve_type == CurveType.CURVETYPE_UNKNOWN or CurveType.CURVETYPE_LINE: + + if self._curve_type == CurveType.CURVETYPE_UNKNOWN or self._curve_type == CurveType.CURVETYPE_LINE: return pv.Line(pointa=self.start_point, pointb=self.end_point) elif self._curve_type == CurveType.CURVETYPE_CIRCLE: self.shape.geometry: Circle point_a = self.shape.geometry.evaluate(0) - point_b = self.shape.geometry.evaluate(1) - half_a = pv.CircularArc( - center=self.shape.geometry.center, - pointa=point_a, - pointb=point_b, + circle = pv.CircularArc( + center=list(self.shape.geometry.origin), + pointa=list(point_a.position), + pointb=list(point_a.position), + negative=True ) - half_b = pv.CircularArc( - center=self.shape.geometry.center, - pointa=point_a, - pointb=point_b, - negative=True, - ) - pv_circle = pv.MultiBlock([half_a, half_b]) - return pv_circle + return circle elif self._curve_type == CurveType.CURVETYPE_ELLIPSE: self.shape.geometry: Ellipse + pv.Ellipse( + semi_major_axis=float(self.shape.geometry.major_radius) + semi_minor_axis=float(self.shape.geometry.minor_radius) + ).transform(self._get_rotation_matrix(self.shape.geometry)) + return None else: LOG.warning("Non linear edges not supported.") return None diff --git a/src/ansys/geometry/core/plotting/plotter.py b/src/ansys/geometry/core/plotting/plotter.py index c96f4e1688..4318516196 100644 --- a/src/ansys/geometry/core/plotting/plotter.py +++ b/src/ansys/geometry/core/plotting/plotter.py @@ -256,9 +256,10 @@ 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.shape.start, edge.shape.start) + edge_polydata = edge.to_polydata() + edge_actor = self.scene.add_mesh( - line, line_width=10, color=EDGE_COLOR, **plotting_options + edge_polydata, line_width=10, color=EDGE_COLOR, **plotting_options ) edge_actor.SetVisibility(False) edge_plot = EdgePlot(edge_actor, edge, body_plot) diff --git a/src/ansys/geometry/core/plotting/plotter_helper.py b/src/ansys/geometry/core/plotting/plotter_helper.py index b14a5cfca0..804aea4a71 100644 --- a/src/ansys/geometry/core/plotting/plotter_helper.py +++ b/src/ansys/geometry/core/plotting/plotter_helper.py @@ -232,15 +232,14 @@ def compute_edge_object_map(self) -> Dict[pv.Actor, EdgePlot]: for object in self._geom_object_actors_map.values(): # get edges only from bodies geom_obj = object.object - if ( - isinstance(geom_obj, Body) - or isinstance(geom_obj, MasterBody) - or isinstance(geom_obj, Face) - or isinstance(geom_obj, SketchFace) - or isinstance(geom_obj, Sketch) - ): - for edge in object.edges: - self._edge_actors_map[edge.actor] = edge + """ + If ( isinstance(geom_obj, Body) or isinstance(geom_obj, MasterBody) or + isinstance(geom_obj, Face) or isinstance(geom_obj, SketchFace) + + or isinstance(geom_obj, Sketch) ): + """ + for edge in object.edges: + self._edge_actors_map[edge.actor] = edge def enable_picking(self): """Enable picking capabilities in the plotter.""" From 1b61381d04bf3f49f158c7b2105bf2566fead161 Mon Sep 17 00:00:00 2001 From: afernand Date: Mon, 18 Mar 2024 16:28:43 +0100 Subject: [PATCH 6/7] feat(wip): Ellipse edges working --- src/ansys/geometry/core/designer/edge.py | 56 ++++----------------- src/ansys/geometry/core/plotting/plotter.py | 18 ++++--- 2 files changed, 22 insertions(+), 52 deletions(-) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 8e8c7c1742..4a2dbd8774 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -28,17 +28,14 @@ from beartype.typing import TYPE_CHECKING, List, Union from pint import Quantity import pyvista as pv -from scipy.spatial.transform import Rotation as spatial_rotation 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.logger import LOG -from ansys.geometry.core.math.matrix import Matrix33, Matrix44 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.misc.units import UNITS from ansys.geometry.core.shapes.curves.trimmed_curve import ReversedTrimmedCurve, TrimmedCurve from ansys.geometry.core.shapes.parameterization import Interval @@ -176,39 +173,6 @@ def faces(self) -> List["Face"]: for grpc_face in grpc_faces ] - - def _get_rotation_matrix_ellipse(self, ellipse) -> Matrix44: - """Return the rotation matrix for the edge.""" - rotation = Matrix33( - spatial_rotation.from_euler( - "xyz", [0, 0, self.shape.geometry.angle_offset.value.m_as(UNITS.radian)], degrees=False - ).as_matrix() - ) - transformation_matrix = Matrix44( - [ - [ - rotation[0, 0], - rotation[0, 1], - rotation[0, 2], - self.shape.geometry.origin, - ], - [ - rotation[1, 0], - rotation[1, 1], - rotation[1, 2], - self.center.y.m_as(DEFAULT_UNITS.LENGTH), - ], - [ - rotation[2, 0], - rotation[2, 1], - rotation[2, 2], - 0, - ], - [0, 0, 0, 1], - ] - ) - return transformation_matrix - @property @protect_grpc def start_point(self) -> Point3D: @@ -236,8 +200,10 @@ def to_polydata(self) -> Union[pv.PolyData, None]: Union[pv.PolyData, None] Edge as polydata """ - - if self._curve_type == CurveType.CURVETYPE_UNKNOWN or self._curve_type == CurveType.CURVETYPE_LINE: + if ( + self._curve_type == CurveType.CURVETYPE_UNKNOWN + or self._curve_type == CurveType.CURVETYPE_LINE + ): return pv.Line(pointa=self.start_point, pointb=self.end_point) elif self._curve_type == CurveType.CURVETYPE_CIRCLE: self.shape.geometry: Circle @@ -246,18 +212,18 @@ def to_polydata(self) -> Union[pv.PolyData, None]: center=list(self.shape.geometry.origin), pointa=list(point_a.position), pointb=list(point_a.position), - negative=True + negative=True, ) return circle elif self._curve_type == CurveType.CURVETYPE_ELLIPSE: self.shape.geometry: Ellipse - - pv.Ellipse( - semi_major_axis=float(self.shape.geometry.major_radius) - semi_minor_axis=float(self.shape.geometry.minor_radius) - ).transform(self._get_rotation_matrix(self.shape.geometry)) - return None + ellipse = pv.Ellipse( + semi_major_axis=self.shape.geometry.major_radius.magnitude, + semi_minor_axis=self.shape.geometry.minor_radius.magnitude, + ) + ellipse = ellipse.translate(list(self.shape.geometry.origin)) + return ellipse else: LOG.warning("Non linear edges not supported.") return None diff --git a/src/ansys/geometry/core/plotting/plotter.py b/src/ansys/geometry/core/plotting/plotter.py index 4318516196..15f6acb803 100644 --- a/src/ansys/geometry/core/plotting/plotter.py +++ b/src/ansys/geometry/core/plotting/plotter.py @@ -257,13 +257,17 @@ def add_body_edges(self, body_plot: GeomObjectPlot, **plotting_options: Optional edge_plot_list = [] for edge in body_plot.object.edges: edge_polydata = edge.to_polydata() - - edge_actor = self.scene.add_mesh( - edge_polydata, line_width=10, color=EDGE_COLOR, **plotting_options - ) - edge_actor.SetVisibility(False) - edge_plot = EdgePlot(edge_actor, edge, body_plot) - edge_plot_list.append(edge_plot) + if edge_polydata is not None: + edge_actor = self.scene.add_mesh( + edge_polydata, + line_width=10, + color=EDGE_COLOR, + style="wireframe", + **plotting_options, + ) + edge_actor.SetVisibility(False) + edge_plot = EdgePlot(edge_actor, edge, body_plot) + edge_plot_list.append(edge_plot) body_plot.edges = edge_plot_list def add_body( From 2643fd9ebe08bdd59296aa177c6c0dc9040a8e21 Mon Sep 17 00:00:00 2001 From: afernand Date: Tue, 19 Mar 2024 11:44:24 +0100 Subject: [PATCH 7/7] feat(wip): Add surface polydata --- src/ansys/geometry/core/designer/edge.py | 2 +- src/ansys/geometry/core/designer/face.py | 46 +++++++++++++++++++++--- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/ansys/geometry/core/designer/edge.py b/src/ansys/geometry/core/designer/edge.py index 4a2dbd8774..8786a5f226 100644 --- a/src/ansys/geometry/core/designer/edge.py +++ b/src/ansys/geometry/core/designer/edge.py @@ -225,5 +225,5 @@ def to_polydata(self) -> Union[pv.PolyData, None]: ellipse = ellipse.translate(list(self.shape.geometry.origin)) return ellipse else: - LOG.warning("Non linear edges not supported.") + LOG.warning("NURBS and procedural edges not supported.") return None diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index dd74a100e3..e8ea50d638 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -371,10 +371,7 @@ def _to_polydata(self) -> Union[pv.PolyData, None]: Union[pv.PolyData, None] Face as polydata """ - if self.surface_type != SurfaceType.SURFACETYPE_PLANE: - LOG.warning("Only planes surfaces are supported") - return None - else: + if self.surface_type == SurfaceType.SURFACETYPE_PLANE: # get vertices from edges vertices = [ vertice @@ -387,6 +384,47 @@ def _to_polydata(self) -> Union[pv.PolyData, None]: vertices_order.extend(range(len(vertices))) return pv.PolyData(vertices, faces=vertices_order, n_faces=1) + elif self.surface_type == SurfaceType.SURFACETYPE_CYLINDER: + cyl_pl = pv.Cylinder( + center=list(self.shape.geometry.origin), + direction=[ + self.shape.geometry.dir_x, + self.shape.geometry.dir_y, + self.shape.geometry.dir_z, + ], + radius=self.shape.geometry.radius.magnitude, + ) + return cyl_pl + elif self.surface_type == SurfaceType.SURFACETYPE_CONE: + cone_pl = pv.Cone( + center=list(self.shape.geometry.origin), + direction=[ + self.shape.geometry.dir_x, + self.shape.geometry.dir_y, + self.shape.geometry.dir_z, + ], + height=self.shape.geometry.height.magnitude, + radius=self.shape.geometry.radius.magnitude, + angle=self.shape.geometry.half_angle.magnitude, + ) + return cone_pl + elif self.surface_type == SurfaceType.SURFACETYPE_TORUS: + torus_pl = pv.ParametricTorus( + ringradius=self.shape.geometry.major_radius.magnitude, + crosssectionradius=self.shape.geometry.minor_radius.magnitude, + ) + torus_pl.translate(self.shape.geometry.origin) + return torus_pl + + elif self.surface_type == SurfaceType.SURFACETYPE_SPHERE: + sphere_pl = pv.Sphere( + center=list(self.shape.geometry.origin), + radius=self.shape.geometry.radius.magnitude, + ) + return sphere_pl + else: + LOG.warning("Cannot convert non-planar faces to polydata.") + return None def create_isoparametric_curves( self, use_u_param: bool, parameter: float