Created
January 20, 2025 19:15
-
-
Save petrasvestartas/bca880892542882afe53fd0fb119a055 to your computer and use it in GitHub Desktop.
BlockModel from barrel vault
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@classmethod | |
def from_barrel_vault( | |
cls, | |
span: float = 6.0, | |
length: float = 6.0, | |
thickness: float = 0.25, | |
rise: float = 0.6, | |
vou_span: int = 9, | |
vou_length: int = 6, | |
zero_is_centerline_or_lowestpoint: bool = False, | |
) -> "BlockModel": | |
""" | |
Creates block elements from the barrel vault geometry. | |
Parameters | |
---------- | |
span : float | |
span of the vault | |
length : float | |
length of the vault perpendicular to the span | |
thickness : float | |
thickness of the vault | |
rise : float | |
rise of the vault from 0.0 to middle axis of the vault thickness | |
vou_span : int | |
number of voussoirs in the span direction | |
vou_length : int | |
number of voussoirs in the length direction | |
zero_is_centerline_or_lowestpoint : bool | |
if True, the lowest point of the vault is at the center line of the arch, otherwise the center line of the vault is lowest mesh z-coordinate. | |
Returns | |
------- | |
list[:class:`compas.datastructures.Mesh`] | |
A list of meshes representing the geometry of the barrel vault. | |
""" | |
radius: float = rise / 2 + span**2 / (8 * rise) | |
top: list[float] = [0, 0, rise] | |
left: list[float] = [-span / 2, 0, 0] | |
center: list[float] = [0.0, 0.0, rise - radius] | |
vector: list[float] = subtract_vectors(left, center) | |
springing: float = angle_vectors(vector, [-1.0, 0.0, 0.0]) | |
sector: float = radians(180) - 2 * springing | |
angle: float = sector / vou_span | |
a: list[float] = [0, -length / 2, rise - (thickness / 2)] | |
d: list[float] = add_vectors(top, [0, -length / 2, (thickness / 2)]) | |
R: Rotation = Rotation.from_axis_and_angle([0, 1.0, 0], 0.5 * sector, center) | |
bottom: list[list[float]] = transform_points([a, d], R) | |
brick_pts: list[list[list[float]]] = [] | |
for i in range(vou_span + 1): | |
R_angle: Rotation = Rotation.from_axis_and_angle([0, 1.0, 0], -angle * i, center) | |
points: list[list[float]] = transform_points(bottom, R_angle) | |
brick_pts.append(points) | |
depth: float = length / vou_length | |
grouped_data: list[list[float]] = [pair[0] + pair[1] for pair in zip(brick_pts, brick_pts[1:])] | |
meshes: list[Mesh] = [] | |
for i in range(vou_length): | |
for l, group in enumerate(grouped_data): # noqa: E741 | |
is_support: bool = l == 0 or l == (len(grouped_data) - 1) | |
if l % 2 == 0: | |
point_l: list[list[float]] = [group[0], group[1], group[2], group[3]] | |
point_list: list[list[float]] = [ | |
[group[0][0], group[0][1] + (depth * i), group[0][2]], | |
[group[1][0], group[1][1] + (depth * i), group[1][2]], | |
[group[2][0], group[2][1] + (depth * i), group[2][2]], | |
[group[3][0], group[3][1] + (depth * i), group[3][2]], | |
] | |
p_t: list[list[float]] = translate_points(point_l, [0, depth * (i + 1), 0]) | |
vertices: list[list[float]] = point_list + p_t | |
faces: list[list[int]] = [[0, 1, 3, 2], [0, 4, 5, 1], [4, 6, 7, 5], [6, 2, 3, 7], [1, 5, 7, 3], [2, 6, 4, 0]] | |
mesh: Mesh = Mesh.from_vertices_and_faces(vertices, faces) | |
mesh.attributes["is_support"] = is_support | |
meshes.append(mesh) | |
else: | |
point_l: list[list[float]] = [group[0], group[1], group[2], group[3]] | |
points_base: list[list[float]] = translate_points(point_l, [0, depth / 2, 0]) | |
points_b_t: list[list[float]] = translate_points(points_base, [0, depth * i, 0]) | |
points_t: list[list[float]] = translate_points(points_base, [0, depth * (i + 1), 0]) | |
vertices: list[list[float]] = points_b_t + points_t | |
if i != vou_length - 1: | |
faces: list[list[int]] = [[0, 1, 3, 2], [0, 4, 5, 1], [4, 6, 7, 5], [6, 2, 3, 7], [1, 5, 7, 3], [2, 6, 4, 0]] | |
mesh: Mesh = Mesh.from_vertices_and_faces(vertices, faces) | |
mesh.attributes["is_support"] = is_support | |
meshes.append(mesh) | |
for l, group in enumerate(grouped_data): # noqa: E741 | |
is_support: bool = l == 0 or l == (len(grouped_data) - 1) | |
if l % 2 != 0: | |
point_l: list[list[float]] = [group[0], group[1], group[2], group[3]] | |
p_t: list[list[float]] = translate_points(point_l, [0, depth / 2, 0]) | |
vertices: list[list[float]] = point_l + p_t | |
faces: list[list[int]] = [[0, 1, 3, 2], [0, 4, 5, 1], [4, 6, 7, 5], [6, 2, 3, 7], [1, 5, 7, 3], [2, 6, 4, 0]] | |
mesh: Mesh = Mesh.from_vertices_and_faces(vertices, faces) | |
mesh.attributes["is_support"] = is_support | |
meshes.append(mesh) | |
point_f: list[list[float]] = translate_points(point_l, [0, length, 0]) | |
p_f: list[list[float]] = translate_points(point_f, [0, -depth / 2, 0]) | |
vertices: list[list[float]] = p_f + point_f | |
faces: list[list[int]] = [[0, 1, 3, 2], [0, 4, 5, 1], [4, 6, 7, 5], [6, 2, 3, 7], [1, 5, 7, 3], [2, 6, 4, 0]] | |
mesh: Mesh = Mesh.from_vertices_and_faces(vertices, faces) | |
mesh.attributes["is_support"] = is_support | |
meshes.append(mesh) | |
# Find the lowest z-coordinate and move all the block to zero. | |
if not zero_is_centerline_or_lowestpoint: | |
min_z: float = min([min(mesh.vertex_coordinates(key)[2] for key in mesh.vertices()) for mesh in meshes]) | |
for mesh in meshes: | |
mesh.translate([0, 0, -min_z]) | |
# Translate blocks to xy frame and create blockmodel. | |
blockmodel: BlockModel = BlockModel() | |
for mesh in meshes: | |
origin: Point = mesh.face_polygon(5).frame.point | |
xform: Transformation = Transformation.from_frame_to_frame( | |
Frame(origin, mesh.vertex_point(0) - mesh.vertex_point(2), mesh.vertex_point(4) - mesh.vertex_point(2)), Frame.worldXY() | |
) | |
mesh_xy: Mesh = mesh.transformed(xform) | |
# brep: Brep = Brep.from_mesh(mesh_xy) | |
block: BlockElement = BlockElement(shape=mesh_xy, is_support=mesh_xy.attributes["is_support"]) | |
block.transformation = xform.inverse() | |
blockmodel.add_element(block) | |
return blockmodel |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment