bluemira.codes._freecadapi ========================== .. py:module:: bluemira.codes._freecadapi .. autoapi-nested-parse:: Supporting functions for the bluemira geometry module. Attributes ---------- .. autoapisummary:: bluemira.codes._freecadapi.apiVertex bluemira.codes._freecadapi.apiVector bluemira.codes._freecadapi.apiEdge bluemira.codes._freecadapi.apiWire bluemira.codes._freecadapi.apiFace bluemira.codes._freecadapi.apiShell bluemira.codes._freecadapi.apiSolid bluemira.codes._freecadapi.apiShape bluemira.codes._freecadapi.apiSurface bluemira.codes._freecadapi.apiPlacement bluemira.codes._freecadapi.apiPlane bluemira.codes._freecadapi.apiCompound bluemira.codes._freecadapi.WORKING_PRECISION bluemira.codes._freecadapi.MIN_PRECISION bluemira.codes._freecadapi.MAX_PRECISION bluemira.codes._freecadapi.ONE_PERIOD Classes ------- .. autoapisummary:: bluemira.codes._freecadapi.JoinType bluemira.codes._freecadapi.Document bluemira.codes._freecadapi._CADType bluemira.codes._freecadapi.CADFileType bluemira.codes._freecadapi.ExporterProtocol bluemira.codes._freecadapi.ImporterProtocol bluemira.codes._freecadapi.DefaultDisplayOptions Functions --------- .. autoapisummary:: bluemira.codes._freecadapi.catch_caderr bluemira.codes._freecadapi.arrange_edges bluemira.codes._freecadapi.check_data_type bluemira.codes._freecadapi.vector_to_list bluemira.codes._freecadapi.point_to_list bluemira.codes._freecadapi.vertex_to_list bluemira.codes._freecadapi.vector_to_numpy bluemira.codes._freecadapi.point_to_numpy bluemira.codes._freecadapi.vertex_to_numpy bluemira.codes._freecadapi.make_solid bluemira.codes._freecadapi.make_shell bluemira.codes._freecadapi.make_compound bluemira.codes._freecadapi.make_polygon bluemira.codes._freecadapi.make_bezier bluemira.codes._freecadapi.make_bspline bluemira.codes._freecadapi.make_bsplinesurface bluemira.codes._freecadapi.interpolate_bspline bluemira.codes._freecadapi.make_bspline_g1_blend bluemira.codes._freecadapi.make_circle_curve bluemira.codes._freecadapi.make_circle bluemira.codes._freecadapi.make_circle_arc_3P bluemira.codes._freecadapi.make_ellipse bluemira.codes._freecadapi.offset_wire bluemira.codes._freecadapi.make_face bluemira.codes._freecadapi._get_api_attr bluemira.codes._freecadapi.length bluemira.codes._freecadapi.area bluemira.codes._freecadapi.volume bluemira.codes._freecadapi.center_of_mass bluemira.codes._freecadapi.is_null bluemira.codes._freecadapi.is_closed bluemira.codes._freecadapi.is_valid bluemira.codes._freecadapi.is_same bluemira.codes._freecadapi.bounding_box bluemira.codes._freecadapi.optimal_bounding_box bluemira.codes._freecadapi.tessellate bluemira.codes._freecadapi.start_point bluemira.codes._freecadapi.end_point bluemira.codes._freecadapi.ordered_vertexes bluemira.codes._freecadapi.vertexes bluemira.codes._freecadapi.orientation bluemira.codes._freecadapi.edges bluemira.codes._freecadapi.ordered_edges bluemira.codes._freecadapi.wires bluemira.codes._freecadapi.faces bluemira.codes._freecadapi.shells bluemira.codes._freecadapi.solids bluemira.codes._freecadapi.normal_at bluemira.codes._freecadapi.wire_closure bluemira.codes._freecadapi.close_wire bluemira.codes._freecadapi.discretise bluemira.codes._freecadapi.discretise_by_edges bluemira.codes._freecadapi.dist_to_shape bluemira.codes._freecadapi.wire_value_at bluemira.codes._freecadapi.wire_parameter_at bluemira.codes._freecadapi.split_wire bluemira.codes._freecadapi._split_edge bluemira.codes._freecadapi._get_closest_edge_idx bluemira.codes._freecadapi.slice_shape bluemira.codes._freecadapi._slice_wire bluemira.codes._freecadapi._slice_solid bluemira.codes._freecadapi.import_cad bluemira.codes._freecadapi.webgl_export bluemira.codes._freecadapi.stepz_import bluemira.codes._freecadapi.meshed_exporter bluemira.codes._freecadapi.save_as_STP bluemira.codes._freecadapi._scale_obj bluemira.codes._freecadapi.save_cad bluemira.codes._freecadapi.scale_shape bluemira.codes._freecadapi.translate_shape bluemira.codes._freecadapi.rotate_shape bluemira.codes._freecadapi.mirror_shape bluemira.codes._freecadapi.revolve_shape bluemira.codes._freecadapi.extrude_shape bluemira.codes._freecadapi._split_wire bluemira.codes._freecadapi.sweep_shape bluemira.codes._freecadapi.loft bluemira.codes._freecadapi.fillet_wire_2D bluemira.codes._freecadapi.join_connect bluemira.codes._freecadapi.boolean_fuse bluemira.codes._freecadapi.boolean_cut bluemira.codes._freecadapi.boolean_fragments bluemira.codes._freecadapi.point_inside_shape bluemira.codes._freecadapi._edges_tangent bluemira.codes._freecadapi._wire_edges_tangent bluemira.codes._freecadapi._wire_is_planar bluemira.codes._freecadapi._wire_is_straight bluemira.codes._freecadapi._is_wire_or_face bluemira.codes._freecadapi._check_shapes_same_type bluemira.codes._freecadapi._check_shapes_coplanar bluemira.codes._freecadapi._shapes_are_coplanar bluemira.codes._freecadapi._shapes_are_coaxis bluemira.codes._freecadapi._make_shapes_coaxis bluemira.codes._freecadapi.fix_shape bluemira.codes._freecadapi.make_placement bluemira.codes._freecadapi.make_placement_from_matrix bluemira.codes._freecadapi.move_placement bluemira.codes._freecadapi.make_placement_from_vectors bluemira.codes._freecadapi.change_placement bluemira.codes._freecadapi.make_plane bluemira.codes._freecadapi.make_plane_from_3_points bluemira.codes._freecadapi.face_from_plane bluemira.codes._freecadapi.plane_from_shape bluemira.codes._freecadapi.placement_from_plane bluemira.codes._freecadapi._colourise bluemira.codes._freecadapi.collect_verts_faces bluemira.codes._freecadapi.collect_wires bluemira.codes._freecadapi.show_cad bluemira.codes._freecadapi.rotate_into_position bluemira.codes._freecadapi.embedLight bluemira.codes._freecadapi.extract_attribute bluemira.codes._freecadapi.serialise_shape bluemira.codes._freecadapi.deserialise_shape bluemira.codes._freecadapi._convert_edge_to_curve Module Contents --------------- .. py:data:: apiVertex .. py:data:: apiVector .. py:data:: apiEdge .. py:data:: apiWire .. py:data:: apiFace .. py:data:: apiShell .. py:data:: apiSolid .. py:data:: apiShape .. py:data:: apiSurface .. py:data:: apiPlacement .. py:data:: apiPlane .. py:data:: apiCompound .. py:data:: WORKING_PRECISION :value: 1e-05 .. py:data:: MIN_PRECISION :value: 1e-05 .. py:data:: MAX_PRECISION :value: 1e-05 .. py:data:: ONE_PERIOD .. py:function:: catch_caderr(new_error_type) Catch CAD errors with given error :returns: the wrapped function .. py:function:: arrange_edges(old_wire: apiWire, new_wire: apiWire) -> apiWire A helper to try and fix some topological naming issues. Tries to arrange edges as they were in the old wire :param old_wire: old wire to emulate edges from :param new_wire: new wire to change edge arrangement :returns: Wire with arranged edges .. py:function:: check_data_type(data_type) Decorator to check the data type of the first parameter input (args[0]) of a function. :returns: Decorator enforcing a certain datatype :raises TypeError: If args[0] objects are not instances of data_type .. py:function:: vector_to_list(vectors: list[apiVector]) -> list[list[float]] Converts a FreeCAD Base.Vector or list(Base.Vector) into a list .. py:function:: point_to_list(points: list[Part.Point]) -> list[list[float]] Converts a FreeCAD Part.Point or list(Part.Point) into a list .. py:function:: vertex_to_list(vertexes: list[apiVertex]) -> list[list[float]] Converts a FreeCAD Part.Vertex or list(Part.Vertex) into a list .. py:function:: vector_to_numpy(vectors: list[apiVector]) -> numpy.ndarray Converts a FreeCAD Base.Vector or list(Base.Vector) into a numpy array .. py:function:: point_to_numpy(points: list[Part.Point]) -> numpy.ndarray Converts a FreeCAD Part.Point or list(Part.Point) into a numpy array .. py:function:: vertex_to_numpy(vertexes: list[apiVertex]) -> numpy.ndarray Converts a FreeCAD Part.Vertex or list(Part.Vertex) into a numpy array .. py:function:: make_solid(shell: apiShell) -> apiSolid Make a solid from a shell. .. py:function:: make_shell(faces: list[apiFace]) -> apiShell Make a shell from faces. .. py:function:: make_compound(shapes: list[apiShape]) -> apiCompound Make an FreeCAD compound object out of many shapes :param shapes: A set of objects to be compounded :rtype: A compounded set of shapes .. py:function:: make_polygon(points: list | numpy.ndarray) -> apiWire Make a polygon from a set of points. :param points: list of points. It can be given as a list of 3D tuples, a 3D numpy array, or similar. :returns: A FreeCAD wire that contains the polygon .. py:function:: make_bezier(points: list | numpy.ndarray) -> apiWire Make a bezier curve from a set of points. :param points: list of points. It can be given as a list of 3D tuples, a 3D numpy array, or similar. :returns: A FreeCAD wire that contains the bezier curve .. py:function:: 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) -> apiWire Builds a B-Spline by a lists of Poles, Mults, Knots :param poles: list of poles. :param mults: list of integers for the multiplicity :param knots: list of knots :param periodic: Whether or not the spline is periodic (same curvature at start and end points) :param degree: bspline degree :type degree: int :param weights: sequence of float :param check_rational: Whether or not to check if the BSpline is rational (not sure) :returns: A FreeCAD wire that contains the bspline curve .. rubric:: Notes This function wraps the FreeCAD function of bsplines buildFromPolesMultsKnots .. py:function:: 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 = False, check_rational: bool = False) -> apiSurface Builds a B-SplineSurface by a lists of Poles, Mults, Knots :param poles: poles (sequence of Base.Vector). :param mults_u: list of integers for the u-multiplicity :param mults_v: list of integers for the u-multiplicity :param knot_vector_u: list of u-knots :param knot_vector_v: list of v-knots :param degree_u: degree of NURBS in u-direction :param degree_v: degree of NURBS in v-direction :param weights: pole weights (sequence of float). :param periodic: Whether or not the spline is periodic (same curvature at start and end points) :param check_rational: Whether or not to check if the BSpline is rational (not sure) :returns: A FreeCAD object that contours the bsplinesurface .. rubric:: Notes This function wraps the FreeCAD function of bsplinesurface buildFromPolesMultsKnots .. py:function:: interpolate_bspline(points: list | numpy.ndarray, *, closed: bool = False, start_tangent: collections.abc.Iterable | None = None, end_tangent: collections.abc.Iterable | None = None) -> apiWire Make a B-Spline curve by interpolating a set of points. :param points: list of points. It can be given as a list of 3D tuples, a 3D numpy array, or similar. :param closed: if True, the first and last points will be connected in order to form a closed shape. :param start_tangent: Tangency of the BSpline at the first pole. Must be specified with end_tangent :param end_tangent: Tangency of the BSpline at the last pole. Must be specified with start_tangent :returns: A FreeCAD wire that contains the bspline curve :raises InvalidCADInputsError: Not enough points to interpolate :raises FreeCADError: Unable to make spline .. py:function:: make_bspline_g1_blend(edge1: apiEdge, edge2: apiEdge, scale=0.2) -> apiWire Create a G1-continuous B-spline blend between two edges. This function generates a B-spline curve that connects `edge1` and `edge2` while attempting to enforce G1 (tangent) continuity. The curve is constructed by blending the tangents of the edges at their connection points. :param edge1: The first edge to connect. The blend will attach to either its start or end, depending on `at_end1`. :type edge1: apiEdge :param edge2: The second edge to connect. The blend will attach to either its start or end, depending on `at_start2`. :type edge2: apiEdge :param scale: Scale factor for the tangent vector length used in the blend (default is 0.1). :type scale: float, optional :returns: A B-spline wire representing the blend curve between `edge1` and `edge2`. :rtype: apiWire :raises FreeCADError: If the edges are coincident .. rubric:: Notes This is hot garbage. Tangency is not reliable. .. py:function:: make_circle_curve(radius: float, center: apiVector, axis: apiVector) -> Part.Circle Make a Part.Circle with a consistent .Rotation property, by initializing a circle of the default size, position and orientation at first. :param radius: radius of the circle [m] :param center: center of the circle [m] :param axis: Normalised vector around which the circle spins counter-clockwise. :returns: Part.Circle created by FreeCAD. :rtype: circle .. py:function:: make_circle(radius: float = 1.0, center: collections.abc.Iterable[float] = [0.0, 0.0, 0.0], start_angle: float = 0.0, end_angle: float = 360.0, axis: collections.abc.Iterable[float] = [0.0, 0.0, 1.0]) -> apiWire Create a circle or arc of circle object with given parameters. :param radius: Radius of the circle :param center: Center of the circle :param start_angle: Start angle of the arc [degrees] :param end_angle: End angle of the arc [degrees]. If start_angle == end_angle, a circle is created, otherwise a circle arc is created :param axis: Normal vector to the circle plane. It defines the clockwise/anticlockwise circle orientation according to the right hand rule. Default [0., 0., 1.]. :returns: FreeCAD wire that contains the arc or circle .. py:function:: make_circle_arc_3P(p1: collections.abc.Iterable[float], p2: collections.abc.Iterable[float], p3: collections.abc.Iterable[float], axis: collections.abc.Iterable[float] | None = None) -> apiWire Create an arc of circle object given three points. :param p1: Starting point of the circle arc :param p2: Middle point of the circle arc :param p3: End point of the circle arc :returns: FreeCAD wire that contains the arc of circle :raises FreeCADError: Raised if the three points are collinear. .. py:function:: make_ellipse(center: collections.abc.Iterable[float] = [0.0, 0.0, 0.0], major_radius: float = 2.0, minor_radius: float = 1.0, major_axis: collections.abc.Iterable[float] = [1, 0, 0], minor_axis: collections.abc.Iterable[float] = [0, 1, 0], start_angle: float = 0.0, end_angle: float = 360.0) -> apiWire Creates an ellipse or arc of ellipse object with given parameters. :param center: Center of the ellipse :param major_radius: the major radius of the ellipse :param minor_radius: the minor radius of the ellipse :param major_axis: major axis direction :param minor_axis: minor axis direction :param start_angle: Start angle of the arc [degrees] :param end_angle: End angle of the arc [degrees]. If start_angle == end_angle, an ellipse is created, otherwise an arc of ellipse is created :returns: FreeCAD wire that contains the ellipse or arc of ellipse .. py:class:: JoinType Bases: :py:obj:`enum.IntEnum` .. autoapi-inheritance-diagram:: bluemira.codes._freecadapi.JoinType :parts: 1 :private-bases: See Part/PartEnums.py, its not importable .. py:attribute:: Arc :value: 0 .. py:attribute:: Tangent :value: 1 .. py:attribute:: Intersect :value: 2 .. py:function:: offset_wire(wire: apiWire, thickness: float, join: str = 'intersect', *, open_wire: bool = True) -> apiWire Make an offset from a wire. :param wire: Wire to offset from :param thickness: Offset distance. Positive values outwards, negative values inwards :param join: Offset method. "arc" gives rounded corners, and "intersect" gives sharp corners :param open_wire: 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. :returns: Offset wire :raises InvalidCADInputsError: Wire must be planar and cannot be straight :raises FreeCADError: offset failed .. py:function:: make_face(wire: apiWire) -> apiFace Make a face given a wire boundary. :param wire: Wire boundary from which to make a face :returns: Face created from the wire boundary :raises FreeCADError: If the created face is invalid .. py:function:: _get_api_attr(obj: apiShape, prop: str) .. py:function:: length(obj: apiShape) -> float Object's length .. py:function:: area(obj: apiShape) -> float Object's Area .. py:function:: volume(obj: apiShape) -> float Object's volume .. py:function:: center_of_mass(obj: apiShape) -> numpy.ndarray Object's center of mass .. py:function:: is_null(obj: apiShape) -> bool True if obj is null .. py:function:: is_closed(obj: apiShape) -> bool True if obj is closed .. py:function:: is_valid(obj) -> bool True if obj is valid .. py:function:: is_same(obj1: apiShape, obj2: apiShape) -> bool True if obj1 and obj2 have the same shape. .. py:function:: bounding_box(obj: apiShape) -> tuple[float, float, float, float, float, float] Object's bounding box .. py:function:: optimal_bounding_box(obj: apiShape) -> tuple[float, float, float, float, float, float] Object's optimal bounding box .. py:function:: tessellate(obj: apiShape, tolerance: float) -> tuple[numpy.ndarray, numpy.ndarray] Tessellate a geometry object. :param obj: Shape to tessellate :param tolerance: Tolerance with which to perform the operation :returns: * *vertices* -- Array of the vertices (N, 3, dtype=float) from the tesselation operation * *indices* -- Array of the indices (M, 3, dtype=int) from the tesselation operation :raises ValueError: If the tolerance is <= 0.0 .. rubric:: Notes Once tesselated an object's properties may change. Tesselation cannot be reverted to a previous lower value, but can be increased (irreversibly). .. py:function:: start_point(obj: apiShape) -> numpy.ndarray The start point of the object .. py:function:: end_point(obj: apiShape) -> numpy.ndarray The end point of the object .. py:function:: ordered_vertexes(obj: apiShape) -> numpy.ndarray Ordered vertexes of the object .. py:function:: vertexes(obj: apiShape) -> numpy.ndarray Wires of the object .. py:function:: orientation(obj: apiShape) -> bool True if obj is valid .. py:function:: edges(obj: apiShape) -> list[apiWire] Edges of the object .. py:function:: ordered_edges(obj: apiShape) -> numpy.ndarray Ordered edges of the object .. py:function:: wires(obj: apiShape) -> list[apiWire] Wires of the object .. py:function:: faces(obj: apiShape) -> list[apiFace] Faces of the object .. py:function:: shells(obj: apiShape) -> list[apiShell] Shells of the object .. py:function:: solids(obj: apiShape) -> list[apiSolid] Solids of the object .. py:function:: normal_at(face: apiFace, alpha_1: float = 0.0, alpha_2: float = 0.0) -> numpy.ndarray :returns: The normal vector of the face at a parameterised point in space. For planar faces, the normal is the same everywhere. .. py:function:: wire_closure(wire: apiWire) -> apiWire Create a line segment wire that closes an open wire :returns: The closure segment .. py:function:: close_wire(wire: apiWire) -> apiWire Closes a wire with a line segment, if not already closed. :returns: A new closed wire. .. py:function:: discretise(w: apiWire, ndiscr: int = 10, dl: float | None = None) -> numpy.ndarray Discretise a wire. :param w: wire to be discretised. :param ndiscr: number of points for the whole wire discretisation. :param dl: target discretisation length (default None). If dl is defined, ndiscr is not considered. :returns: Array of points :raises ValueError: If ndiscr < 2 If dl <= 0.0 .. py:function:: discretise_by_edges(w: apiWire, ndiscr: int = 10, dl: float | None = None) -> numpy.ndarray Discretise a wire taking into account the edges of which it consists of. :param w: Wire to be discretised. :param ndiscr: Number of points for the whole wire discretisation. :param dl: Target discretisation length (default None). If dl is defined, ndiscr is not considered. :returns: Array of points :raises ValueError: dl <= 0 .. rubric:: Notes Final number of points can be slightly different due to edge discretisation routine. .. py:function:: dist_to_shape(shape1: apiShape, shape2: apiShape) -> tuple[float, list[tuple[numpy.ndarray, numpy.ndarray]]] Find the minimum distance between two shapes :param shape1: reference shape. :param shape2: target shape. :returns: * *dist* -- Minimum distance * *vectors* -- List of tuples corresponding to the nearest points (numpy.ndarray) between shape1 and shape2. The distance between those points is the minimum distance given by dist. .. py:function:: wire_value_at(wire: apiWire, distance: float) -> numpy.ndarray Get a point a given distance along a wire. :param wire: Wire along which to get a point :param distance: Distance :returns: Wire point value at distance .. py:function:: wire_parameter_at(wire: apiWire, vertex: collections.abc.Iterable[float], tolerance: float = EPS_FREECAD) -> float Get the parameter value at a vertex along a wire. :param wire: Wire along which to get the parameter :param vertex: Vertex for which to get the parameter :param tolerance: Tolerance within which to get the parameter :returns: Parameter value along the wire at the vertex :raises FreeCADError:: If the vertex is further away to the wire than the specified tolerance .. py:function:: split_wire(wire: apiWire, vertex: collections.abc.Iterable[float], tolerance: float) -> tuple[apiWire | None, apiWire | None] Split a wire at a given vertex. :param wire: Wire to be split :param vertex: Vertex at which to split the wire :param tolerance: 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 FreeCADError: If the vertex is further away to the wire than the specified tolerance .. py:function:: _split_edge(edge, parameter) :param edge: The Part.Edge to be splitted :param parameter: the parameter :returns: * *edge_1* -- The edge from its minimum parameter up to the user-provided parameter. If length=0, then return None. * *edge_2* -- The edge from the user-provided parameter up to its maximum parameter. If length=0, then return None. :raises FreeCADError: Thrown if the provided parameter is outside of the edge's valid parameter range. .. py:function:: _get_closest_edge_idx(wire, vertex) .. py:function:: slice_shape(shape: apiShape, plane_origin: collections.abc.Iterable[float], plane_axis: collections.abc.Iterable[float]) Slice a shape along a given plane :param shape: shape to slice :param plane_origin: plane origin :param plane_axis: normal plane axis .. rubric:: Notes Degenerate cases such as tangents to solid or faces do not return intersections if the shape and plane are acting at the Plane base. Further investigation needed. .. py:function:: _slice_wire(wire, normal_plane, shift, *, BIG_NUMBER=100000.0) Get the plane intersection points of any wire (possibly anything, needs testing) .. py:function:: _slice_solid(obj, normal_plane, shift) Get the plane intersection wires of a face or solid .. py:class:: Document(shapes: collections.abc.Iterable[apiShape] | None = None, labels: collections.abc.Iterable[str] | None = None, doc_name: str = 'Bluemira_FreeCAD_wrapper') Context manager to wrap freecad document creation .. py:attribute:: shapes :value: None .. py:attribute:: labels :value: None .. py:attribute:: doc_name :value: 'Bluemira_FreeCAD_wrapper' .. py:method:: __enter__() .. py:method:: parts() -> collections.abc.Iterator[Part.Feature] Get FreeCAD parts. Converts shapes to FreeCAD Part.Features to enable saving and viewing :Yields: Each object in document :raises ValueError: Number of objects not equal to number of labels .. py:method:: __exit__(exc_type, exc_value, exc_tb) .. py:class:: _CADType CAD file type definition .. py:attribute:: file_extensions :type: str | tuple[str, Ellipsis] .. py:attribute:: export_module :type: str | None :value: None .. py:attribute:: import_module :type: str | None :value: None .. py:method:: __post_init__() .. py:method:: __contains__(value: str) -> bool .. py:method:: __eq__(value: str | _CADType) -> bool .. py:method:: __hash__() .. py:property:: ext .. py:method:: exporter() -> ExporterProtocol .. py:method:: importer() -> ImporterProtocol .. py:class:: CADFileType(*args, **kwds) Bases: :py:obj:`enum.Enum` .. autoapi-inheritance-diagram:: bluemira.codes._freecadapi.CADFileType :parts: 1 :private-bases: FreeCAD standard export filetypes .. rubric:: Notes Some filetypes my require additional dependencies see: https://wiki.freecad.org/Import_Export .. py:attribute:: ASCII_STEREO_MESH .. py:attribute:: ADDITIVE_MANUFACTURING .. py:attribute:: ASC .. py:attribute:: AUTOCAD .. py:attribute:: AUTOCAD_DXF .. py:attribute:: BDF .. py:attribute:: BINMESH .. py:attribute:: BREP .. py:attribute:: CSG .. py:attribute:: DAE .. py:attribute:: DAT .. py:attribute:: FREECAD .. py:attribute:: FENICS_FEM .. py:attribute:: FENICS_FEM_XML .. py:attribute:: GLTRANSMISSION .. py:attribute:: IFC_BIM .. py:attribute:: IFC_BIM_JSON .. py:attribute:: IGES .. py:attribute:: INP .. py:attribute:: INVENTOR_V2_1 .. py:attribute:: JSON .. py:attribute:: JSON_MESH .. py:attribute:: MED .. py:attribute:: MESHJSON .. py:attribute:: MESHPY .. py:attribute:: MESHYAML .. py:attribute:: OBJ .. py:attribute:: OBJ_WAVE .. py:attribute:: OFF .. py:attribute:: OPENSCAD .. py:attribute:: PCD .. py:attribute:: PLY .. py:attribute:: PLY_STANFORD .. py:attribute:: SIMPLE_MODEL .. py:attribute:: STEP .. py:attribute:: STEP_ZIP .. py:attribute:: STL .. py:attribute:: SVG_FLAT .. py:attribute:: TETGEN_FEM .. py:attribute:: UNV .. py:attribute:: VTK .. py:attribute:: VTU .. py:attribute:: WEBGL .. py:attribute:: YAML .. py:attribute:: Z88_FEM_MESH .. py:attribute:: Z88_FEM_MESH_2 .. py:method:: _missing_(value: str) -> CADFileType :classmethod: .. py:method:: unitless_formats() -> tuple[CADFileType, Ellipsis] :classmethod: :returns: CAD formats that don't need to be converted because they are unitless .. py:method:: manual_mesh_formats() -> tuple[CADFileType, Ellipsis] :classmethod: CAD formats that need to have meshed objects. .. py:method:: not_importable_formats() -> tuple[CADFileType, Ellipsis] :classmethod: .. py:method:: mesh_import_formats() -> tuple[CADFileType, Ellipsis] :classmethod: .. py:method:: ext() -> str .. py:method:: exporter() -> ExporterProtocol Get exporter module for each filetype :raises FreeCADError: Unable to save file type .. py:method:: importer() -> ImporterProtocol Get importer module for each filetype :raises FreeCADError: Unable to import file type .. py:class:: ExporterProtocol Bases: :py:obj:`Protocol` .. autoapi-inheritance-diagram:: bluemira.codes._freecadapi.ExporterProtocol :parts: 1 :private-bases: Typing for CAD exporter .. py:method:: __call__(objs: list[Part.Feature], filename: str, **kwargs) Export CAD protocol .. py:class:: ImporterProtocol Bases: :py:obj:`Protocol` .. autoapi-inheritance-diagram:: bluemira.codes._freecadapi.ImporterProtocol :parts: 1 :private-bases: Typing for CAD importer .. py:method:: __call__(filename: str, document: str, **kwargs) Import CAD protocol .. py:function:: import_cad(file: str | pathlib.Path, filetype: CADFileType | str | None = None, unit_scale: str = 'm', **kwargs) -> list[tuple[apiShape, str]] Import CAD objects from file :returns: The imported shapes .. py:function:: webgl_export(export_func: ExporterProtocol) -> ExporterProtocol Webgl exporter for offscreen rendering .. py:function:: stepz_import(import_func: ImporterProtocol) -> ImporterProtocol Step z importer "needs" more FreeCADGui so we're patching it out .. py:function:: meshed_exporter(cad_format: CADFileType, export_func: ExporterProtocol) -> ExporterProtocol Meshing and then exporting CAD in certain formats. .. py:function:: save_as_STP(shapes: list[apiShape], filename: str = 'test') Saves a series of Shape objects as a STEP assembly :param shapes: Iterable of shape objects to be saved :param filename: Full path filename of the STP assembly :raises FreeCADError: Shape is null .. rubric:: Notes This uses the legacy method to save to STP files. It doesn't require freecad documents but also doesn't allow much customisation. Part builds in millimetres therefore we need to scale to metres to be consistent with our units. .. py:function:: _scale_obj(objs, scale: float = 1000) Scale objects .. rubric:: Notes Since the scale function modifies directly the shape, a copy of the shape is made to avoid modification of the original shapes. The scale of Part is in mm by default therefore we scale by 1000 to convert to metres. .. py:function:: save_cad(shapes: collections.abc.Iterable[apiShape], filename: str, cad_format: str | CADFileType = 'stp', labels: collections.abc.Iterable[str] | None = None, doc_name: str = 'Bluemira_FreeCAD_wrapper', **kwargs) Save CAD in a given file format :param shapes: CAD shape objects to save :param filename: filename (file extension will be forced base on `cad_format`) :param cad_format: file cad_format :param labels: shape labels :param kwargs: passed to freecad preferences configuration :raises FreeCADError: Unable to save to format .. rubric:: Notes Part builds in millimetres therefore we need to scale to metres to be consistent with our units .. py:function:: scale_shape(shape: apiShape, factor: float) -> apiShape Apply scaling with factor to the shape :param shape: The shape to be scaled :param factor: The scaling factor :returns: The scaled shape .. py:function:: translate_shape(shape: apiShape, vector: tuple[float, float, float]) -> apiShape Apply scaling with factor to the shape :param shape: The shape to be scaled :param vector: The translation vector :returns: The translated shape .. py:function:: rotate_shape(shape: apiShape, base: tuple[float, float, float] = (0.0, 0.0, 0.0), direction: tuple[float, float, float] = (0.0, 0.0, 1.0), degree: float = 180) -> apiShape Apply the rotation (base, dir, degree) to this shape :param shape: The shape to be rotated :param base: Origin location of the rotation :param direction: The direction vector :param degree: rotation angle :returns: The rotated shape .. py:function:: mirror_shape(shape: apiShape, base: tuple[float, float, float], direction: tuple[float, float, float]) -> apiShape Mirror a shape about a plane. :param shape: Shape to mirror :param base: Mirror plane base point :param direction: Mirror plane direction :returns: The mirrored shape .. py:function:: revolve_shape(shape: apiShape, base: tuple[float, float, float] = (0.0, 0.0, 0.0), direction: tuple[float, float, float] = (0.0, 0.0, 1.0), degree: float = 180.0) -> apiShape Apply the revolve (base, dir, degree) to this shape :param shape: The shape to be revolved :param base: Origin location of the revolution :param direction: The direction vector :param degree: revolution angle :returns: The revolved shape. .. py:function:: extrude_shape(shape: apiShape, vec: tuple[float, float, float]) -> apiShape Apply the extrusion along vec to this shape :param shape: The shape to be extruded :param vec: The vector along which to extrude :returns: The extruded shape. .. py:function:: _split_wire(wire) Split a wire into two parts at mid point or middle edge. :returns: * The first split * The second split .. py:function:: sweep_shape(profiles: collections.abc.Iterable[apiWire], path: apiWire, *, solid: bool = True, frenet: bool = True, transition: int = 0) -> apiShell | apiSolid Sweep a a set of profiles along a path. :param profiles: Set of profiles to sweep :param path: Path along which to sweep the profiles :param solid: Whether or not to create a Solid :param frenet: If true, the orientation of the profile(s) is calculated based on local curvature and tangency. For planar paths, should not make a difference. :returns: Swept geometry object :raises FreeCADError: Wires must be all open or all closed and edges must be consecutively tangent .. py:function:: loft(profiles: collections.abc.Iterable[apiWire], *, solid: bool = False, ruled: bool = False, closed: bool = False) -> apiShell | apiSolid Loft between a set of profiles. :param profiles: Profile(s) to loft between :param solid: Whether or not to create a Solid :param ruled: Create a ruled shape :rtype: Lofted geometry object .. py:function:: fillet_wire_2D(wire: apiWire, radius: float, *, chamfer: bool = False) -> apiWire Fillet or chamfer a two-dimensional wire, returning a new wire :param wire: Wire to be filleted or chamfered :param radius: Radius of the fillet or chamfer operation :param chamfer: Whether to chamfer or not :type chamfer: bool (default=False) :rtype: Resulting filleted or chamfered wire .. py:function:: join_connect(shapes: collections.abc.Iterable[apiShape], dist_tolerance: float) -> apiShape Connects the interiors of two walled objects (e.g. pipes). It can also join shells and wires. :returns: Result of the join connect operation. :raises FreeCADError: In case the boolean operation fails. :raises TypeError: Shapes must be in a list :raises ValueError: At least 2 shapes must be given .. rubric:: Notes See https://wiki.freecad.org/Part_JoinConnect .. py:function:: boolean_fuse(shapes: collections.abc.Iterable[apiShape], *, remove_splitter: bool = True) -> apiShape Fuse two or more shapes together. Internal splitter are removed. :param shapes: List of FreeCAD shape objects to be fused together. All the objects in the list must be of the same type. :param remove_splitter: if True, shape is refined removing extra edges. See(https://wiki.freecadweb.org/Part_RefineShape) :rtype: Result of the boolean operation. :raises FreeCADError: In case the boolean operation fails. :raises TypeError: Shapes must be in a list :raises ValueError: At least 2 shapes must be given .. py:function:: boolean_cut(shape: apiShape, tools: list[apiShape], *, split: bool = True) -> list[apiShape] Difference of shape and a given (list of) topo shape cut(tools) :param shape: the reference object :param tools: List of FreeCAD shape objects to be used as tools. :param split: If True, shape is split into pieces based on intersections with tools. :rtype: Result of the boolean operation. .. py:function:: boolean_fragments(shapes: list[apiSolid], tolerance: float = 0.0) -> tuple[apiCompound, list[apiSolid]] Split a list of shapes into their Boolean fragments. :param shapes: List of BluemiraSolids to be split into Boolean fragments :param tolerance: 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) :raises FreeCADError: Boolean operation failed .. py:function:: point_inside_shape(point: collections.abc.Iterable[float], shape: apiShape) -> bool Whether or not a point is inside a shape. :param point: Coordinates of the point :param shape: Geometry to check with :returns: Whether or not the point is inside the shape .. py:function:: _edges_tangent(edge_1, edge_2) -> bool Check if two adjacent edges are tangent to one another. .. py:function:: _wire_edges_tangent(wire) -> bool Check that all consecutive edges in a wire are tangent .. py:function:: _wire_is_planar(wire) -> bool Check if a wire is planar. .. py:function:: _wire_is_straight(wire) -> bool Check if a wire is a straight line. .. py:function:: _is_wire_or_face(shape_type) .. py:function:: _check_shapes_same_type(shapes) Check that all the shapes are of the same type. :raises ValueError: shapes must all be the same type .. py:function:: _check_shapes_coplanar(shapes) .. py:function:: _shapes_are_coplanar(shapes) -> bool Check if a list of shapes are all coplanar. First shape is taken as the reference. .. py:function:: _shapes_are_coaxis(shapes) -> bool Check if a list of shapes are all co-axis. First shape is taken as the reference. .. py:function:: _make_shapes_coaxis(shapes) Make a list of shapes co-axis by reversing. First shape is taken as the reference. .. py:function:: fix_shape(shape: apiShape, precision: float = EPS_FREECAD, min_length: float = MINIMUM_LENGTH) Fix a shape by removing any small edges and joining the remaining edges. :param shape: Shape to fix :param precision: General precision with which to work :param min_length: Minimum edge length .. py:function:: make_placement(base: collections.abc.Iterable[float], axis: collections.abc.Iterable[float], angle: float) -> apiPlacement Make a FreeCAD Placement :param base: a vector representing the Placement local origin :type base: Iterable :param axis: axis of rotation :type axis: Iterable :param angle: rotation angle in degree .. py:function:: make_placement_from_matrix(matrix: numpy.ndarray) -> apiPlacement Make a FreeCAD Placement from a 4 x 4 matrix. :param matrix: 4 x 4 matrix from which to make the placement :raises FreeCADError: Must be 4x4 matrix .. rubric:: Notes Matrix should be of the form: [cos_11, cos_12, cos_13, dx] [cos_21, cos_22, cos_23, dy] [cos_31, cos_32, cos_33, dz] [ 0, 0, 0, 1] .. py:function:: move_placement(placement: apiPlacement, vector: collections.abc.Iterable[float]) Moves the FreeCAD Placement along the given vector :param placement: the FreeCAD placement to be modified :param vector: direction along which the placement is moved .. py:function:: make_placement_from_vectors(base: collections.abc.Iterable[float] = [0, 0, 0], vx: collections.abc.Iterable[float] = [1, 0, 0], vy: collections.abc.Iterable[float] = [0, 1, 0], vz: collections.abc.Iterable[float] = [0, 0, 1], order: str = 'ZXY') -> apiPlacement Create a placement from three directional vectors .. py:function:: change_placement(geo: apiShape, placement: apiPlacement) Change the placement of a FreeCAD object :param geo: the object to be modified :param placement: the FreeCAD placement to be modified .. py:function:: make_plane(base: tuple[float, float, float] = (0.0, 0.0, 0.0), axis: tuple[float, float, float] = (0.0, 0.0, 1.0)) -> apiPlane Creates a FreeCAD plane with a given location and normal :param base: a reference point in the plane :param axis: normal vector to the plane :rtype: Plane from base and axis .. py:function:: make_plane_from_3_points(point1: tuple[float, float, float] = (0.0, 0.0, 0.0), point2: tuple[float, float, float] = (1.0, 0.0, 0.0), point3: tuple[float, float, float] = (0.0, 1.0, 0.0)) -> apiPlane Creates a FreeCAD plane defined by three non-linear points :param point1: a reference point in the plane :param point2: a reference point in the plane :param point3: a reference point in the plane :rtype: Plane from three points .. py:function:: face_from_plane(plane: apiPlane, width: float, height: float) -> apiFace Creates a FreeCAD face from a Plane with specified height and width. .. note:: Face is centred on the Plane Position. With respect to the global coordinate system, the face placement is given by a simple rotation of the z axis. :param plane: the reference plane :param width: output face width :param height: output face height :returns: Face from plane .. py:function:: plane_from_shape(shape: apiShape) -> apiPlane :returns: A plane if the shape is planar .. py:function:: placement_from_plane(plane: apiPlane) -> apiPlacement :returns: A placement from a plane with the origin on the plane base and the z-axis directed as the plane normal. .. py:function:: _colourise(node: pivy.coin.SoNode, options: dict) .. py:function:: collect_verts_faces(solid: apiShape, tesselation: float = 0.1) -> tuple[numpy.ndarray | None, Ellipsis] Collects vertices and faces of parts and tessellates them for the CAD viewer :param solid: FreeCAD Part :param tesselation: amount of tessellation for the mesh :returns: * *vertices* -- Vertices * *faces* -- Faces .. py:function:: collect_wires(solid: apiShape, **kwds) -> tuple[numpy.ndarray, numpy.ndarray] Collects vertices and edges of parts and discretises them for the CAD viewer :param solid: FreeCAD Part :returns: * *vertices* -- Vertices * *edges* -- Edges .. py:class:: DefaultDisplayOptions Freecad default display options .. py:attribute:: colour :type: bluemira.utilities.tools.ColourDescriptor .. py:attribute:: transparency :type: float :value: 0.0 .. py:property:: color :type: str See colour .. py:function:: show_cad(parts: apiShape | list[apiShape], options: dict | list[dict | None] | None = None, labels: list[str] | None = None, camera_rotation: collections.abc.Iterable[float] = (90, 0, 0), **kwargs) The implementation of the display API for FreeCAD parts. :param parts: The parts to display. :param options: The options to use to display the parts. :param labels: labels to use for each part object :param camera_rotation: rotation in degrees of camera around object, Default looks at the bluemira xz plane. :raises FreeCADError: Number of parts and options must be equal .. py:function:: rotate_into_position(scene: pivy.quarter.QuarterWidget, x_ang: float, y_ang: float, z_ang: float) Rotate camera around object .. py:function:: embedLight(scene, lightdir: tuple[float], intensity: float) -> pivy.coin.SoSeparator Embeds a given coin node inside a shadow group with directional light with the given direction (x,y,z) tuple. :returns: the final coin node .. rubric:: Notes Modified from BIM.OfflineRendingerUtils::embedLight .. py:function:: extract_attribute(func) Decorator for serialise_shape. Convert the function output attributes string list to the corresponding object attributes. The first argument of func is the reference object. :returns: If an output is callable, the output result is returned. .. py:function:: serialise_shape(shape) Serialise a FreeCAD topological data object. :returns: The json-ified shape .. py:function:: deserialise_shape(buffer) Deserialise a FreeCAD topological data object obtained from serialise_shape. :param buffer: Object serialisation as stored by serialise_shape :returns: The deserialised FreeCAD object :raises FreeCADError: Wrapping the OCCError: BRep not done in a more understandable message. .. py:function:: _convert_edge_to_curve(edge: apiEdge) -> Part.LineSegment | Part.Circle | Part.ArcOfCircle | Part.Ellipse | Part.ArcOfEllipse | Part.BezierCurve | Part.BSplineCurve Convert a Freecad Edge to the respective curve. :param edge: FreeCAD Edge, where type(edge.Curve) is one of the following: 1. Part.Line 2. Part.Circle 3. Part.Ellipse 4. Part.BezierCurve 5. Part.BSplineCurve 6. Part.OffsetCurve :returns: FreeCAD Part curve object, corresponding to the input type: 1. Part.Line -> Part.LineSegment 2. Part.Circle -> Part.ArcOfCircle 3. Part.ellipse -> Part.ArcOfEllipse 4. Part.BezierCurve -> Part.BezierCurve 5. Part.BSplineCurve-> Part.BSplineCurve 6. Part.OffsetCurve -> Part.BSplineCurve