ifcopenshell.util.shape_builder

Module Contents

class ifcopenshell.util.shape_builder.ShapeBuilder(ifc_file: ifcopenshell.file)
circle(center: mathutils.Vector = Vector((0.0, 0.0)).freeze(), radius: float = 1.0) ifcopenshell.entity_instance
Parameters:
  • center (Vector, optional) – circle 2D position, defaults to zero-vector

  • radius (float, optional) – radius of the circle, defaults to 1.0

Returns:

IfcCircle

Return type:

ifcopenshell.entity_instance

create_axis2_placement_3d(position: VectorTuple = (0.0, 0.0, 0.0), z_axis: VectorTuple = (0.0, 0.0, 1.0), x_axis: VectorTuple = (1.0, 0.0, 0.0)) ifcopenshell.entity_instance

Create IfcAxis2Placement3D.

Parameters:
  • position (VectorTuple, optional) – placement position (Axis), defaults to (0.0, 0.0, 0.0)

  • z_axis (VectorTuple, optional) – local Z axis direction, defaults to (0.0, 0.0, 1.0)

  • x_axis (VectorTuple, optional) – local X axis direction (RefDirection), defaults to (1.0, 0.0, 0.0)

Returns:

IfcAxis2Placement3D

Return type:

ifcopenshell.entity_instance

create_axis2_placement_3d_from_matrix(matrix: numpy.typing.NDArray[numpy.float64] | None = None) ifcopenshell.entity_instance

Create IfcAxis2Placement3D from numpy matrix.

Parameters:

matrix (npt.NDArray[np.float64], optional) – 4x4 transformation matrix, defaults to np.eye(4)

Returns:

IfcAxis2Placement3D

Return type:

ifcopenshell.entity_instance

create_ellipse_curve(x_axis_radius: float, y_axis_radius: float, position=Vector((0.0, 0.0)).freeze(), trim_points: Sequence[mathutils.Vector] = (), ref_x_direction: mathutils.Vector = Vector((1.0, 0.0)), trim_points_mask: Sequence[int] = ()) ifcopenshell.entity_instance

Ellipse trimming points should be specified in counter clockwise order.

For example, if you need to get the part of the ellipse ABOVE y-axis, you need to use mask (0,2). Below y-axis - (2,0)

For more information about trim_points_mask check builder.get_trim_points_from_mask

Notion: trimmed ellipse also contains polyline between trim points, meaning IfcTrimmedCurve could be used for further extrusion.

create_swept_disk_solid(path_curve: ifcopenshell.entity_instance, radius: float) ifcopenshell.entity_instance

Create IfcSweptDiskSolid from path_curve (must be 3D) and radius

create_transition_arc_ifc(width: str, height: str, create_ifc_curve: bool = False) tuple[list[mathutils.Vector], list[tuple[int, int], ifcopenshell.entity_instance | None]]
create_z_profile_lips_curve(FirstFlangeWidth: float, SecondFlangeWidth: float, Depth: float, Girth: float, WallThickness: float, FilletRadius: float) ifcopenshell.entity_instance
curve_between_two_points(points: tuple[mathutils.Vector, mathutils.Vector]) ifcopenshell.entity_instance

Simple circle based curve between two points Good for creating curves and fillets, won’t work for continuous ellipse shapes.

deep_copy(element: ifcopenshell.entity_instance) ifcopenshell.entity_instance
extrude(profile_or_curve: ifcopenshell.entity_instance, magnitude: float = 1.0, position: mathutils.Vector = Vector([0.0, 0.0, 0.0]).freeze(), extrusion_vector: mathutils.Vector = Vector((0.0, 0.0, 1.0)).freeze(), position_z_axis: mathutils.Vector = Vector((0.0, 0.0, 1.0)).freeze(), position_x_axis: mathutils.Vector = Vector((1.0, 0.0, 0.0)).freeze(), position_y_axis: mathutils.Vector | None = None) ifcopenshell.entity_instance

Extrude profile or curve to get IfcExtrudedAreaSolid.

REMEMBER when handling custom axes - IFC is using RIGHT handed coordinate system.

Position and position axes are in world space, extrusion vector in placement space defined by position_x_axis/position_y_axis/position_z_axis

