Blocks

The examples shown in this section were created using RV2 v1.0.0. They will be updated soon, and be compatible with the latest release of RV2.

from compas.datastructures import Mesh
from compas_rhino.artists import MeshArtist

FILE_I1 = 'form_idos.json'
FILE_I2 = 'form_edos.json'

FILE_O = 'blocks.json'

idos = Mesh.from_json(FILE_I1)
edos = Mesh.from_json(FILE_I2)

blocks = []

for face in idos.faces():
    bottom = idos.face_coordinates(face)
    top = edos.face_coordinates(face)

    f = len(bottom)

    faces = [
        list(range(f)),
        list(range(f + f - 1, f - 1, -1))]

    for i in range(f - 1):
        faces.append([i, i + f, i + f + 1, i + 1])
    faces.append([f - 1, f + f - 1, f, 0])

    block = Mesh.from_vertices_and_faces(bottom + top, faces)
    blocks.append(block)


with open(FILE_O, 'w+') as f:
    data = [block.to_data()for block in blocks]
    json.dump(data, f)

artist = MeshArtist(None, layer="RV2::Blocks")
artist.clear_layer()

for block in blocks:
    artist.mesh = block
    artist.draw_faces(color=(0, 255, 255), join_faces=True)

artist.redraw()

Blocks with flat top surface

The block geometries generated using the intrados and extrados, which are offsets of the initial mesh, contain two main hexagonal faces that are not planar. If the blocks are to be milled using stone blanks, milling both sides of the stone would be not only time intensive, but also result in loss of precision during the flipping of the blocks.

One way to address this problem, would be to make one of the two hexagonal faces planar so that the block is only milled on one side and does not need to be flipped. This technique was used for the Armadillo Vault, where the inner face of the blocks had double curvature, while the top face remained flat.

import os
import json
from compas.datastructures import Mesh
from compas.geometry import intersection_line_plane
from compas_rhino.artists import MeshArtist
from compas_cloud import Proxy
from compas_rv2.rhino import ErrorHandler

errorHandler = ErrorHandler(title="Server side Error", showLocalTraceback=False)
proxy = Proxy(errorHandler=errorHandler, background=False)
# proxy.restart()

bestfit = proxy.function('compas.geometry.bestfit_plane_numpy')

HERE = os.path.dirname(__file__)
FILE_I = os.path.join(HERE, 'blocks.json')
FILE_O = os.path.join(HERE, 'blocksflat.json')

with open(FILE_I, 'r') as f:
    blocks = [Mesh.from_data(data) for data in json.load(f)]


for block in blocks:
    bottom = block.face_vertices(0)
    top = block.face_vertices(1)[::-1]

    bottom_points = block.vertices_attributes('xyz', keys=bottom)
    top_points = block.vertices_attributes('xyz', keys=top)

    plane = bestfit(top_points)
    
    top_new = []
    for a, b in zip(bottom_points, top_points):
        b = intersection_line_plane((a, b), plane)
        top_new.append(b)
    
    for vertex, point in zip(top, top_new):
        block.vertex_attributes(vertex, 'xyz', point)


with open(FILE_O, 'w+') as f:
    data = [block.to_data()for block in blocks]
    json.dump(data, f)

artist = MeshArtist(None, layer="RV2::BlocksFlat")
artist.clear_layer()

for block in blocks:
    artist.mesh = block
    artist.draw_faces(color=(0, 255, 0), join_faces=True)

artist.redraw()

Blocks to origin with flat face on bottom

import os
import json
from compas.geometry import subtract_vectors, cross_vectors
from compas.geometry import Frame, Transformation
from compas.datastructures import Mesh
from compas_rhino.artists import MeshArtist

HERE = os.path.dirname(__file__)
FILE_I = os.path.join(HERE, 'blocksflat.json')

with open(FILE_I, 'r') as f:
    blocks = [Mesh.from_data(data) for data in json.load(f)]

world = Frame.worldXY()

for block in blocks:
    point = block.face_centroid(1)
    normal = block.face_normal(1)
    vertices = block.face_vertices(1)
    xaxis = subtract_vectors(block.vertex_attributes(vertices[0], 'xyz'), point)
    yaxis = cross_vectors(xaxis, normal)
    local = Frame(point, xaxis, yaxis)
    X = Transformation.from_frame_to_frame(local, world)
    block.transform(X)

artist = MeshArtist(None, layer="RV2::BlocksTransformed")
artist.clear_layer()

for block in blocks:
    artist.mesh = block
    artist.draw_faces(color=(0, 255, 0), join_faces=True)

artist.redraw()

Last updated