diff --git a/doc/changelog.d/2412.maintenance.md b/doc/changelog.d/2412.maintenance.md new file mode 100644 index 0000000000..ad0828813d --- /dev/null +++ b/doc/changelog.d/2412.maintenance.md @@ -0,0 +1 @@ +V1 implementation of faces + edges stubs diff --git a/src/ansys/geometry/core/_grpc/_services/v0/conversions.py b/src/ansys/geometry/core/_grpc/_services/v0/conversions.py index 601f564696..f9177d5886 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/conversions.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/conversions.py @@ -184,6 +184,24 @@ def from_unit_vector_to_grpc_direction(unit_vector: "UnitVector3D") -> GRPCDirec return GRPCDirection(x=unit_vector.x, y=unit_vector.y, z=unit_vector.z) +def from_grpc_direction_to_unit_vector(direction: GRPCDirection) -> "UnitVector3D": + """Convert a gRPC direction message to a ``UnitVector3D`` class. + + Parameters + ---------- + direction : GRPCDirection + Source direction data. + + Returns + ------- + UnitVector3D + Converted unit vector. + """ + from ansys.geometry.core.math.vector import UnitVector3D + + return UnitVector3D([direction.x, direction.y, direction.z]) + + def from_line_to_grpc_line(line: "Line") -> GRPCLine: """Convert a ``Line`` to a line gRPC message. diff --git a/src/ansys/geometry/core/_grpc/_services/v0/faces.py b/src/ansys/geometry/core/_grpc/_services/v0/faces.py index aaab06f122..f51ea42635 100644 --- a/src/ansys/geometry/core/_grpc/_services/v0/faces.py +++ b/src/ansys/geometry/core/_grpc/_services/v0/faces.py @@ -35,6 +35,7 @@ from .conversions import ( build_grpc_id, from_grpc_curve_to_curve, + from_grpc_direction_to_unit_vector, from_grpc_point_to_point3d, from_grpc_surface_to_surface, from_line_to_grpc_line, @@ -212,8 +213,6 @@ def set_color(self, **kwargs) -> dict: # noqa: D102 def get_normal(self, **kwargs) -> dict: # noqa: D102 from ansys.api.geometry.v0.faces_pb2 import GetNormalRequest - from ansys.geometry.core.math.vector import UnitVector3D - # Create the request - assumes all inputs are valid and of the proper type request = GetNormalRequest( id=kwargs["id"], @@ -226,9 +225,7 @@ def get_normal(self, **kwargs) -> dict: # noqa: D102 # Return the response - formatted as a dictionary return { - "normal": UnitVector3D( - [response.direction.x, response.direction.y, response.direction.z] - ), + "normal": from_grpc_direction_to_unit_vector(response.direction), } @protect_grpc diff --git a/src/ansys/geometry/core/_grpc/_services/v1/conversions.py b/src/ansys/geometry/core/_grpc/_services/v1/conversions.py index fa81a6c545..61944d450e 100644 --- a/src/ansys/geometry/core/_grpc/_services/v1/conversions.py +++ b/src/ansys/geometry/core/_grpc/_services/v1/conversions.py @@ -35,6 +35,7 @@ Plane as GRPCPlane, Point as GRPCPoint, Polygon as GRPCPolygon, + Quantity as GRPCQuantity, ) from ansys.api.discovery.v1.design.designmessages_pb2 import ( CurveGeometry as GRPCCurveGeometry, @@ -50,6 +51,7 @@ Surface as GRPCSurface, Tessellation as GRPCTessellation, TessellationOptions as GRPCTessellationOptions, + TrackedCommandResponse as GRPCTrackedCommandResponse, TrimmedCurve as GRPCTrimmedCurve, TrimmedSurface as GRPCTrimmedSurface, ) @@ -66,6 +68,7 @@ from ansys.geometry.core.errors import GeometryRuntimeError from ansys.geometry.core.misc.checks import graphics_required +from ansys.geometry.core.misc.measurements import DEFAULT_UNITS from ansys.geometry.core.shapes.surfaces.nurbs import NURBSSurface if TYPE_CHECKING: @@ -81,6 +84,7 @@ 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 Measurement from ansys.geometry.core.misc.options import TessellationOptions from ansys.geometry.core.parameters.parameter import ( Parameter, @@ -175,9 +179,9 @@ def from_point3d_to_grpc_point(point: "Point3D") -> GRPCPoint: from ansys.geometry.core.misc.measurements import DEFAULT_UNITS return GRPCPoint( - x=point.x.m_as(DEFAULT_UNITS.SERVER_LENGTH), - y=point.y.m_as(DEFAULT_UNITS.SERVER_LENGTH), - z=point.z.m_as(DEFAULT_UNITS.SERVER_LENGTH), + x=GRPCQuantity(value_in_geometry_units=point.x.m_as(DEFAULT_UNITS.SERVER_LENGTH)), + y=GRPCQuantity(value_in_geometry_units=point.y.m_as(DEFAULT_UNITS.SERVER_LENGTH)), + z=GRPCQuantity(value_in_geometry_units=point.z.m_as(DEFAULT_UNITS.SERVER_LENGTH)), ) @@ -198,7 +202,11 @@ def from_grpc_point_to_point3d(point: GRPCPoint) -> "Point3D": from ansys.geometry.core.misc.measurements import DEFAULT_UNITS return Point3D( - [point.x, point.y, point.z], + [ + point.x.value_in_geometry_units, + point.y.value_in_geometry_units, + point.z.value_in_geometry_units, + ], DEFAULT_UNITS.SERVER_LENGTH, ) @@ -979,23 +987,26 @@ def from_grpc_curve_to_curve(curve: GRPCCurveGeometry) -> "Curve": Curve Resulting converted curve. """ - from ansys.geometry.core.math.point import Point3D from ansys.geometry.core.math.vector import UnitVector3D from ansys.geometry.core.shapes.curves.circle import Circle from ansys.geometry.core.shapes.curves.ellipse import Ellipse from ansys.geometry.core.shapes.curves.line import Line - origin = Point3D([curve.origin.x, curve.origin.y, curve.origin.z]) + origin = from_grpc_point_to_point3d(curve.origin) try: 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.radius != 0: - result = Circle(origin, curve.radius, reference, axis) - elif curve.major_radius != 0 and curve.minor_radius != 0: - result = Ellipse(origin, curve.major_radius, curve.minor_radius, reference, axis) + + radius = curve.radius.value_in_geometry_units + major_radius = curve.major_radius.value_in_geometry_units + minor_radius = curve.minor_radius.value_in_geometry_units + if radius != 0: + result = Circle(origin, radius, reference, axis) + elif major_radius != 0 and minor_radius != 0: + result = Ellipse(origin, major_radius, minor_radius, reference, axis) elif curve.nurbs_curve.nurbs_data.degree != 0: result = from_grpc_nurbs_curve_to_nurbs_curve(curve.nurbs_curve) elif curve.direction is not None: @@ -1284,6 +1295,56 @@ def from_grpc_matrix_to_matrix(matrix: GRPCMatrix) -> "Matrix44": ) +def from_grpc_direction_to_unit_vector(direction: GRPCDirection) -> "UnitVector3D": + """Convert a gRPC direction to a unit vector. + + Parameters + ---------- + direction : GRPCDirection + Source gRPC direction data. + + Returns + ------- + UnitVector3D + Converted unit vector. + """ + from ansys.geometry.core.math.vector import UnitVector3D + + return UnitVector3D([direction.x, direction.y, direction.z]) + + +def from_length_to_grpc_quantity(input: "Measurement") -> GRPCQuantity: + """Convert a ``Measurement`` containing a length to a gRPC quantity. + + Parameters + ---------- + input : Measurement + Source measurement data. + + Returns + ------- + GRPCQuantity + Converted gRPC quantity. + """ + return GRPCQuantity(value_in_geometry_units=input.value.m_as(DEFAULT_UNITS.SERVER_LENGTH)) + + +def from_angle_to_grpc_quantity(input: "Measurement") -> GRPCQuantity: + """Convert a ``Measurement`` containing an angle to a gRPC quantity. + + Parameters + ---------- + input : Measurement + Source measurement data. + + Returns + ------- + GRPCQuantity + Converted gRPC quantity. + """ + return GRPCQuantity(value_in_geometry_units=input.value.m_as(DEFAULT_UNITS.SERVER_ANGLE)) + + def _nurbs_curves_compatibility(backend_version: "semver.Version", grpc_geometries: GRPCGeometries): """Check if the backend version is compatible with NURBS curves in sketches. @@ -1351,18 +1412,18 @@ def from_enclosure_options_to_grpc_enclosure_options( ) -def serialize_tracker_command_response(**kwargs) -> dict: - """Serialize a TrackerCommandResponse object into a dictionary. +def serialize_tracked_command_response(response: GRPCTrackedCommandResponse) -> dict: + """Serialize a TrackedCommandResponse object into a dictionary. Parameters ---------- - response : TrackerCommandResponse - The gRPC TrackerCommandResponse object to serialize. + response : GRPCTrackedCommandResponse + The gRPC TrackedCommandResponse object to serialize. Returns ------- dict - A dictionary representation of the TrackerCommandResponse object. + A dictionary representation of the TrackedCommandResponse object. """ def serialize_body(body): @@ -1387,17 +1448,17 @@ def serialize_entity_identifier(entity): "id": entity.id, } - response = kwargs["response"] return { - "success": response.success, + "success": getattr(response.command_response, "success", False), "created_bodies": [ - serialize_body(body) for body in getattr(response, "created_bodies", []) + serialize_body(body) for body in getattr(response.tracked_changes, "created_bodies", []) ], "modified_bodies": [ - serialize_body(body) for body in getattr(response, "modified_bodies", []) + serialize_body(body) + for body in getattr(response.tracked_changes, "modified_bodies", []) ], "deleted_bodies": [ serialize_entity_identifier(entity) - for entity in getattr(response, "deleted_bodies", []) + for entity in getattr(response.tracked_changes, "deleted_bodies", []) ], } diff --git a/src/ansys/geometry/core/_grpc/_services/v1/edges.py b/src/ansys/geometry/core/_grpc/_services/v1/edges.py index 507ac6c449..8ecb95d3b5 100644 --- a/src/ansys/geometry/core/_grpc/_services/v1/edges.py +++ b/src/ansys/geometry/core/_grpc/_services/v1/edges.py @@ -21,11 +21,22 @@ # SOFTWARE. """Module containing the edges service implementation for v1.""" +from ansys.api.discovery.v1.commonmessages_pb2 import MultipleEntitiesRequest import grpc from ansys.geometry.core.errors import protect_grpc +from ..base.conversions import to_distance from ..base.edges import GRPCEdgesService +from .conversions import ( + build_grpc_id, + from_grpc_curve_to_curve, + from_grpc_point_to_point3d, + from_length_to_grpc_quantity, + from_point3d_to_grpc_point, + from_unit_vector_to_grpc_direction, + serialize_tracked_command_response, +) class GRPCEdgesServiceV1(GRPCEdgesService): # pragma: no cover @@ -43,54 +54,258 @@ class GRPCEdgesServiceV1(GRPCEdgesService): # pragma: no cover @protect_grpc def __init__(self, channel: grpc.Channel): # noqa: D102 - from ansys.api.geometry.v1.edges_pb2_grpc import EdgesStub + from ansys.api.discovery.v1.design.geometry.edge_pb2_grpc import EdgeStub + from ansys.api.discovery.v1.operations.edit_pb2_grpc import EditStub - self.stub = EdgesStub(channel) + self.stub = EdgeStub(channel) + self.edit_stub = EditStub(channel) @protect_grpc def get_edge(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + from ansys.api.discovery.v1.commonmessages_pb2 import EntityRequest + + # Create the request - assumes all inputs are valid and of the proper type + request = EntityRequest(id=build_grpc_id(kwargs["id"])) + + # Call the gRPC service + response = self.stub.Get(request=request) + + # Return the response - formatted as a dictionary + return { + "id": response.edge.id, + "curve_type": response.edge.curve_type, + "is_reversed": response.edge.is_reversed, + } @protect_grpc def get_curve(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetCurve(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "curve": from_grpc_curve_to_curve(response.curve), + } @protect_grpc def get_start_and_end_points(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetStartAndEndPoints(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "start": from_grpc_point_to_point3d(response.start), + "end": from_grpc_point_to_point3d(response.end), + } @protect_grpc def get_length(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetLength(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "length": to_distance(response.length.value_in_geometry_units), + } @protect_grpc def get_interval(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetInterval(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "start": response.start, + "end": response.end, + } @protect_grpc def get_faces(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetFaces(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "faces": [ + { + "id": face.id, + "surface_type": face.surface_type, + "is_reversed": face.is_reversed, + } + for face in response.faces + ], + } @protect_grpc def get_vertices(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + # Create the request - assumes all inputs are valid and of proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetVertices(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "vertices": [ + { + "id": vertex.id.id, + "position": from_grpc_point_to_point3d(vertex.position), + } + for vertex in response.vertices + ], + } @protect_grpc def get_bounding_box(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetBoundingBox(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "min_corner": from_grpc_point_to_point3d(response.box.min), + "max_corner": from_grpc_point_to_point3d(response.box.max), + "center": from_grpc_point_to_point3d(response.box.center), + } @protect_grpc def extrude_edges(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + ExtrudeEdgesRequest, + ExtrudeEdgesRequestData, + ) + + # Parse some optional arguments + point = from_point3d_to_grpc_point(kwargs["point"]) if kwargs["point"] else None + direction = ( + from_unit_vector_to_grpc_direction(kwargs["direction"]) if kwargs["direction"] else None + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = ExtrudeEdgesRequest( + request_data=[ + ExtrudeEdgesRequestData( + edge_ids=[build_grpc_id(edge_id) for edge_id in kwargs["edge_ids"]], + face_id=build_grpc_id(kwargs["face"]), + point=point, + direction=direction, + distance=from_length_to_grpc_quantity(kwargs["distance"]), + extrude_type=kwargs["extrude_type"].value, + pull_symmetric=kwargs["pull_symmetric"], + copy=kwargs["copy"], + natural_extension=kwargs["natural_extension"], + ) + ] + ) + + # Call the gRPC service and serialize the response + response = self.edit_stub.ExtrudeEdges(request) + tracked_response = serialize_tracked_command_response(response.tracked_command_response) + + # Return the response - formatted as a dictionary + return { + "success": tracked_response.get("success"), + "created_bodies": [ + body.get("id").id for body in tracked_response.get("created_bodies") + ], + } @protect_grpc def extrude_edges_up_to(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + ExtrudeEdgesUpToRequest, + ExtrudeEdgesUpToRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = ExtrudeEdgesUpToRequest( + request_data=[ + ExtrudeEdgesUpToRequestData( + edge_ids=[build_grpc_id(id) for id in kwargs["face_ids"]], + up_to_selection_id=build_grpc_id(kwargs["up_to_selection_id"]), + seed_point=from_point3d_to_grpc_point(kwargs["seed_point"]), + direction=from_unit_vector_to_grpc_direction(kwargs["direction"]), + extrude_type=kwargs["extrude_type"].value, + ) + ] + ) + + # Call the gRPC service and serialize the response + response = self.edit_stub.ExtrudeFacesUpTo(request=request) + tracked_response = serialize_tracked_command_response(response.tracked_command_response) + + # Return the response - formatted as a dictionary + return { + "success": tracked_response.get("success"), + "created_bodies": [ + body.get("id").id for body in tracked_response.get("created_bodies") + ], + } @protect_grpc def move_imprint_edges(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + MoveImprintEdgesRequest, + MoveImprintEdgesRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = MoveImprintEdgesRequest( + request_data=[ + MoveImprintEdgesRequestData( + edge_ids=[build_grpc_id(edge_id) for edge_id in kwargs["edge_ids"]], + direction=from_unit_vector_to_grpc_direction(kwargs["direction"]), + distance=from_length_to_grpc_quantity(kwargs["distance"]), + ) + ] + ) + + # Call the gRPC service + response = self.edit_stub.MoveImprintEdges(request) + + # Return the response - formatted as a dictionary + return { + "success": response.tracked_command_response.command_response.success, + } @protect_grpc def offset_edges(self, **kwargs) -> dict: # noqa: D102 - return NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + OffsetEdgesRequest, + OffsetEdgesRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = OffsetEdgesRequest( + request_data=[ + OffsetEdgesRequestData( + edge_ids=[build_grpc_id(edge_id) for edge_id in kwargs["edge_ids"]], + value=from_length_to_grpc_quantity(kwargs["offset"]), + ) + ] + ) + + # Call the gRPC service + response = self.edit_stub.OffsetEdges(request) + + # Return the response - formatted as a dictionary + return { + "success": response.tracked_command_response.command_response.success, + } diff --git a/src/ansys/geometry/core/_grpc/_services/v1/faces.py b/src/ansys/geometry/core/_grpc/_services/v1/faces.py index 611381aa6e..6629004f87 100644 --- a/src/ansys/geometry/core/_grpc/_services/v1/faces.py +++ b/src/ansys/geometry/core/_grpc/_services/v1/faces.py @@ -21,11 +21,29 @@ # SOFTWARE. """Module containing the faces service implementation for v1.""" +from ansys.api.discovery.v1.commonmessages_pb2 import MultipleEntitiesRequest import grpc from ansys.geometry.core.errors import protect_grpc +from ..base.conversions import ( + from_measurement_to_server_length, + to_area, +) from ..base.faces import GRPCFacesService +from .conversions import ( + build_grpc_id, + from_angle_to_grpc_quantity, + from_grpc_curve_to_curve, + from_grpc_direction_to_unit_vector, + from_grpc_point_to_point3d, + from_grpc_surface_to_surface, + from_length_to_grpc_quantity, + from_line_to_grpc_line, + from_point3d_to_grpc_point, + from_unit_vector_to_grpc_direction, + serialize_tracked_command_response, +) class GRPCFacesServiceV1(GRPCFacesService): # pragma: no cover @@ -43,102 +61,606 @@ class GRPCFacesServiceV1(GRPCFacesService): # pragma: no cover @protect_grpc def __init__(self, channel: grpc.Channel): # noqa: D102 - from ansys.api.geometry.v1.faces_pb2_grpc import FacesStub + from ansys.api.discovery.v1.design.geometry.face_pb2_grpc import FaceStub + from ansys.api.discovery.v1.operations.edit_pb2_grpc import EditStub - self.stub = FacesStub(channel) + self.stub = FaceStub(channel) + self.edit_stub = EditStub(channel) @protect_grpc def get_surface(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetSurface(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "surface": from_grpc_surface_to_surface(response.surface, kwargs["surface_type"]), + } @protect_grpc def get_box_uv(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetBoxUV(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "uv_box": { + "u": ( + response.start_u.value_in_geometry_units, + response.end_u.value_in_geometry_units, + ), + "v": ( + response.start_v.value_in_geometry_units, + response.end_v.value_in_geometry_units, + ), + } + } @protect_grpc def get_area(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetArea(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return {"area": to_area(response.area.value_in_geometry_units)} @protect_grpc def get_edges(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetEdges(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "edges": [ + { + "id": edge.id.id, + "curve_type": edge.curve_type, + "is_reversed": edge.is_reversed, + } + for edge in response.edges + ] + } @protect_grpc def get_vertices(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetVertices(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "vertices": [ + { + "id": vertex.id.id, + "position": from_grpc_point_to_point3d(vertex.position), + } + for vertex in response.vertices + ] + } @protect_grpc def get_loops(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ..base.conversions import to_distance + + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetLoops(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "loops": [ + { + "type": loop.type, + "length": to_distance(loop.length.value_in_geometry_units).value, + "min_corner": from_grpc_point_to_point3d(loop.bounding_box.min), + "max_corner": from_grpc_point_to_point3d(loop.bounding_box.max), + "edges": [edge for edge in loop.edges], + } + for loop in response.loops + ] + } @protect_grpc def get_color(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetColor(request=request) + + # Return the response - formatted as a dictionary + color = response.colors.get(kwargs["id"], "") + return {"color": color} @protect_grpc def get_bounding_box(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["id"])]) + + # Call the gRPC service + response = self.stub.GetBoundingBox(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "min_corner": from_grpc_point_to_point3d(response.box.min), + "max_corner": from_grpc_point_to_point3d(response.box.max), + "center": from_grpc_point_to_point3d(response.box.center), + } @protect_grpc def set_color(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.design.designmessages_pb2 import ( + SetColorRequest, + SetColorRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = SetColorRequest( + request_data=[ + SetColorRequestData( + id=build_grpc_id(kwargs["id"]), + color=kwargs["color"], + ) + ] + ) + # Call the gRPC service + response = self.stub.SetColor(request=request) + + # Return the response - formatted as a dictionary + return {"success": len(response.successfully_set_ids) == 1} @protect_grpc def get_normal(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.design.geometry.face_pb2 import ( + GetNormalRequest, + GetNormalRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = GetNormalRequest( + request_data=[ + GetNormalRequestData( + id=build_grpc_id(kwargs["id"]), + u=kwargs["u"], + v=kwargs["v"], + ) + ] + ) + + # Call the gRPC service + response = self.stub.GetNormal(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "normal": from_grpc_direction_to_unit_vector(response.direction), + } @protect_grpc def evaluate(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.design.geometry.face_pb2 import ( + EvaluateRequest, + EvaluateRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = EvaluateRequest( + request_data=[ + EvaluateRequestData( + id=build_grpc_id(kwargs["id"]), + u=kwargs["u"], + v=kwargs["v"], + ) + ] + ) + + # Call the gRPC service + response = self.stub.Evaluate(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "point": from_grpc_point_to_point3d(response.point), + } @protect_grpc def create_iso_parametric_curve(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.design.geometry.face_pb2 import ( + CreateIsoParamCurvesRequest, + CreateIsoParamCurvesRequestData, + ) + + from ansys.geometry.core.shapes.parameterization import Interval + + from ..base.conversions import to_distance + + # Create the request - assumes all inputs are valid and of the proper type + request = CreateIsoParamCurvesRequest( + request_data=[ + CreateIsoParamCurvesRequestData( + id=build_grpc_id(kwargs["id"]), + u_dir_curve=kwargs["use_u_param"], + proportion=kwargs["parameter"], + ) + ] + ) + + # Call the gRPC service + response = self.stub.CreateIsoParamCurves(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "curves": [ + { + "geometry": from_grpc_curve_to_curve(curve.curve), + "start": from_grpc_point_to_point3d(curve.start), + "end": from_grpc_point_to_point3d(curve.end), + "interval": Interval(curve.interval_start, curve.interval_end), + "length": to_distance(curve.length).value, + } + for curve in response.curves + ] + } @protect_grpc def extrude_faces(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + ExtrudeFacesRequest, + ExtrudeFacesRequestData, + ) + + # Assign direction + direction = ( + None + if kwargs["direction"] is None + else from_unit_vector_to_grpc_direction(kwargs["direction"]) + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = ExtrudeFacesRequest( + request_data=[ + ExtrudeFacesRequestData( + ids=[build_grpc_id(id) for id in kwargs["face_ids"]], + distance=from_length_to_grpc_quantity(kwargs["distance"]), + direction=direction, + extrude_type=kwargs["extrude_type"].value, + pull_symmetric=kwargs["pull_symmetric"], + offset_mode=kwargs["offset_mode"].value, + copy=kwargs["copy"], + force_do_as_extrude=kwargs["force_do_as_extrude"], + ) + ] + ) + + # Call the gRPC service and serialize the response + response = self.edit_stub.ExtrudeFaces(request=request) + tracked_response = serialize_tracked_command_response(response.tracked_command_response) + + # Return the response - formatted as a dictionary + return { + "success": tracked_response.get("success"), + "created_bodies": [ + body.get("id").id for body in tracked_response.get("created_bodies") + ], + } @protect_grpc def extrude_faces_up_to(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + ExtrudeFacesUpToRequest, + ExtrudeFacesUpToRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = ExtrudeFacesUpToRequest( + request_data=[ + ExtrudeFacesUpToRequestData( + ids=[build_grpc_id(id) for id in kwargs["face_ids"]], + up_to_selection_id=build_grpc_id(kwargs["up_to_selection_id"]), + direction=from_unit_vector_to_grpc_direction(kwargs["direction"]), + extrude_type=kwargs["extrude_type"].value, + pull_symmetric=kwargs["pull_symmetric"], + offset_mode=kwargs["offset_mode"].value, + copy=kwargs["copy"], + force_do_as_extrude=kwargs["force_do_as_extrude"], + seed_point=from_point3d_to_grpc_point(kwargs["seed_point"]), + ) + ] + ) + + # Call the gRPC service and serialize the response + response = self.edit_stub.ExtrudeFacesUpTo(request=request) + tracked_response = serialize_tracked_command_response(response.tracked_command_response) + + # Return the response - formatted as a dictionary + return { + "success": tracked_response.get("success"), + "created_bodies": [ + body.get("id").id for body in tracked_response.get("created_bodies") + ], + } @protect_grpc def offset_faces_set_radius(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + OffsetFacesSetRadiusRequest, + OffsetFacesSetRadiusRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = OffsetFacesSetRadiusRequest( + request_data=[ + OffsetFacesSetRadiusRequestData( + faces_ids=[build_grpc_id(id) for id in kwargs["face_ids"]], + radius=from_length_to_grpc_quantity(kwargs["radius"]), + offset_mode=kwargs["offset_mode"].value, + copy=kwargs["copy"], + extrude_type=kwargs["extrude_type"].value, + ) + ] + ) + + # Call the gRPC service + response = self.edit_stub.OffsetFacesSetRadius(request=request) + + # Return the response - formatted as a dictionary + return { + "success": response.tracked_command_response.command_response.success, + } @protect_grpc def revolve_faces(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + RevolveFacesRequest, + RevolveFacesRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = RevolveFacesRequest( + request_data=[ + RevolveFacesRequestData( + selection_id=[build_grpc_id(id) for id in kwargs["selection_ids"]], + axis=from_line_to_grpc_line(kwargs["axis"]), + angle=from_angle_to_grpc_quantity(kwargs["angle"]), + extrude_type=kwargs["extrude_type"].value, + ) + ] + ) + + # Call the gRPC service and serialize the response + response = self.edit_stub.RevolveFaces(request=request) + tracked_response = serialize_tracked_command_response(response.tracked_command_response) + + # Return the response - formatted as a dictionary + return { + "success": tracked_response.get("success"), + "created_bodies": [ + body.get("id").id for body in tracked_response.get("created_bodies") + ], + } @protect_grpc def revolve_faces_up_to(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + RevolveFacesUpToRequest, + RevolveFacesUpToRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = RevolveFacesUpToRequest( + request_data=[ + RevolveFacesUpToRequestData( + selection_ids=[build_grpc_id(id) for id in kwargs["selection_ids"]], + up_to_selection_id=build_grpc_id(kwargs["up_to_selection_id"]), + direction=from_unit_vector_to_grpc_direction(kwargs["direction"]), + axis=from_line_to_grpc_line(kwargs["axis"]), + extrude_type=kwargs["extrude_type"].value, + ) + ] + ) + + # Call the gRPC service and serialize the response + response = self.edit_stub.RevolveFacesUpTo(request=request) + tracked_response = serialize_tracked_command_response(response.tracked_command_response) + + # Return the response - formatted as a dictionary + return { + "success": tracked_response.get("success"), + "created_bodies": [ + body.get("id").id for body in tracked_response.get("created_bodies") + ], + } @protect_grpc def revolve_faces_by_helix(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + RevolveFacesByHelixRequest, + RevolveFacesByHelixRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = RevolveFacesByHelixRequest( + request_data=[ + RevolveFacesByHelixRequestData( + selection_ids=[build_grpc_id(id) for id in kwargs["selection_ids"]], + direction=from_unit_vector_to_grpc_direction(kwargs["direction"]), + axis=from_line_to_grpc_line(kwargs["axis"]), + height=from_length_to_grpc_quantity(kwargs["height"]), + pitch=from_length_to_grpc_quantity(kwargs["pitch"]), + taper_angle=from_angle_to_grpc_quantity(kwargs["taper_angle"]), + right_handed=kwargs["right_handed"], + both_sides=kwargs["both_sides"], + extrude_type=kwargs["extrude_type"].value, + ) + ] + ) + + # Call the gRPC service and serialize the response + response = self.edit_stub.RevolveFacesByHelix(request=request) + tracked_response = serialize_tracked_command_response(response.tracked_command_response) + + # Return the response - formatted as a dictionary + return { + "success": tracked_response.get("success"), + "created_bodies": [ + body.get("id").id for body in tracked_response.get("created_bodies") + ], + } @protect_grpc def replace_faces(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.design.geometry.face_pb2 import ReplaceFaceRequest + + # Create the request - assumes all inputs are valid and of the proper type + request = ReplaceFaceRequest( + target_selection_ids=[build_grpc_id(id) for id in kwargs["target_ids"]], + replacement_selection_ids=[build_grpc_id(id) for id in kwargs["replacement_ids"]], + ) + + # Call the gRPC service + response = self.stub.Replace(request=request) + + # Return the response - formatted as a dictionary + return { + "success": response.tracked_command_response.command_response.success, + } @protect_grpc def thicken_faces(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + ThickenFacesRequest, + ThickenFacesRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = ThickenFacesRequest( + request_data=[ + ThickenFacesRequestData( + ids=[build_grpc_id(id) for id in kwargs["face_ids"]], + direction=from_unit_vector_to_grpc_direction(kwargs["direction"]), + value=from_length_to_grpc_quantity(kwargs["thickness"]), + extrude_type=kwargs["extrude_type"].value, + pull_symmetric=kwargs["pull_symmetric"], + select_direction=kwargs["select_direction"], + ) + ] + ) + + # Call the gRPC service + response = self.edit_stub.ThickenFaces(request=request) + + # Return the response - formatted as a dictionary + return { + "success": response.tracked_command_response.command_response.success, + } @protect_grpc def draft_faces(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + DraftFacesRequest, + DraftFacesRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = DraftFacesRequest( + request_data=[ + DraftFacesRequestData( + ids=[build_grpc_id(id) for id in kwargs["face_ids"]], + reference_ids=[build_grpc_id(id) for id in kwargs["reference_face_ids"]], + draft_side=kwargs["draft_side"].value, + draft_angle=from_angle_to_grpc_quantity(kwargs["angle"]), + extrude_type=kwargs["extrude_type"].value, + ) + ] + ) + + # Call the gRPC server + response = self.edit_stub.DraftFaces(request=request) + + # Return the drafted faces + return { + "created_faces": [face.id for face in response.created_faces], + } @protect_grpc def get_round_info(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + # Create the request - assumes all inputs are valid and of the proper type + request = MultipleEntitiesRequest(ids=[build_grpc_id(kwargs["face_id"])]) + + # Call the gRPC service + response = self.stub.GetRoundInfo(request=request).response_data[0] + + # Return the response - formatted as a dictionary + return { + "along_u": response.along_u, + "radius": response.radius, + } @protect_grpc def offset_faces(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + OffsetFacesRequest, + OffsetFacesRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = OffsetFacesRequest( + request_data=[ + OffsetFacesRequestData( + face_ids=[build_grpc_id(id) for id in kwargs["face_ids"]], + offset=from_measurement_to_server_length(kwargs["distance"]), + direction=from_unit_vector_to_grpc_direction(kwargs["direction"]), + extrude_type=kwargs["extrude_type"].value, + ) + ] + ) + + # Call the gRPC service and serialize the response + response = self.edit_stub.OffsetFaces(request=request) + tracked_response = serialize_tracked_command_response(response.tracked_command_response) + + # Return the response - formatted as a dictionary + return { + "results": [face.get("id").id for face in tracked_response.get("created_faces")], + } @protect_grpc def setup_offset_relationship(self, **kwargs) -> dict: # noqa: D102 - raise NotImplementedError + from ansys.api.discovery.v1.operations.edit_pb2 import ( + FaceOffsetRequest, + FaceOffsetRequestData, + ) + + # Create the request - assumes all inputs are valid and of the proper type + request = FaceOffsetRequest( + request_data=[ + FaceOffsetRequestData( + face1=build_grpc_id(kwargs["face1_id"]), + face2=build_grpc_id(kwargs["face2_id"]), + set_baselines=kwargs["set_baselines"], + process_adjacent_faces=kwargs["process_adjacent_faces"], + ) + ] + ) + + # Call the gRPC service + response = self.edit_stub.FaceOffset(request=request) + + # Return the response - formatted as a dictionary + return { + "success": response.tracked_command_response.command_response.success, + } diff --git a/src/ansys/geometry/core/designer/face.py b/src/ansys/geometry/core/designer/face.py index 3267b0fff4..fa07939fe4 100644 --- a/src/ansys/geometry/core/designer/face.py +++ b/src/ansys/geometry/core/designer/face.py @@ -543,7 +543,6 @@ def get_named_selections(self) -> list["NamedSelection"]: """ included_ns = [] for ns in get_design_from_body(self.body).named_selections: - print([face.id for face in ns.faces]) if any(face.id == self.id for face in ns.faces): included_ns.append(ns)