NOTE: changing position also changes the resulting geometry origin.

extrude_face_set(points: list[mathutils.Vector], magnitude: float, extrusion_vector: mathutils.Vector = V(0, 0, 1).freeze(), offset: mathutils.Vector | None = None, start_cap: bool = True, end_cap: bool = True) ifcopenshell.entity_instance

Method to extrude by creating face sets rather than creating IfcExtrudedAreaSolid.

Useful if your representation is already using face sets and you need to avoid using SweptSolid to assure CorrectItemsForType.

Parameters:
  • points (list[Vector]) – list of points, assuming they form consecutive closed polyline.

  • magnitude (float) – extrusion magnitude

  • extrusion_vector (Vector, optional) – extrusion direction, by default it’s extruding by Z+ axis

  • offset (Vector, optional) – offset from the points

  • start_cap (bool, optional) – if True, create start cap, by default it’s True

  • end_cap (bool, optional) – if True, create end cap, by default it’s True

Returns:

IfcPolygonalFaceSet

Return type:

ifcopenshell.entity_instance

extrude_kwargs(axis: Literal['Y', 'X', 'Z']) dict[str, mathutils.Vector]

Shortcut to get kwargs for ShapeBuilder.extrude to extrude by some axis.

It assumes you have 2D profile in:

XZ plane for Y axis extrusion,

YZ plane for X axis extrusion,

XY plane for Z axis extrusion,

Extruding by X/Y using other kwargs might break ValidExtrusionDirection.

get_axis2_placement_3d_matrix(axis2_placement_3d: ifcopenshell.entity_instance) mathutils.Matrix

Generate a Matrix from IfcAxis2Placement3D.

Parameters:

axis2_placement_3d (ifcopenshell.entity_instance) – IfcAxis2Placement3D

Returns:

generated matrix

Return type:

Matrix

get_polyline_coords(polyline: ifcopenshell.entity_instance) list[mathutils.Vector]

polyline should be either IfcIndexedPolyCurve or IfcPolyline

get_rectangle_coords(size: mathutils.Vector = Vector((1.0, 1.0)).freeze(), position: mathutils.Vector | None = None) list[mathutils.Vector]

Get rectangle coords arranged as below:

3 2
0 1
Parameters:
  • size (Vector, optional) – rectangle size, could be either 2d or 3d, defaults to (1,1)

  • position (Vector, optional) – rectangle position, default to None. if position not specified zero-vector will be used

Returns:

list of rectangle coords

Return type:

List[Vector]

get_representation(context: ifcopenshell.entity_instance, items: ifcopenshell.entity_instance | list[ifcopenshell.entity_instance], representation_type: str | None = None) ifcopenshell.entity_instance

Create IFC representation for the specified context and items.

Parameters:
  • context (ifcopenshell.entity_instance) – IfcGeometricRepresentationSubContext

  • items – could be a list or single curve/IfcExtrudedAreaSolid

  • representation_type (str, optional) – Explicitly specified RepresentationType, defaults to None. If not provided it will be guessed from the items types

Returns:

IfcShapeRepresentation

Return type:

ifcopenshell.entity_instance

get_simple_2dcurve_data(coords: list[mathutils.Vector], fillets: Sequence[int] = (), fillet_radius: Sequence[float] = (), closed: bool = True, create_ifc_curve: bool = False) tuple[list[mathutils.Vector], list[tuple[int, int], ifcopenshell.entity_instance | None]]

Creates simple 2D curve from set of 2d coords and list of points with fillets. Simple curve means that all fillets are based on 90 degree angle.

> coords: list of 2d coords. Example: ((x0,y0), (x1,y1), (x2, y2)) > fillets: list of points from coords to base fillet on. Example: (1,) > fillet_radius: list of fillet radius for each of corresponding point form fillets. Example: (5.,) Note: filler_radius could be just 1 float value if it’s the same for all fillets.

Optional arguments: > closed: boolean whether curve should be closed (whether last point connected to first one). Default: True > create_ifc_curve: create IfcIndexedPolyCurve or just return the data. Default: False

< returns (points, segments, ifc_curve) for the created simple curve if both points in e are equally far from pt, then v1 is returned.

