bluemira.geometry.tools
Useful functions for bluemira geometries.
Classes
Enumeration of planes to perform a hull operation in. |
|
JSON Encoder for BluemiraGeo. |
|
Typing for closed_wire_wrapper input |
|
Typing for closed_wire_wrapper output |
|
Sweep shape corner transition options |
|
Used in cut_wire_at_z_value to choose which part of the shape to remove |
Functions
|
Convert a FreeCAD shape into the corresponding BluemiraGeo object. |
|
Reconstruct the call of a function with inputs arguments and defaults. |
|
Make a new file in the geometry debugging folder. |
|
Decorator for debugging of failed geometry operations. |
|
Decorator for a fallback to an alternative geometry operation. |
|
Make a vertex. |
|
Decorator for checking / enforcing closures on wire creation functions. |
|
Make a polygon from a set of points. |
|
Make a bspline from a set of points. |
|
Builds a B-Spline by a lists of Poles, Mults, Knots |
|
Builds a B-SplineSurface by a lists of Poles, Mults, Knots |
Overloaded function signature for fallback option from interpolate_bspline |
|
|
Make a bspline from a set of points. |
|
Force a wire to be a spline wire. |
|
Create a circle or arc of circle object with given parameters. |
|
Create an arc of circle object given three points. |
|
Create an ellipse or arc of ellipse object with given parameters. |
|
Close this wire with a line segment |
Fallback function for discretised offsetting |
|
|
Make a planar offset from a planar wire. |
|
Perform a convex hull around the given wires and return the hull |
|
Revolve a polygon along the z axis, and return the volume. |
|
Gives the relationship between how the the solid volume varies with the position of |
|
Apply the revolve (base, dir, degree) to this shape |
|
Apply the extrusion along vec to this shape |
|
Sweep a profile along a path. |
|
Loft between a set of profiles. |
|
Decorator for fillet and chamfer operations, checking for validity of wire |
|
Fillet all edges of a wire |
|
Chamfer all edges of a wire |
|
Calculate the distance between two BluemiraGeos. |
|
Split a wire at a given vertex. |
|
Remove the parts of the wire below or above a given z-value. |
|
Calculate the plane intersection points with an object |
|
Cut a wire using a plane. |
|
Make a equally spaced circular pattern of shapes. |
|
Get a mirrored copy of a shape about a plane. |
|
Check that the the list of xz points are strictly convex, i.e. |
|
Saves a series of Shape objects as a STEP assembly |
|
Save the CAD of a component (eg a reactor) or a list of components |
|
Import CAD from file |
|
|
|
|
|
2-D function for the signed distance from a point to a polygon. The return value is |
|
2-D vector-valued signed distance function from a subject polygon to a target |
|
Single-valued signed "distance" function between two wires. Will return negative |
|
|
|
Connect (imprint) a list of shapes together. |
|
Make a compound of the given shapes. |
|
Fuse two or more shapes together. Internal splitter are removed. |
|
Subtract from the base, a (list of) topo shapes cut (tools). |
|
Split a list of shapes into their Boolean fragments. |
|
Check whether or not a point is inside a shape. |
|
Check whether or not a point is on a plane. |
|
Serialise a BluemiraGeo object. |
|
Deserialise a BluemiraGeo object obtained from serialise_shape. |
|
Search through the boundary of the shape and get any shapes with a label |
|
Find the clockwise angle between the 2D vectors |
Module Contents
- bluemira.geometry.tools.convert(apiobj: bluemira.codes._freecadapi.apiShape, label: str = '') bluemira.geometry.base.BluemiraGeoT
Convert a FreeCAD shape into the corresponding BluemiraGeo object.
- Returns:
BluemiraGeo object of inputted FreeCAD shape.
- Raises:
TypeError – Cannot convert to BluemiraGeo
- Parameters:
apiobj (bluemira.codes._freecadapi.apiShape)
label (str)
- Return type:
bluemira.geometry.base.BluemiraGeoT
- class bluemira.geometry.tools.HullPlane(*args, **kwds)
Bases:
enum.EnumEnumeration of planes to perform a hull operation in.
- XZ
- XY
- YZ
- classmethod _missing_(value: str)
- Parameters:
value (str)
- class bluemira.geometry.tools.BluemiraGeoEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)
Bases:
json.JSONEncoderJSON Encoder for BluemiraGeo.
- default(obj: bluemira.geometry.base.BluemiraGeoT | numpy.ndarray | Any)
Override the JSONEncoder default object handling behaviour for BluemiraGeo.
- Returns:
List from bluemira shape or numpy array.
- Parameters:
obj (bluemira.geometry.base.BluemiraGeoT | numpy.ndarray | Any)
- bluemira.geometry.tools._reconstruct_function_call(signature, *args, **kwargs) dict
Reconstruct the call of a function with inputs arguments and defaults.
- Returns:
Dictionary of data from a function with inputs arguments and defaults.
- Return type:
dict
- bluemira.geometry.tools._make_debug_file(name: str) pathlib.Path
Make a new file in the geometry debugging folder.
- Returns:
Filename for new file in the geometry debugging folder.
- Parameters:
name (str)
- Return type:
pathlib.Path
- bluemira.geometry.tools.log_geometry_on_failure(func)
Decorator for debugging of failed geometry operations.
- Returns:
Decorator for debugging of failed geometry operations.
- bluemira.geometry.tools.fallback_to(fallback_func, exception)
Decorator for a fallback to an alternative geometry operation.
- Returns:
Decorator for fallback function.
- bluemira.geometry.tools._make_vertex(point: numpy.typing.ArrayLike | bluemira.geometry.coordinates.Coordinates) bluemira.codes._freecadapi.apiVertex
Make a vertex.
- Parameters:
point (numpy.typing.ArrayLike | bluemira.geometry.coordinates.Coordinates) – Coordinates of the point
- Return type:
Vertex at the point
- Raises:
GeometryError – Shape must a single point
- class bluemira.geometry.tools.GeometryCreationIn
Bases:
ProtocolTyping for closed_wire_wrapper input
- __call__(points: bluemira.geometry.coordinates.Coordinates, label: str = '', *, closed: bool = False) bluemira.geometry.wire.BluemiraWire
Typing for coordinates wrapping
- Parameters:
label (str)
closed (bool)
- Return type:
- class bluemira.geometry.tools.GeometryCreationOut
Bases:
ProtocolTyping for closed_wire_wrapper output
- __call__(points: bluemira.geometry.coordinates.Coordinates | numpy.typing.ArrayLike | dict[str, numpy.typing.ArrayLike], label: str = '', *, closed: bool = False) bluemira.geometry.wire.BluemiraWire
Typing for coordinates wrapping
- Parameters:
points (bluemira.geometry.coordinates.Coordinates | numpy.typing.ArrayLike | dict[str, numpy.typing.ArrayLike])
label (str)
closed (bool)
- Return type:
- bluemira.geometry.tools.closed_wire_wrapper(*, drop_closure_point: bool) collections.abc.Callable[[GeometryCreationIn], GeometryCreationOut]
Decorator for checking / enforcing closures on wire creation functions.
- Returns:
Decorator on wire creation functions.
- Parameters:
drop_closure_point (bool)
- Return type:
collections.abc.Callable[[GeometryCreationIn], GeometryCreationOut]
- bluemira.geometry.tools.make_polygon(points: bluemira.geometry.coordinates.Coordinates, label: str = '', *, closed: bool = False) bluemira.geometry.wire.BluemiraWire
Make a polygon from a set of points.
- Parameters:
points (bluemira.geometry.coordinates.Coordinates) – list of points. It can be given as a list of 3D tuples, a 3D numpy array, or similar.
label (str) – Object’s label
closed (bool) – if True, the first and last points will be connected in order to form a closed polygon. Defaults to False.
- Return type:
BluemiraWire of the polygon
Notes
If the input points are closed, but closed is False, the returned BluemiraWire will be closed.
- bluemira.geometry.tools.make_bezier(points: bluemira.geometry.coordinates.Coordinates, label: str = '', *, closed: bool = False) bluemira.geometry.wire.BluemiraWire
Make a bspline from a set of points.
- Parameters:
points (bluemira.geometry.coordinates.Coordinates) – list of points. It can be given as a list of 3D tuples, a 3D numpy array, or similar.
label (str) – Object’s label
closed (bool) – if True, the first and last points will be connected in order to form a closed bspline. Defaults to False.
- Return type:
BluemiraWire that contains the bspline
Notes
If the input points are closed, but closed is False, the returned BluemiraWire will be closed.
Bezier curve of degree n by the control points P_i is:
\[{\textbf{C}}(t) = \sum_{i=0}^{n} B_{i,n}(t) \cdot {\textbf{P}}_i\]where \(B_{i,n}(t)\) are the Bernstein polynomials:
\[B_{i,n}(t) = \binom{n}{i} (1 - t)^{n-i} t^i\]t is a parameter ranging from 0 to 1.
- bluemira.geometry.tools.make_bspline(poles: numpy.typing.ArrayLike, mults: numpy.typing.ArrayLike, knots: numpy.typing.ArrayLike, *, periodic: bool, degree: int, weights: numpy.typing.ArrayLike, check_rational: bool, label: str = '') bluemira.geometry.wire.BluemiraWire
Builds a B-Spline by a lists of Poles, Mults, Knots
- Parameters:
poles (numpy.typing.ArrayLike) – list of poles.
mults (numpy.typing.ArrayLike) – list of integers for the multiplicity
knots (numpy.typing.ArrayLike) – list of knots
periodic (bool) – Whether or not the spline is periodic (same curvature at start and end points)
degree (int) – bspline degree
weights (numpy.typing.ArrayLike) – sequence of float
check_rational (bool) – Whether or not to check if the BSpline is rational
label (str)
- Return type:
BluemiraWire of the spline
Notes
The B-spline curve is defined by the control points P_i:
\[\textbf{C}(t) = \sum_{i=0}^{n} B_{i,p}(t) {\textbf{P}}_i,\]where the basis functions \(B_{i,p}(t)\) are computed as:
\[\begin{split}B_{i,0}(t) = \begin{cases} 1 & \text{if } t_i \leq t < t_{i+1}, \\ 0 & \text{otherwise}. \end{cases}\end{split}\]\[B_{i,p}(t) = \frac{t - t_i}{t_{i+p} - t_i} B_{i,p-1}(t) + \frac{t_{i+p+1} - t}{t_{i+p+1} - t_{i+1}} B_{i+1,p-1}(t).\]Here, t is a parameter ranging from 0 to 1, representing the position along the curve.
- bluemira.geometry.tools.make_bsplinesurface(poles: numpy.typing.ArrayLike, mults_u: numpy.typing.ArrayLike, mults_v: numpy.typing.ArrayLike, knot_vector_u: numpy.typing.ArrayLike, knot_vector_v: numpy.typing.ArrayLike, degree_u: int, degree_v: int, weights: numpy.typing.ArrayLike, *, periodic: bool, check_rational: bool, label: str = '') bluemira.geometry.wire.BluemiraWire
Builds a B-SplineSurface by a lists of Poles, Mults, Knots
- Parameters:
poles (numpy.typing.ArrayLike) – Array of poles (control points).
mults_u (numpy.typing.ArrayLike) – list of integers for the u-multiplicity
mults_v (numpy.typing.ArrayLike) – list of integers for the u-multiplicity
knot_vector_u (numpy.typing.ArrayLike) – list of u-knots
knot_vector_v (numpy.typing.ArrayLike) – list of v-knots
degree_u (int) – degree of NURBS in u-direction
degree_v (int) – degree of NURBS in v-direction
weights (numpy.typing.ArrayLike) – point weights.
periodic (bool) – Whether or not the spline is periodic (same curvature at start and end points)
check_rational (bool) – Whether or not to check if the BSpline is rational (not sure)
label (str)
- Return type:
A FreeCAD object that contours the bsplinesurface
Notes
This function wraps the FreeCAD function of bsplinesurface buildFromPolesMultsKnots.
The B-spline surface is defined as:
\[\begin{split}{\textbf{S}}(u, v) = \sum_{i=0}^{n} \sum_{j=0}^{m} N_{i,p}(u) \\ M_{j,q}(v) {\textbf{P}}_{i,j}\end{split}\]where \(N_{i,p}(u)\) and \(M_{j,q}(v)\) are the B-spline basis functions in the u and v dimensions, respectively.
- bluemira.geometry.tools._make_polygon_fallback(points, label='', *, closed=False, **kwargs) bluemira.geometry.wire.BluemiraWire
Overloaded function signature for fallback option from interpolate_bspline
- Returns:
Closed BluemiraWire from points.
- Return type:
- bluemira.geometry.tools.interpolate_bspline(points: numpy.typing.ArrayLike, label: str = '', *, closed: bool = False, start_tangent: collections.abc.Iterable | None = None, end_tangent: collections.abc.Iterable | None = None, allow_fallback: bool = True) bluemira.geometry.wire.BluemiraWire
Make a bspline from a set of points.
- Parameters:
points (numpy.typing.ArrayLike) – list of points. It can be given as a list of 3D tuples, a 3D numpy array, or similar.
label (str) – Object’s label
closed (bool) – if True, the first and last points will be connected in order to form a closed bspline. Defaults to False.
start_tangent (collections.abc.Iterable | None) – Tangency of the BSpline at the first pole. Must be specified with end_tangent
end_tangent (collections.abc.Iterable | None) – Tangency of the BSpline at the last pole. Must be specified with start_tangent
allow_fallback (bool)
- Return type:
Bluemira wire that contains the bspline
- bluemira.geometry.tools.force_wire_to_spline(wire: bluemira.geometry.wire.BluemiraWire, n_edges_max: int = 200, l2_tolerance: float = 0.005) bluemira.geometry.wire.BluemiraWire
Force a wire to be a spline wire.
- Parameters:
wire (bluemira.geometry.wire.BluemiraWire) – The BluemiraWire to be turned into a splined wire
n_edges_max (int) – The maximum number of edges in the wire, below which this operation does nothing
l2_tolerance (float) – The L2-norm difference w.r.t. the original wire, above which this operation will warn that the desired tolerance was not achieved.
- Return type:
A new spline version of the wire
Notes
This is intended for use with wires that consist of large polygons, often resulting from operations that failed with primitives and fallback methods making use of of polygons. This can be relatively stubborn to transform back to splines.
- bluemira.geometry.tools.make_circle(radius: float = 1.0, center: numpy.typing.ArrayLike = (0.0, 0.0, 0.0), start_angle: float = 0.0, end_angle: float = 360.0, axis: numpy.typing.ArrayLike = (0.0, 0.0, 1.0), label: str = '') bluemira.geometry.wire.BluemiraWire
Create a circle or arc of circle object with given parameters.
- Parameters:
radius (float) – Radius of the circle
center (numpy.typing.ArrayLike) – Center of the circle
start_angle (float) – Start angle of the arc [degrees]
end_angle (float) – End angle of the arc [degrees]. If start_angle == end_angle, a circle is created, otherwise a circle arc is created
axis (numpy.typing.ArrayLike) – Normal vector to the circle plane. It defines the clockwise/anticlockwise circle orientation according to the right hand rule.
label (str) – object’s label
- Return type:
Bluemira wire that contains the arc or circle
- bluemira.geometry.tools.make_circle_arc_3P(p1: collections.abc.Iterable[float], p2: collections.abc.Iterable[float], p3: collections.abc.Iterable[float], axis: tuple[float, float, float] | None = None, label: str = '') bluemira.geometry.wire.BluemiraWire
Create an arc of circle object given three points.
- Parameters:
p1 (collections.abc.Iterable[float]) – Starting point of the circle arc
p2 (collections.abc.Iterable[float]) – Middle point of the circle arc
p3 (collections.abc.Iterable[float]) – End point of the circle arc
axis (tuple[float, float, float] | None)
label (str)
- Return type:
Bluemira wire that contains the arc or circle
- Raises:
GeometryError – Raised if the three points are collinear.
- bluemira.geometry.tools.make_ellipse(center: numpy.typing.ArrayLike = (0.0, 0.0, 0.0), major_radius: float = 2.0, minor_radius: float = 1.0, major_axis: numpy.typing.ArrayLike = (1, 0, 0), minor_axis: numpy.typing.ArrayLike = (0, 1, 0), start_angle: float = 0.0, end_angle: float = 360.0, label: str = '') bluemira.geometry.wire.BluemiraWire
Create an ellipse or arc of ellipse object with given parameters.
- Parameters:
center (numpy.typing.ArrayLike) – Center of the ellipse
major_radius (float) – Major radius of the ellipse
minor_radius (float) – Minor radius of the ellipse (float). Default to 2.
major_axis (numpy.typing.ArrayLike) – Major axis direction
minor_axis (numpy.typing.ArrayLike) – Minor axis direction
start_angle (float) – Start angle of the arc [degrees]
end_angle (float) – End angle of the arc [degrees]. if start_angle == end_angle, an ellipse is created, otherwise a ellipse arc is created
label (str) – Object’s label
- Return type:
Bluemira wire that contains the arc or ellipse
- bluemira.geometry.tools.wire_closure(bmwire: bluemira.geometry.wire.BluemiraWire, label='closure') bluemira.geometry.wire.BluemiraWire
Close this wire with a line segment
- Parameters:
bmwire (bluemira.geometry.wire.BluemiraWire) – supporting wire for the closure
label – Object’s label
- Return type:
Closure wire
- bluemira.geometry.tools._offset_wire_discretised(wire: bluemira.geometry.wire.BluemiraWire, thickness: float, /, join: str = 'intersect', *, open_wire: bool = True, label: str = '', fallback_method: str = 'square', fallback_force_spline: bool = False, byedges: bool = True, ndiscr: int = 200, **fallback_kwargs) bluemira.geometry.wire.BluemiraWire
Fallback function for discretised offsetting
- Returns:
The offset wire.
- Raises:
GeometryError – If the wire is not closed. This function cannot handle the offet of an open wire.
- Parameters:
thickness (float)
join (str)
open_wire (bool)
label (str)
fallback_method (str)
fallback_force_spline (bool)
byedges (bool)
ndiscr (int)
- Return type:
- bluemira.geometry.tools.offset_wire(wire: bluemira.geometry.wire.BluemiraWire, thickness: float, /, join: str = 'intersect', *, open_wire: bool = True, label: str = '', fallback_method: str = 'square', byedges: bool = True, ndiscr: int = 400, allow_fallback: bool = True, **fallback_kwargs) bluemira.geometry.wire.BluemiraWire
Make a planar offset from a planar wire.
- Parameters:
wire (bluemira.geometry.wire.BluemiraWire) – Wire to offset from
thickness (float) – Offset distance. Positive values outwards, negative values inwards
join (str) – Offset method. “arc” gives rounded corners, and “intersect” gives sharp corners
open_wire (bool) – For open wires (counter-clockwise default) whether or not to make an open offset wire, or a closed offset wire that encompasses the original wire. This is disabled for closed wires.
byedges (bool) – Whether or not to discretise the wire by edges
ndiscr (int) – Number of points to discretise the wire to
fallback_method (str) – Method to use in discretised offsetting, will default to square as round is know to be very slow
label (str)
allow_fallback (bool)
- Returns:
Offset wire
- Return type:
Notes
If primitive offsetting failed, will fall back to a discretised offset implementation, where the fallback kwargs are used. Discretised offsetting is only supported for closed wires.
- bluemira.geometry.tools.convex_hull_wires_2d(wires: collections.abc.Sequence[bluemira.geometry.wire.BluemiraWire], ndiscr: int, plane: str = 'xz') bluemira.geometry.wire.BluemiraWire
Perform a convex hull around the given wires and return the hull as a new wire.
The operation performs discretisations on the input wires.
- Parameters:
wires (collections.abc.Sequence[bluemira.geometry.wire.BluemiraWire]) – The wires to draw a hull around.
ndiscr (int) – The number of points to discretise each wire into.
plane (str) – The plane to perform the hull in. One of: ‘xz’, ‘xy’, ‘yz’. Default is ‘xz’.
- Returns:
A wire forming a convex hull around the input wires in the given
plane.
- Raises:
ValueError – not enough wires
- Return type:
- bluemira.geometry.tools.polygon_revolve_signed_volume(polygon: numpy.typing.ArrayLike) float
Revolve a polygon along the z axis, and return the volume.
A polygon placed in the RHS of the z-axis in the xz plane would have positive volume if it runs clockwise, and negative volume if it runs counter-clockwise.
Similarly a polygon placed on the LHS of the z-axis in the xz plane would have negative volume if it runs clockwise, positive volume if it runs counter-clockwise.
- Parameters:
polygon (numpy.typing.ArrayLike) – Stores the x-z coordinate pairs of the four coordinates.
- Returns:
Volume of revolved polygon
- Raises:
ValueError – shape must be (2, N)
- Return type:
float
Notes
Consider one edge of the polygon, which has two vertices, $p$ and $c$.
When revolved around the z-axis, this trapezium forms a the frustum of a cone. The expression for the volume of this frustrum needs to be modified to avoid ZeroDivisionError, thus it is recast into the following (also the simplest) form: \(V = \frac{\pi}{3} (p_z - c_z) (p_x^2 + p_x c_x + c_x^2)\).
Adding together the signed volume of all edges, the excess negative volume from one side would cancel out the excess positive volume from the other, such that abs(signed volume)= the volume of the polygon after being revolved around the z-axis.
- bluemira.geometry.tools.partial_diff_of_volume(three_vertices: collections.abc.Sequence[collections.abc.Sequence[float]], normalised_direction_vector: collections.abc.Iterable[float]) float
Gives the relationship between how the the solid volume varies with the position of one of its verticies. More precisely, it gives gives the the partial derivative of the volume of the solid revolved out of a polygon when one vertex of that polygon is moved in the direction specified by normalised_direction_vector.
- Parameters:
three_vertices (collections.abc.Sequence[collections.abc.Sequence[float]]) – Contain (x, z) coordinates of the polygon. It extracts only the vertex being moved, and the two vertices around it. three_vertices[0] and three_vertices[2] are anchor vertices that cannot be adjusted. shape (3, 2)
normalised_direction_vector (collections.abc.Iterable[float]) – Direction that the point is allowed to move in. shape = (2,)
- Returns:
Partial differential of volume
- Return type:
float
Notes
Let there be 3 points, \(q\), \(r\), and \(s\), forming two edges of a polygon. When r is moved, the polygon’s revolved solid volume changes. After a hefty amount of derivation, everything cancels out to give the expression .. math:
\frac{dV}{d r_z} = q_z q_x - r_z q_x + 2 q_z r_x - 2 s_z r_x + r_z s_x - s_z s_x \frac{dV}{d r_x} = (q_x + r_x + s_x) (s_x - q_x)
The dot product between the direction of motion and the vector \(\frac{dV}{dr}\) gives the required scalar derivative showing “how much does the volume change when r is moved in a certain direction by one unit length”.
- bluemira.geometry.tools.revolve_shape(shape: bluemira.geometry.base.BluemiraGeoT, base: numpy.typing.ArrayLike = (0.0, 0.0, 0.0), direction: numpy.typing.ArrayLike = (0.0, 0.0, 1.0), degree: float = 180, label: str = '') bluemira.geometry.base.BluemiraGeoT
Apply the revolve (base, dir, degree) to this shape
- Parameters:
shape (bluemira.geometry.base.BluemiraGeoT) – The shape to be revolved
base (numpy.typing.ArrayLike) – Origin location of the revolution
direction (numpy.typing.ArrayLike) – The direction vector
degree (float) – revolution angle
label (str)
- Returns:
The revolved shape.
- Raises:
FreeCADError – Cannot revolve shape
- Return type:
bluemira.geometry.base.BluemiraGeoT
- bluemira.geometry.tools.extrude_shape(shape: bluemira.geometry.base.BluemiraGeo, vec: numpy.typing.ArrayLike, label: str = '') bluemira.geometry.solid.BluemiraSolid
Apply the extrusion along vec to this shape
- Parameters:
shape (bluemira.geometry.base.BluemiraGeo) – The shape to be extruded
vec (numpy.typing.ArrayLike) – The vector along which to extrude
label (str) – label of the output shape
- Return type:
The extruded shape.
- class bluemira.geometry.tools.SweepShapeTransition
Bases:
enum.IntEnumSweep shape corner transition options
- DEFAULT = 0
- RIGHT_CORNER = 1
- ROUND_CORNER = 2
- bluemira.geometry.tools.sweep_shape(profiles: bluemira.geometry.wire.BluemiraWire | collections.abc.Iterable[bluemira.geometry.wire.BluemiraWire], path: bluemira.geometry.wire.BluemiraWire, *, solid: bool = True, frenet: bool = True, transition: SweepShapeTransition | int = SweepShapeTransition.DEFAULT, label: str = '') bluemira.geometry.solid.BluemiraSolid | bluemira.geometry.shell.BluemiraShell
Sweep a profile along a path.
- Parameters:
profiles (bluemira.geometry.wire.BluemiraWire | collections.abc.Iterable[bluemira.geometry.wire.BluemiraWire]) – Profile(s) to sweep
path (bluemira.geometry.wire.BluemiraWire) – Path along which to sweep the profiles
solid (bool) – Whether or not to create a Solid
frenet (bool) – If true, the orientation of the profile(s) is calculated based on local curvature and tangency. For planar paths, should not make a difference.
transition (SweepShapeTransition | int) – transition type between sweep sections
label (str)
- Return type:
Swept geometry object
- bluemira.geometry.tools.loft_shape(profiles: collections.abc.Iterable[bluemira.geometry.wire.BluemiraWire], *, solid: bool = True, ruled: bool = False, closed: bool = False, label: str = '') bluemira.geometry.solid.BluemiraSolid | bluemira.geometry.shell.BluemiraShell
Loft between a set of profiles.
- Parameters:
profiles (collections.abc.Iterable[bluemira.geometry.wire.BluemiraWire]) – Profile(s) to loft between
solid (bool) – Whether or not to create a Solid
ruled (bool) – Create a ruled shape, see https://en.wikipedia.org/wiki/Ruled_surface for explanation.
closed (bool)
label (str)
- Return type:
Lofted geometry object
- bluemira.geometry.tools.fillet_chamfer_decorator(*, chamfer: bool)
Decorator for fillet and chamfer operations, checking for validity of wire and radius.
- Returns:
Decorator for fillet and chamfer operations.
- Raises:
GeometryError – Number of edges >= 2, radius >= 0 and planar
- Parameters:
chamfer (bool)
- bluemira.geometry.tools.fillet_wire_2D(wire: bluemira.geometry.wire.BluemiraWire, radius: float) bluemira.geometry.wire.BluemiraWire
Fillet all edges of a wire
- Parameters:
wire (bluemira.geometry.wire.BluemiraWire) – Wire to fillet
radius (float) – Radius of the fillet operation
- Return type:
The filleted wire
- bluemira.geometry.tools.chamfer_wire_2D(wire: bluemira.geometry.wire.BluemiraWire, radius: float) bluemira.geometry.wire.BluemiraWire
Chamfer all edges of a wire
- Parameters:
wire (bluemira.geometry.wire.BluemiraWire) – Wire to chamfer
radius (float) – Radius of the chamfer operation
- Return type:
The chamfered wire
- bluemira.geometry.tools.distance_to(geo1: numpy.typing.ArrayLike | bluemira.geometry.base.BluemiraGeo, geo2: numpy.typing.ArrayLike | bluemira.geometry.base.BluemiraGeo) tuple[float, list[tuple[float, float, float]]]
Calculate the distance between two BluemiraGeos.
- Parameters:
geo1 (numpy.typing.ArrayLike | bluemira.geometry.base.BluemiraGeo) – Reference shape. If an iterable of length 3, converted to a point.
geo2 (numpy.typing.ArrayLike | bluemira.geometry.base.BluemiraGeo) – Target shape. If an iterable of length 3, converted to a point.
- Returns:
dist – Minimum distance
vectors – List of tuples corresponding to the nearest points between geo1 and geo2. The distance between those points is the minimum distance given by dist.
- Return type:
tuple[float, list[tuple[float, float, float]]]
- bluemira.geometry.tools.split_wire(wire: bluemira.geometry.wire.BluemiraWire, vertex: numpy.typing.ArrayLike, tolerance: float = EPS * 10) tuple[bluemira.geometry.wire.BluemiraWire | None, bluemira.geometry.wire.BluemiraWire | None]
Split a wire at a given vertex.
- Parameters:
wire (bluemira.geometry.wire.BluemiraWire) – Wire to be split
vertex (numpy.typing.ArrayLike) – Vertex at which to split the wire
tolerance (float) – Tolerance within which to find the closest vertex on the wire
- Returns:
wire_1 – First half of the wire. Will be None if the vertex is the start point of the wire
wire_2 – Last half of the wire. Will be None if the vertex is the start point of the wire
- Raises:
GeometryError: – If the vertex is further away to the wire than the specified tolerance
- Return type:
tuple[bluemira.geometry.wire.BluemiraWire | None, bluemira.geometry.wire.BluemiraWire | None]
- bluemira.geometry.tools.cut_wire_at_z_value(wire: bluemira.geometry.wire.BluemiraWire, point_z: float, location: CutLocation, point_name: str = 'chosen point_z') bluemira.geometry.wire.BluemiraWire
Remove the parts of the wire below or above a given z-value.
- Parameters:
wire (bluemira.geometry.wire.BluemiraWire) – Wire shape that needs cutting.
point_z (float) – Z-value at point to make the cut.
location (CutLocation) – Choose to remove the lower or upper part of the wire after cutting.
point_name (str) – String printed in warning message, relevant when applied to an input of interest e.g. x-point location for an Equilibrium.
- Returns:
The remaining section of wire after cutting.
- Return type:
cut_wire
- Raises:
ValueError – No parts of shape found
- class bluemira.geometry.tools.CutLocation(*args, **kwds)
Bases:
enum.EnumUsed in cut_wire_at_z_value to choose which part of the shape to remove
- UPPER
Remove upper part of shape after cut
- LOWER
remove lower part of shape after cut
- bluemira.geometry.tools.slice_shape(shape: bluemira.geometry.base.BluemiraGeo, plane: bluemira.geometry.plane.BluemiraPlane) list[numpy.ndarray] | list[bluemira.geometry.wire.BluemiraWire] | None
Calculate the plane intersection points with an object
- Parameters:
shape (bluemira.geometry.base.BluemiraGeo) – Shape to intersect with a plane
plane (bluemira.geometry.plane.BluemiraPlane) – Plane to intersect with
- Returns:
Wire (Union[List[np.ndarray], None]) – returns array of intersection points
Face, Solid, Shell (Union[List[BluemiraWire], None]) – list of intersections lines
- Return type:
list[numpy.ndarray] | list[bluemira.geometry.wire.BluemiraWire] | None
Notes
Degenerate cases such as tangets to solid or faces do not return intersections if the shape and plane are acting at the Plane base. Further investigation needed.
- bluemira.geometry.tools.get_wire_plane_intersect(convex_bm_wire: bluemira.geometry.wire.BluemiraWire, plane: bluemira.geometry.plane.BluemiraPlane, cut_direction: numpy.typing.NDArray[float]) numpy.typing.NDArray[float]
Cut a wire using a plane.
- Parameters:
convex_bm_wire (bluemira.geometry.wire.BluemiraWire) – The wire that we’re interested in cutting.
plane (bluemira.geometry.plane.BluemiraPlane) – Plane that is cutting the wire.
cut_direction (numpy.typing.NDArray[float]) – np.ndarray with shape==(3,)
- Returns:
np.ndarray with shape==(3,)
- Return type:
intersection point
- bluemira.geometry.tools.circular_pattern(shape: bluemira.geometry.base.BluemiraGeo, origin: numpy.typing.ArrayLike = (0, 0, 0), direction: numpy.typing.ArrayLike = (0, 0, 1), degree: float = 360, n_shapes: int = 10) list[bluemira.geometry.base.BluemiraGeo]
Make a equally spaced circular pattern of shapes.
- Parameters:
shape (bluemira.geometry.base.BluemiraGeo) – Shape to pattern
origin (numpy.typing.ArrayLike) – Origin vector of the circular pattern
direction (numpy.typing.ArrayLike) – Direction vector of the circular pattern
degree (float) – Angle range of the patterning
n_shapes (int) – Number of shapes to pattern
- Return type:
List of patterned shapes, the first element is the original shape
- bluemira.geometry.tools.mirror_shape(shape: bluemira.geometry.base.BluemiraGeo, base: numpy.typing.ArrayLike, direction: numpy.typing.ArrayLike, label='') bluemira.geometry.base.BluemiraGeo
Get a mirrored copy of a shape about a plane.
- Parameters:
shape (bluemira.geometry.base.BluemiraGeo) – Shape to mirror
base (numpy.typing.ArrayLike) – Mirror plane base
direction (numpy.typing.ArrayLike) – Mirror plane normal direction
- Return type:
The mirrored shape
- Raises:
GeometryError – if the norm of the direction tuple is <= 3*EPS
- bluemira.geometry.tools.is_convex(points: numpy.typing.NDArray)
Check that the the list of xz points are strictly convex, i.e. Not even collinear points are allowed.
However, repeated points are allowed, as the repeated point would be ignored; and points are allowed to be entered in 3D (xyz), but the y component would be ignored as well.
- Parameters:
points (numpy.typing.NDArray) – A list of points that we want to check the convexity for. Shape = (n, 2/3)
- Return type:
boolean
- bluemira.geometry.tools.save_as_STP(shapes: bluemira.geometry.base.BluemiraGeoT | collections.abc.Iterable[bluemira.geometry.base.BluemiraGeoT], filename: str, **kwargs)
Saves a series of Shape objects as a STEP assembly
- Parameters:
shapes (bluemira.geometry.base.BluemiraGeoT | collections.abc.Iterable[bluemira.geometry.base.BluemiraGeoT]) – List of shape objects to be saved
filename (str) – Full path filename of the STP assembly
- bluemira.geometry.tools.save_cad(shapes: bluemira.geometry.base.BluemiraGeoT | collections.abc.Iterable[bluemira.geometry.base.BluemiraGeoT], filename: str | pathlib.Path, cad_format: str | bluemira.codes._freecadapi.CADFileType = 'stp', names: str | list[str] | None = None, **kwargs)
Save the CAD of a component (eg a reactor) or a list of components
- Parameters:
shapes (bluemira.geometry.base.BluemiraGeoT | collections.abc.Iterable[bluemira.geometry.base.BluemiraGeoT]) – shapes to save
filename (str | pathlib.Path) – Full path filename for the CAD file
cad_format (str | bluemira.codes._freecadapi.CADFileType) – file format to save as
names (str | list[str] | None) – Names of shapes to save
kwargs – arguments passed to cadapi save function
- bluemira.geometry.tools.import_cad(filename: str | pathlib.Path, cad_format: str | bluemira.codes._freecadapi.CADFileType | None = None, unit_scale: str = 'm', **kwargs) bluemira.geometry.base.BluemiraGeo | list[bluemira.geometry.base.BluemiraGeo]
Import CAD from file
- Returns:
The imported objects
- Parameters:
filename (str | pathlib.Path)
cad_format (str | bluemira.codes._freecadapi.CADFileType | None)
unit_scale (str)
- Return type:
bluemira.geometry.base.BluemiraGeo | list[bluemira.geometry.base.BluemiraGeo]
- bluemira.geometry.tools._nb_dot_2D(v_1, v_2)
- Returns:
Numba 2-D dot product
- bluemira.geometry.tools._nb_clip(val, a_min, a_max)
- Returns:
Numba 1-D clip.
- bluemira.geometry.tools._signed_distance_2D(point: numpy.ndarray, polygon: numpy.ndarray) float
2-D function for the signed distance from a point to a polygon. The return value is negative if the point is outside the polygon, and positive if the point is inside the polygon.
- Parameters:
point (numpy.ndarray) – 2-D point
polygon (numpy.ndarray) – 2-D set of points (closed)
- Return type:
Signed distance value of the point to the polygon
Notes
Credit: Inigo Quilez (https://www.iquilezles.org/)
- bluemira.geometry.tools.signed_distance_2D_polygon(subject_poly: numpy.ndarray, target_poly: numpy.ndarray) numpy.ndarray
2-D vector-valued signed distance function from a subject polygon to a target polygon. The return values are negative for points outside the target polygon, and positive for points inside the target polygon.
- Parameters:
subject_poly (numpy.ndarray) – Subject 2-D polygon
target_poly (numpy.ndarray) – Target 2-D polygon (closed polygons only)
- Return type:
Signed distances from the vertices of the subject polygon to the target polygon
Notes
This can used as a keep-out-zone constraint, in which the target polygon would be the keep-out-zone, and the subject polygon would be the shape which must be outsize of the keep-out-zone.
The target polygon must be closed.
- bluemira.geometry.tools.signed_distance(origin: bluemira.geometry.wire.BluemiraWire | bluemira.geometry.coordinates.Coordinates, target: bluemira.geometry.wire.BluemiraWire | bluemira.geometry.coordinates.Coordinates) float
Single-valued signed “distance” function between two wires. Will return negative values if origin does not touch or intersect target, 0 if there is one intersection, and a positive estimate of the intersection length if there are overlaps.
- Parameters:
origin (bluemira.geometry.wire.BluemiraWire | bluemira.geometry.coordinates.Coordinates) – a 0D/1D set of points
target (bluemira.geometry.wire.BluemiraWire | bluemira.geometry.coordinates.Coordinates) – a 0D/1D set of points
- Return type:
Closest distance between origin and target
Notes
This is not a pure implementation of a distance function, as for overlapping wires a metric of the quantity of overlap is returned (a positive value). This nevertheless enables the use of such a function as a constraint in gradient-based optimisers.
- This function has been extended to allow the target wire to be a point
(
Coordinates) as well
The signed “distance” function can be expressed as:
\[\begin{split}d (\textbf{p}_1, \textbf{p}_2) = \begin{cases} - \| \textbf{p}_1 - \textbf{p}_2 \| & \text{if no intersection} \\ 0 & \text{if one intersection} \\ \text{positive estimate of overlap length} & \text{if overlap exists} \end{cases}\end{split}\]
- bluemira.geometry.tools.raise_error_if_overlap(origin: bluemira.geometry.wire.BluemiraWire | bluemira.geometry.coordinates.Coordinates, target: bluemira.geometry.wire.BluemiraWire | bluemira.geometry.coordinates.Coordinates, origin_name: str = '', target_name: str = '')
- Raises:
GeometryError – if two wires/points intersects overlaps.
- Parameters:
origin (bluemira.geometry.wire.BluemiraWire | bluemira.geometry.coordinates.Coordinates)
target (bluemira.geometry.wire.BluemiraWire | bluemira.geometry.coordinates.Coordinates)
origin_name (str)
target_name (str)
- bluemira.geometry.tools.connect_shapes(shapes: collections.abc.Iterable[bluemira.geometry.base.BluemiraGeo], tolerance: float = 0.0, label: str = '') bluemira.geometry.base.BluemiraGeo
Connect (imprint) a list of shapes together.
This is similar to a boolean fuse operation, but connects the interior walls of solid or shells (removeing the excess).
For wires it will fuse them, keeping the biggest joined piece.
- Parameters:
shapes (collections.abc.Iterable[bluemira.geometry.base.BluemiraGeo]) – List of shape objects to be saved
label (str) – Label for the resulting shape
tolerance (float)
- Return type:
Result of the connect operation.
- Raises:
GeometryError – In case the boolean operation fails.
ValueError – All shapes (2 or more) must be the same type
- bluemira.geometry.tools.make_compound(shapes: collections.abc.Iterable[bluemira.geometry.base.BluemiraGeo], label: str = '') bluemira.geometry.compound.BluemiraCompound
Make a compound of the given shapes.
The shapes must all be the same topologic type (all solids, shells etc.). No mixing.
- Parameters:
shapes (collections.abc.Iterable[bluemira.geometry.base.BluemiraGeo]) – List of shape objects to be saved
label (str) – Label for the resulting shape
- Return type:
Result of the connect operation.
- Raises:
GeometryError – In case the boolean operation fails.
ValueError – All shapes (2 or more) must be the same type
- bluemira.geometry.tools.boolean_fuse(shapes: collections.abc.Iterable[bluemira.geometry.base.BluemiraGeo], label: str = '') bluemira.geometry.base.BluemiraGeo
Fuse two or more shapes together. Internal splitter are removed.
- Parameters:
shapes (collections.abc.Iterable[bluemira.geometry.base.BluemiraGeo]) – List of shape objects to be saved
label (str) – Label for the resulting shape
- Return type:
Result of the boolean operation.
- Raises:
GeometryError – In case the boolean operation fails.
ValueError – All shapes (2 or more) must be the same type
- bluemira.geometry.tools.boolean_cut(shape: bluemira.geometry.base.BluemiraGeoT, tools: bluemira.geometry.base.BluemiraGeoT | collections.abc.Iterable[bluemira.geometry.base.BluemiraGeoT]) bluemira.geometry.base.BluemiraGeoT | list[bluemira.geometry.base.BluemiraGeoT]
Subtract from the base, a (list of) topo shapes cut (tools).
- Parameters:
shape (bluemira.geometry.base.BluemiraGeoT) – the reference object
tools (bluemira.geometry.base.BluemiraGeoT | collections.abc.Iterable[bluemira.geometry.base.BluemiraGeoT]) – List of BluemiraGeo shape objects to be used as tools.
- Return type:
Result of the boolean cut operation.
- Raises:
error – GeometryError: In case the boolean operation fails.
Notes
Example:
Before cutting: shape = a cube, tools = a sphere.
After cutting: a cube with a sphere subtracted out of it.
- bluemira.geometry.tools.boolean_fragments(shapes: collections.abc.Iterable[bluemira.geometry.solid.BluemiraSolid], tolerance: float = 0.0) tuple[bluemira.geometry.compound.BluemiraCompound, list[list[bluemira.geometry.solid.BluemiraSolid]]]
Split a list of shapes into their Boolean fragments.
- Parameters:
shapes (collections.abc.Iterable[bluemira.geometry.solid.BluemiraSolid]) – List of BluemiraSolids to be split into Boolean fragments
tolerance (float) – Tolerance with which to perform the operation
- Returns:
compound – A compound of the unique fragments
fragment_map – An ordered list of groups of solid Boolean fragments (ordered in terms of input ordering)
- Return type:
tuple[bluemira.geometry.compound.BluemiraCompound, list[list[bluemira.geometry.solid.BluemiraSolid]]]
Notes
Labelling will be lost. This function is only tested on solids.
- bluemira.geometry.tools.point_inside_shape(point: collections.abc.Iterable[float], shape: bluemira.geometry.base.BluemiraGeoT) bool
Check whether or not a point is inside a shape.
- Parameters:
point (collections.abc.Iterable[float]) – Coordinates of the point
shape (bluemira.geometry.base.BluemiraGeoT) – Geometry to check with
- Return type:
Whether or not the point is inside the shape
- bluemira.geometry.tools.point_on_plane(point: collections.abc.Iterable[float], plane: bluemira.geometry.plane.BluemiraPlane, tolerance: float = D_TOLERANCE) bool
Check whether or not a point is on a plane.
- Parameters:
point (collections.abc.Iterable[float]) – Coordinates of the point
plane (bluemira.geometry.plane.BluemiraPlane) – Plane to check
tolerance (float) – Tolerance with which to check
- Return type:
Whether or not the point is on the plane
- bluemira.geometry.tools.serialise_shape(shape: bluemira.geometry.base.BluemiraGeoT)
Serialise a BluemiraGeo object.
- Returns:
A serialised BluemiraGeo object.
- Parameters:
shape (bluemira.geometry.base.BluemiraGeoT)
- bluemira.geometry.tools.deserialise_shape(buffer: dict) bluemira.geometry.base.BluemiraGeoT | None
Deserialise a BluemiraGeo object obtained from serialise_shape.
- Parameters:
buffer (dict) – Object serialisation as stored by serialise_shape
- Return type:
The deserialised BluemiraGeo object.
- bluemira.geometry.tools.get_shape_by_name(shape: bluemira.geometry.base.BluemiraGeoT, name: str) list[bluemira.geometry.base.BluemiraGeoT]
Search through the boundary of the shape and get any shapes with a label corresponding to the provided name. Includes the shape itself if the name matches its label.
- Parameters:
shape (bluemira.geometry.base.BluemiraGeoT) – The shape to search for the provided name.
name (str) – The name to search for.
- Return type:
The shapes known to the provided shape that correspond to the provided name.
- bluemira.geometry.tools.find_clockwise_angle_2d(base: numpy.ndarray, vector: numpy.ndarray) numpy.ndarray
Find the clockwise angle between the 2D vectors
baseandvectorin the range [0°, 360°).- Parameters:
base (numpy.ndarray) – The vector to start the angle from.
vector (numpy.ndarray) – The vector to end the angle at.
- Return type:
The clockwise angle between the two vectors in degrees.
- Raises:
TypeError – both base and vector must be arrays
ValueError – Array shapes must be (2, N)