Skip to content

Distance to facade

Pesudocode

# initialization
import numpy, topogenesis, ...

# load lattice
read lattice.csv & transform to lattice

# find the facade
define stencil

insider = []
for i in lattice.find_neighbors(stencil):
    inside = True
    for n in i:
        if n is not avail:
            inside = False
    if inside:
        insider.append(i)

facade = avail_lattice
for i in insider:
    facade[i[0],i[1],:] = False

# calculate distance to facade
define lattice_cens, facade_locs

dist_m = []
for voxel_cen in lattice_cens:
    dist_v = []
    for facade_cen in facade_locs:
        dist_v.append(distance voxel_cen to facade_cen)
    dist_m.append(dist_v)
min_dist = np.array(dist_m).min(axis=1)

make min_dist a lattice: envelope_eu_dist_lattice
envelope_eu_dist_lattice += 1

# visualization and saving
visualize
save to csv

0. Initialization

0.1. Importing packages and lattices

import os
import topogenesis as tg
import pyvista as pv
import trimesh as tm
import numpy as np

# convert mesh to pv_mesh
def tri_to_pv(tri_mesh):
    faces = np.pad(tri_mesh.faces, ((0, 0),(1,0)), 'constant', constant_values=3)
    pv_mesh = pv.PolyData(tri_mesh.vertices, faces)
    return pv_mesh
# loading the lattice from csv
lattice_path = os.path.relpath('../Data/dynamic output/voxelized_envelope_cut.csv')
avail_lattice = tg.lattice_from_csv(lattice_path)
init_avail_lattice = tg.to_lattice(np.copy(avail_lattice), avail_lattice)

0.2. Defining neighbourhood and facade

# creating neighborhood definition
stencil = tg.create_stencil("von_neumann", 1, 1)
insider = []
for i in avail_lattice.find_neighbours(stencil):
    inside = True
    for n in i:
        neigh_3d_id = np.unravel_index(n, init_avail_lattice.shape)
        if not avail_lattice[neigh_3d_id]:
            inside = False
    if inside:
        insider.append(np.unravel_index(i[0], init_avail_lattice.shape))

facade = avail_lattice
for i in insider:
    facade[i[0],i[1],:] = False

0.3. Visualizing facade

# initiating the plotter
p = pv.Plotter()

# fast visualization of the lattice
init_avail_lattice.fast_vis(p, color="66ccff")
facade.fast_vis(p)

# plotting
p.show()

1. Distance to facade

1.1 Calculating distance to facade

lattice_cens = init_avail_lattice.centroids_threshold(-1)
facade_locs = facade.centroids_threshold(0)

dist_m = []
for voxel_cen in lattice_cens:
    dist_v = []
    for facade_location in facade_locs:
        diff = voxel_cen - facade_location
        diff_p2 = diff**2
        diff_p2s = diff_p2.sum()
        dist = diff_p2s**0.5
        dist_v.append(dist)
    dist_m.append(dist_v)
dist_m = np.array(dist_m)
min_dist = dist_m.min(axis=1)
eu_distance_lattice = tg.to_lattice(min_dist.reshape(init_avail_lattice.shape), init_avail_lattice)

envelope_eu_dist_lattice = eu_distance_lattice * init_avail_lattice
envelope_eu_dist_lattice[init_avail_lattice==False] -= 1
envelope_eu_dist_lattice +=1

1.2. Visualizing distance to facade

# initiating the plotter
p = pv.Plotter()

l = envelope_eu_dist_lattice

# Create the spatial reference
grid = pv.UniformGrid()

# Set the grid dimensions: shape because we want to inject our values
grid.dimensions = l.shape
# The bottom left corner of the data set
grid.origin = l.minbound
# These are the cell sizes along each axis
grid.spacing = l.unit

# Add the data values to the cell data
grid.point_arrays["Distance from Facade"] = l.flatten(order="F")  # Flatten the Lattice

# adding the volume
p.add_volume(grid, cmap="Oranges", shade=False, show_scalar_bar=True)

# plotting
p.show()

Saving to csv

csv_path = os.path.relpath('../Data/dynamic output/dist_fac.csv')
envelope_eu_dist_lattice.to_csv(csv_path)

Credits

__author__ = "Shervin Azadi and Pirouz Nourian"
__license__ = "MIT"
__version__ = "1.0"
__url__ = "https://github.com/shervinazadi/spatial_computing_workshops"
__summary__ = "Spatial Computing Design Studio Workshop on Solar Envelope"