get_trim_points_from_mask(x_axis_radius: float, y_axis_radius: float, trim_points_mask: list[int], position_offset: mathutils.Vector | None = None) list[mathutils.Vector]

Handy way to get edge points of the ellipse like shape of a given radiuses.

Mask points are numerated from 0 to 3 ccw starting from (x_axis_radius/2; 0).

Example: mask (0, 1, 2, 3) will return points (x, 0), (0, y), (-x, 0), (0, -y)

mep_bend_shape(segment, start_length: float, end_length: float, angle: float, radius: float, bend_vector: mathutils.Vector, flip_z_axis: bool) ifcopenshell.entity_instance
Parameters:
  • segment (ifcopenshell.entity_instance) – IfcFlowSegment for a bend. Note that for a bend start and end segments types should match.

  • angle (float) – bend angle, in radians

  • radius (float) – bend radius

  • bend_vector (Vector) – offset between start and end segments in local space of start segment used mainly to determine the second bend axis and it’s direction (positive or negative), the actual magnitude of the vector is not important (though near zero values will be ignored).

  • flip_z_axis (bool) – since we cannot determine z axis direction from the profile offset, there is an option to flip it if bend is going by start segment Z- axis.

Returns:

tuple of Model/Body/MODEL_VIEW IfcRepresentation and transition shape data

mep_transition_calculate(start_half_dim, end_half_dim, offset, diff=None, end_profile=False, angle=None, length=None, verbose=True)

will return transition length based on the profile dimension differences and offset.

If length is provided will return transition angle

mep_transition_length(start_half_dim, end_half_dim, angle, profile_offset=V(0, 0).freeze(), verbose=True)

get the final transition length for two profiles dimensions, angle and XY offset between them,

the difference from calculate_transition - get_transition_length is making sure that length will fit both sides of the transition

mep_transition_shape(start_segment, end_segment, start_length, end_length, angle=30.0, profile_offset=V(0, 0).freeze())

returns tuple of Model/Body/MODEL_VIEW IfcRepresentation and transition shape data

mirror(curve_or_item: ifcopenshell.entity_instance | list[ifcopenshell.entity_instance], mirror_axes: mathutils.Vector = Vector((1.0, 1.0)).freeze(), mirror_point: mathutils.Vector = Vector((0.0, 0.0)).freeze(), create_copy: bool = False, placement_matrix: mathutils.Matrix | None = None) ifcopenshell.entity_instance | list[ifcopenshell.entity_instance]

mirror_axes - along which axes mirror will be applied

For example, mirroring A(1,0) by axis (1,0) will result in A’(-1,0)

mirror_2d_point(point_2d: mathutils.Vector, mirror_axes: mathutils.Vector = Vector((1.0, 1.0)).freeze(), mirror_point: mathutils.Vector = Vector((0.0, 0.0)).freeze()) mathutils.Vector

mirror_axes - along which axes mirror will be applied

plane(location: mathutils.Vector = Vector((0.0, 0.0, 0.0)).freeze(), normal: mathutils.Vector = Vector((0.0, 0.0, 1.0)).freeze()) ifcopenshell.entity_instance

Create IfcPlane.

Parameters:
  • location (Vector, optional) – plane position, defaults to (0.0, 0.0, 0.0)

  • normal (Vector, optional) – plane normal direction, defaults to (0.0, 0.0, 1.0)

Returns:

IfcPlane

Return type:

ifcopenshell.entity_instance

polygonal_face_set(points: list[mathutils.Vector], faces: list[list[int]]) ifcopenshell.entity_instance

Generate an IfcPolygonalFaceSet.

Parameters:
  • points – rectangle size, could be either 2d or 3d, defaults to (1,1)

  • faces – list of faces consisted of point indices (points indices starting from 0)

Returns:

IfcPolygonalFaceSet

polyline(points: list[mathutils.Vector], closed: bool = False, position_offset: mathutils.Vector | None = None, arc_points: list[int] = []) ifcopenshell.entity_instance

Generate an IfcIndexedPolyCurve based on the provided points.

Parameters:
  • points (list[Vector]) – List of 2d or 3d points

  • closed (bool, optional) – Whether polyline should be closed. Default is False

  • position_offset (Vector, optional) – offset to be applied to all points

  • arc_points (list[int], optional) – Indices of the middle points for arcs. For creating an arc segment, provide 3 points: arc_start, arc_middle and arc_end to points and add the arc_middle point’s index to arc_points

Returns:

IfcIndexedPolyCurve

Return type:

ifcopenshell.entity_instance

Example:

# rectangle
points = Vector((0, 0)), Vector((1, 0)), Vector((1, 1)), Vector((0, 1))
position = Vector((2, 0))
# #2=IfcIndexedPolyCurve(#1,(IfcLineIndex((1,2,3,4,1))),$)
polyline = builder.polyline(points, closed=True, position_offset=position)

# arc between points (1,0) and (0,1). Second point in the arc should be it's middle
points = Vector((1, 0)), Vector((0.707, 0.707)), Vector((0, 1)), Vector((0,2))
arc_points = (1,) # point with index 1 is a middle of the arc
# 4=IfcIndexedPolyCurve(#3,(IfcArcIndex((1,2,3)),IfcLineIndex((3,4,1))),$)
curved_polyline = builder.polyline(points, closed=False, position_offset=position, arc_points=arc_points)
profile(outer_curve: ifcopenshell.entity_instance, name: str | None = None, inner_curves: Sequence[ifcopenshell.entity_instance] = (), profile_type: str = 'AREA') ifcopenshell.entity_instance
rectangle(size: mathutils.Vector = Vector((1.0, 1.0)).freeze(), position: mathutils.Vector = None) ifcopenshell.entity_instance

Generate a rectangle polyline.

Parameters:
  • size (Vector, optional) – rectangle size, could be either 2d or 3d, defaults to (1,1)

  • position (Vector, optional) – rectangle position, default to None. if position not specified zero-vector will be used

Returns:

IfcIndexedPolyCurve

Return type:

ifcopenshell.entity_instance

rotate(curve_or_item: ifcopenshell.entity_instance | list[ifcopenshell.entity_instance], angle: float = 90, pivot_point: mathutils.Vector = Vector((0.0, 0.0)).freeze(), counter_clockwise: bool = False, create_copy: bool = False) ifcopenshell.entity_instance | list[ifcopenshell.entity_instance]
rotate_2d_point(point_2d: mathutils.Vector, angle=90, pivot_point: mathutils.Vector = Vector((0.0, 0.0)).freeze(), counter_clockwise=False) mathutils.Vector
rotate_extrusion_kwargs_by_z(kwargs: dict[str, Any], angle: float, counter_clockwise: bool = False) dict[str, mathutils.Vector]

shortcut to rotate extrusion kwargs by z axis

kwargs expected to have position_x_axis and position_z_axis keys

angle is a rotation value in radians

by default rotation is clockwise, to make it counter clockwise use counter_clockwise flag

set_polyline_coords(polyline: ifcopenshell.entity_instance, coords: list[mathutils.Vector]) None

polyline should be either IfcIndexedPolyCurve or IfcPolyline

sphere(radius: float = 1.0, center: VectorTuple = (0.0, 0.0, 0.0)) ifcopenshell.entity_instance
Parameters:
  • radius (float, optional) – radius of the sphere, defaults to 1.0

  • center (VectorTuple, optional) – sphere position, defaults to (0.0, 0.0, 0.0)

Returns:

IfcSphere

Return type:

ifcopenshell.entity_instance

translate(curve_or_item: ifcopenshell.entity_instance | list[ifcopenshell.entity_instance], translation: mathutils.Vector, create_copy: bool = False) ifcopenshell.entity_instance | list[ifcopenshell.entity_instance]
file
ifcopenshell.util.shape_builder.is_x(value, x, si_conversion=None)
ifcopenshell.util.shape_builder.PRECISION = 1e-05
ifcopenshell.util.shape_builder.V
ifcopenshell.util.shape_builder.VectorTuple

tuple of 3 float values

ifcopenshell.util.shape_builder.round_to_precision
ifcopenshell.util.shape_builder.round_vector_to_precision
ifcopenshell.util.shape_builder.sign