Skip to content

Generative Relations: Corridor Generation

In this workshop, we will learn about creation of vertical shafts, path-finding between agents, and constructition of coridor system within the building.

0. Initialization

0.1. Load required libraries

import os
import topogenesis as tg
import pyvista as pv
import trimesh as tm
import numpy as np
import networkx as nx
from sklearn.cluster import KMeans
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib import cm
import pandas as pd
np.random.seed(0)
import pickle

0.2. Define the Neighborhood (Stencil)

# creating neighborhood definition
stencil = tg.create_stencil("von_neumann", 1, 1)
# setting the center to zero
stencil.set_index([0,0,0], 0)
stencil.set_index([0,0,1], 0)
stencil.set_index([0,0,-1], 0)

0.3. Load the envelope lattice as the avialbility lattice

# loading the lattice from csv
lattice_path = os.path.relpath('../data/voxelated_model_3_6.csv')
avail_lattice = tg.lattice_from_csv(lattice_path)
init_avail_lattice = tg.to_lattice(np.copy(avail_lattice), avail_lattice)

0.4. Load Agents Information

# loading program (agents information) from CSV
prgm_path = os.path.relpath('../data/Matrix10.csv')
agn_info = np.genfromtxt(prgm_path, delimiter=',')[1:, 1:]

agn_df = pd.read_csv(prgm_path)

# extract the initial location 
agn_initial_loc = list(agn_df["initial_loc"])

# extract agent ids
agn_ids = list(agn_df["space_id"])

agn_df
space_name space_id Atrium Courtyard Starter_housing Assisted_living Student_housing Supermarket Cafe_restaurant_pub Cinema ... Ent_access_cinema_cafe_arcade Ent_access_atrium sun_access sky_view silent_level_active noise_sensitivity space_area initial_loc 0 floor 1 floor
0 Atrium 0 1.0 1.0 0.0 0.0 0.0 0.2 0.2 0.2 ... 0 1 1.0 0.0 0.6 0.0 188 5984 1 0
1 Courtyard 1 1.0 1.0 0.4 0.4 0.4 0.0 0.0 0.0 ... 0 0 1.0 0.0 0.8 0.0 136 4642 1 0
2 Starter_housing 2 0.0 0.6 1.0 0.2 0.0 0.2 0.0 0.0 ... 0 0 1.0 0.6 1.0 1.0 7252 2148 0 1
3 Assisted_living 3 0.0 0.8 0.2 1.0 0.0 0.4 0.0 0.0 ... 0 0 1.0 0.6 1.0 1.0 2828 5126 0 1
4 Student_housing 4 0.0 0.6 0.0 0.0 1.0 0.2 0.2 0.0 ... 0 0 1.0 0.6 0.6 0.8 7596 10404 0 1
5 Supermarket 5 0.6 0.0 0.0 0.0 0.0 1.0 0.0 0.0 ... 0 0 0.2 0.0 0.0 0.0 624 198 1 0
6 Cafe_restaurant_pub 6 0.6 0.0 0.0 0.0 0.0 0.0 1.0 0.0 ... 1 0 0.4 0.0 0.4 0.2 188 268 1 0
7 Cinema 7 0.4 0.0 0.0 0.0 0.0 0.0 0.0 1.0 ... 1 0 0.0 0.0 0.4 0.0 1296 1504 1 0
8 Arcade 8 0.4 0.0 0.0 0.0 0.2 0.0 0.0 0.2 ... 1 0 0.0 0.0 0.2 0.0 632 7140 1 0
9 Workshops 9 0.4 0.0 0.2 0.2 0.2 0.0 0.0 0.0 ... 0 0 0.8 0.0 0.6 0.6 276 10244 1 0
10 Community_center 10 0.2 0.6 0.0 0.0 0.4 0.0 0.0 0.0 ... 0 0 0.8 0.0 0.8 0.4 100 10948 0 1
11 Co_cooking_center 11 0.0 0.0 0.0 0.0 0.0 0.2 0.0 0.0 ... 0 0 0.8 0.0 0.8 0.2 48 10312 0 1
12 Library 12 0.4 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0 0 1.0 0.0 0.0 1.0 500 9190 1 0
13 Gym 13 0.0 0.2 0.0 0.0 0.6 0.0 0.0 0.0 ... 0 0 0.4 0.0 0.4 0.2 220 9860 0 1
14 Laundry_room 14 0.0 0.2 0.6 0.4 0.4 0.0 0.0 0.0 ... 0 0 0.2 0.0 1.0 0.0 116 10472 0 0
15 Ent_access_courtyard 18 0.0 1.0 0.6 0.6 0.6 0.0 0.0 0.0 ... 0 0 0.0 0.0 0.0 0.0 1 7040 0 0
16 Ent_access_trashroom 19 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0 0 0.0 0.0 0.0 0.0 1 13760 0 0
17 Ent_access_parking 20 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0 0 0.0 0.0 0.0 0.0 1 0 0 0
18 Ent_access_supermarket 21 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 ... 0 0 0.0 0.0 0.0 0.0 1 14064 0 0
19 Ent_access_library 22 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0 0 0.0 0.0 0.0 0.0 1 13904 0 0
20 Ent_access_cinema_cafe_arcade 23 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 ... 1 0 0.0 0.0 0.0 0.0 1 304 0 0
21 Ent_access_atrium 24 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0 1 0.0 0.0 0.0 0.0 1 7344 0 0

22 rows × 32 columns

1. Creation of Vertical Shaft

1.1. Agent initialization

# initialize the occupation lattice
occ_lattice = avail_lattice * 0 - 1

# Finding the index of the available voxels in avail_lattice
avail_flat = avail_lattice.flatten()
avail_index = np.array(np.where(avail_lattice == 1)).T

# count the number of spaces (rows) and intiialize an agent for each space
agn_num = len(agn_info) # this is now based on the number of rows in our table

# Randomly choosing three available voxels
select_id = np.random.choice(len(avail_index), agn_num)
agn_origins = avail_index[select_id]

# adding the origins to the agents locations
agn_locs = []
# for each agent origin ... 
for a_id, a_origin, a_init_loc in zip(agn_ids, agn_origins, agn_initial_loc):
#     if a_init_loc == -1:
#         final_a_origin = a_origin
#     else:
    final_a_origin = np.unravel_index(a_init_loc, avail_lattice.shape)
    # add the origin to the list of agent locations
    agn_locs.append([final_a_origin])

    # set the origin in availablity lattice as 0 (UNavailable)
    avail_lattice[tuple(final_a_origin)] = 0

    # set the origin in occupation lattice as the agent id (a_id)
    occ_lattice[tuple(final_a_origin)] = int(a_id) # this is now based on the id of the agent in the program

with open("../data/startpoint.txt", "wb") as fp:   #Pickling
    pickle.dump(agn_locs, fp)
np.argwhere(occ_lattice == 23)
array([[ 0, 19,  0]], dtype=int64)

1.2. Visualizing the agents seeds

p = pv.Plotter(notebook=True)

base_lattice = occ_lattice

# Set the grid dimensions: shape + 1 because we want to inject our values on the CELL data
grid = pv.UniformGrid()
grid.dimensions = np.array(base_lattice.shape) + 1
# The bottom left corner of the data set
grid.origin = base_lattice.minbound - base_lattice.unit * 0.5
# These are the cell sizes along each axis
grid.spacing = base_lattice.unit 

# adding the boundingbox wireframe
p.add_mesh(grid.outline(), color="grey", label="Domain")

# adding the avilability lattice
# init_avail_lattice.fast_vis(p)

# adding axes

p.add_axes()
p.show_bounds(grid="back", location="back", color="#aaaaaa")

#Make a dictonary for the annotations
space_list = agn_df["space_name"].to_dict()

#make a dictionary for 
sargs = dict(
    shadow = True,
    n_labels = 0,
    italic = False,
    fmt ="%.0f",
    font_family="arial",
    height = 0.6,
    vertical = True,
    position_x = 1.05,
    position_y = 1)


# Add the data values to the cell data
grid.cell_arrays["Agents"] = base_lattice.flatten(order="F").astype(int)  # Flatten the array!
# filtering the voxels

# visualize all agents
threshed = grid.threshold([-0.1, max(agn_ids) + 0.1])

# # visualize a selected agent
# a_id = 22
# threshed = grid.threshold([a_id-0.1, a_id+0.1])

# adding the voxels
p.add_mesh(threshed, name='sphere', show_edges=True, opacity=1.0, show_scalar_bar=True, annotations = space_list, scalar_bar_args=sargs, cmap="tab20b")

# p.add_slider_widget(create_mesh, [0, n_frames], title='Time', value=0, event_type="always", style="classic", pointa=(0.1, 0.1), pointb=(0.9, 0.1))
p.show(use_ipyvtk=True)
[(253.02459757597026, 152.2245973852354, 231.42459588319835),
 (48.60000133514404, -52.19999885559082, 26.99999964237213),
 (0.0, 0.0, 1.0)]

1.3. Cluster the existing voxels and set the vertical column of cluster centers as vertical shafts

# making the clusters and weights for the atrium and courtyard
cluster_1_agents =  [ 0, 7, 8, 6, 20, 21]
cluster_1_weights = [7, 1, 1, 1,  1,  1]
cluster_2_agents =  [ 0, 21, 9, 5, 12, 18, 19]
cluster_2_weights = [7, 1,  1, 1,1,1,1]
cluster_3_agents =  [1, 15, 17, 4, 13, 10]
cluster_3_weights = [1,1,1,1,1,1]
cluster_4_agents =  [1, 3, 2, 12, 15, 16]
cluster_4_weights = [8,1,1,1,1,1]

# put them in a list
cluster_agents = [cluster_1_agents, cluster_2_agents, cluster_3_agents, cluster_4_agents]
cluster_weights = [cluster_1_weights,cluster_2_weights,cluster_3_weights,cluster_4_weights]

# make centers out of the clusters and the extra weights
cluster_centers = []
for ca,cw in zip(cluster_agents,cluster_weights):

    occ_ind_cluster = np.vstack([agn_locs[i]*w for i,w in zip(ca,cw)])

    rough_cen_cluster = occ_ind_cluster.mean(axis=0)
    cen_cluster = np.round(rough_cen_cluster).astype(np.int8)
    cluster_centers.append(cen_cluster)

print(cluster_centers)
[array([14, 14,  1], dtype=int8), array([23, 13,  1], dtype=int8), array([22,  7,  2], dtype=int8), array([17,  8,  2], dtype=int8)]

1.4. Add cluster centres so there are pairs

# init shaft lattice
shft_lattice = occ_lattice * 0

# set the shafts
# shaft_new = np.array([[5,5,1], [13,6,2], [8,9,2], [15,14,3]])
shaft_new = []
for coords in cluster_centers:
    shaft_new.append([(coords[0]-1), coords[1], coords[2]]) 

# have all the cluster centers in 1 list
cluster_final = np.concatenate((cluster_centers, shaft_new), axis=0)

for cl_cen in cluster_final:
    shft_lattice[cl_cen[0],cl_cen[1],:] = 1

#Assign maxium height for shafts, so that they are not taller than the voxelated model
shft_lattice *= avail_lattice

1.5. Visualize Vertical Shafts

p = pv.Plotter(notebook=True)

base_lattice = shft_lattice

# Set the grid dimensions: shape + 1 because we want to inject our values on the CELL data
grid = pv.UniformGrid()
grid.dimensions = np.array(base_lattice.shape) + 1
# The bottom left corner of the data set
grid.origin = base_lattice.minbound - base_lattice.unit * 0.5
# These are the cell sizes along each axis
grid.spacing = base_lattice.unit 

# adding the boundingbox wireframe
p.add_mesh(grid.outline(), color="grey", label="Domain")

# adding the avilability lattice
init_avail_lattice.fast_vis(p)

# adding axes
p.add_axes()
p.show_bounds(grid="back", location="back", color="#aaaaaa")

cluster_final
Function_list = {
    0: "Public noisy traffic space",
    1: "Public quiet traffic space",
    2: "Private noisy traffic space",
    3: "Private quiet traffic space",
    4: "Public noisy traffic space",
    5: "Public quiet traffic space",
    6: "Private noisy traffic space",
    7: "Private quiet traffic space",

    #0 or 1: "Public noisy traffic space",
    #2 or 3: "Public quiet traffic space",
    #4 or 5: "Private noisy traffic space",
    #6 or 7: "Private quiet traffic space",

}
#make a dictionary for 
sargs = dict(
    shadow = True,
    n_labels = 0,
    italic = False,
    fmt ="%.0f",
    font_family="arial",
    height = 0.6,
    vertical = True,
    position_x = 1.05,
    position_y = 1)


# Add the data values to the cell data
grid.cell_arrays["Agents"] = base_lattice.flatten(order="F").astype(int)  # Flatten the array!
# filtering the voxels
threshed = grid.threshold([0.9, 1.1])
# adding the voxels
p.add_mesh(threshed, name='sphere', show_edges=True, opacity=1.0, show_scalar_bar=True, annotations = Function_list, scalar_bar_args=sargs, cmap="tab20b")


# p.add_slider_widget(create_mesh, [0, n_frames], title='Time', value=0, event_type="always", style="classic", pointa=(0.1, 0.1), pointb=(0.9, 0.1))
p.show(use_ipyvtk=True)
[(253.02459757597026, 152.2245973852354, 231.42459588319835),
 (48.60000133514404, -52.19999885559082, 26.99999964237213),
 (0.0, 0.0, 1.0)]

2. Creation of Horizontal Corridors

2.1. Extract the connectivity graph from the lattice based on the horizontal stencil

# find the neighbours of a voxel
# take the stencil, lattice and adress of a voxel in that lattice 
def find_neighbours_masked(lattice, stencil, loc):
    neigh_locs = np.argwhere(stencil) - stencil.origin + loc

    neigh_filter = np.all(neigh_locs > -1, axis=1) * np.all(neigh_locs < np.array(lattice.shape), axis=1)
    neigh_3d = neigh_locs[neigh_filter]
# returns the index of the neigbhours of that voxel
    neigh_1d = [np.ravel_multi_index(n_loc, avail_lattice.shape) for n_loc in neigh_3d]
    return(neigh_1d)
find_neighbours_masked(init_avail_lattice, stencil, loc = [0,19,0])
[288, 624]
# find the number of all voxels
vox_count = init_avail_lattice.size 

# initialize the adjacency matrix
adj_mtrx = np.zeros((vox_count,vox_count))

# Finding the index of the available voxels in avail_lattice
avail_index = np.array(np.where(init_avail_lattice == 1)).T

# fill the adjacency matrix using the list of all neighbours
for vox_loc in avail_index:
    # find the 1D id
    vox_id = np.ravel_multi_index(vox_loc, init_avail_lattice.shape)
    # retrieve the list of neighbours of the voxel based on the stencil
    vox_neighs = find_neighbours_masked(init_avail_lattice, stencil, loc = vox_loc)

    # iterating over the neighbours
    for neigh in vox_neighs:

        # setting the entry to one
        adj_mtrx[vox_id, neigh] = 1.0
# construct the graph 
g = nx.from_numpy_array(adj_mtrx)

2.2. Find the shortest path to the cluster centres seeds and construct the corridor

# define the clusters again
cluster_1_agents = [0, 7, 8, 6, 20, 21]
cluster_2_agents = [0, 21, 9, 5, 12, 18, 19]
cluster_3_agents = [1, 15, 17, 4, 13, 10]
cluster_4_agents = [1, 3, 2, 12, 15, 16]

cluster_agents = [cluster_1_agents, cluster_2_agents, cluster_3_agents, cluster_4_agents]
cluster_centers = []
for ca in cluster_agents:

    occ_ind_cluster = np.vstack([agn_locs[i] for i in ca])
    rough_cen_cluster = occ_ind_cluster.mean(axis=0)
    cen_cluster = np.round(rough_cen_cluster).astype(np.int8)
    cluster_centers.append(cen_cluster)

# initialize corridor lattice
cor_lattice = shft_lattice * 0
cor_flat = cor_lattice.flatten()

paths = []
# for each voxel that needs to have access to shafts
for i, ccen in enumerate(cluster_centers):
    ca = cluster_agents[i]
    occ_ind_cluster = np.vstack([agn_locs[i] for i in ca])

    for a_vox in occ_ind_cluster:

        # slice the corridor lattice horizontally
        cor_floor = shft_lattice[:,:,a_vox[2]]
        # find the vertical shaft voxel indices

        # construct the destination address
        dst_vox = np.array([ccen[0],ccen[1],a_vox[2]])
        # construct 1-dimensional indices
        src_ind = np.ravel_multi_index(a_vox, shft_lattice.shape)
        dst_ind = np.ravel_multi_index(dst_vox, shft_lattice.shape)
        try: 
            # find the shortest path
            path = nx.algorithms.shortest_paths.astar.astar_path(g, src_ind, dst_ind)
            paths.append(path)

            # set the shortest path occupied in the 
            cor_flat[path] = 1
        except:
            print("unreachable",src_ind, a_vox , init_avail_lattice[tuple(a_vox)],dst_ind, dst_vox, init_avail_lattice[tuple(dst_vox)])

# reshape the flat lattice
cor_lattice = cor_flat.reshape(cor_lattice.shape)
unreachable 268 [ 0 16 12] False 3772 [11 15 12] False

list(nx.neighbors(g, 387  ))
# g.nodes()
[67, 371, 403, 707]
# iterates over the list of paths
path_3d = []
for p in paths:
    p_3d = [np.unravel_index(p[0], cor_lattice.shape)]
    # iterates over the list of voxels that are included in each path
    for v in p:
        # convert 1 dimensional index of that voxel to a 3 dimensional index
        v_3d = np.unravel_index(v, cor_lattice.shape)
        print(np.array(v_3d) - np.array(p_3d[-1]), v_3d, v)
        p_3d.append(v_3d)
    # append the 3dimensional indices in a list
    path_3d.append(p_3d)
[0 0 0] (18, 14, 0) 5984
[-1  0  0] (17, 14, 0) 5664
[-1  0  0] (16, 14, 0) 5344
[-1  0  0] (15, 14, 0) 5024
[-1  0  0] (14, 14, 0) 4704
[-1  0  0] (13, 14, 0) 4384
[-1  0  0] (12, 14, 0) 4064
[-1  0  0] (11, 14, 0) 3744
[0 1 0] (11, 15, 0) 3760
[0 0 0] (4, 14, 0) 1504
[0 1 0] (4, 15, 0) 1520
[1 0 0] (5, 15, 0) 1840
[1 0 0] (6, 15, 0) 2160
[1 0 0] (7, 15, 0) 2480
[1 0 0] (8, 15, 0) 2800
[1 0 0] (9, 15, 0) 3120
[1 0 0] (10, 15, 0) 3440
[1 0 0] (11, 15, 0) 3760
[0 0 0] (22, 6, 4) 7140
[-1  0  0] (21, 6, 4) 6820
[-1  0  0] (20, 6, 4) 6500
[-1  0  0] (19, 6, 4) 6180
[-1  0  0] (18, 6, 4) 5860
[-1  0  0] (17, 6, 4) 5540
[-1  0  0] (16, 6, 4) 5220
[-1  0  0] (15, 6, 4) 4900
[-1  0  0] (14, 6, 4) 4580
[-1  0  0] (13, 6, 4) 4260
[-1  0  0] (12, 6, 4) 3940
[-1  0  0] (11, 6, 4) 3620
[0 1 0] (11, 7, 4) 3636
[0 1 0] (11, 8, 4) 3652
[0 1 0] (11, 9, 4) 3668
[0 1 0] (11, 10, 4) 3684
[0 1 0] (11, 11, 4) 3700
[0 1 0] (11, 12, 4) 3716
[0 1 0] (11, 13, 4) 3732
[0 1 0] (11, 14, 4) 3748
[0 1 0] (11, 15, 4) 3764
[0 0 0] (0, 19, 0) 304
[ 0 -1  0] (0, 18, 0) 288
[ 0 -1  0] (0, 17, 0) 272
[ 0 -1  0] (0, 16, 0) 256
[ 0 -1  0] (0, 15, 0) 240
[1 0 0] (1, 15, 0) 560
[1 0 0] (2, 15, 0) 880
[1 0 0] (3, 15, 0) 1200
[1 0 0] (4, 15, 0) 1520
[1 0 0] (5, 15, 0) 1840
[1 0 0] (6, 15, 0) 2160
[1 0 0] (7, 15, 0) 2480
[1 0 0] (8, 15, 0) 2800
[1 0 0] (9, 15, 0) 3120
[1 0 0] (10, 15, 0) 3440
[1 0 0] (11, 15, 0) 3760
[0 0 0] (22, 19, 0) 7344
[-1  0  0] (21, 19, 0) 7024
[-1  0  0] (20, 19, 0) 6704
[-1  0  0] (19, 19, 0) 6384
[-1  0  0] (18, 19, 0) 6064
[-1  0  0] (17, 19, 0) 5744
[-1  0  0] (16, 19, 0) 5424
[-1  0  0] (15, 19, 0) 5104
[-1  0  0] (14, 19, 0) 4784
[-1  0  0] (13, 19, 0) 4464
[-1  0  0] (12, 19, 0) 4144
[-1  0  0] (11, 19, 0) 3824
[ 0 -1  0] (11, 18, 0) 3808
[ 0 -1  0] (11, 17, 0) 3792
[ 0 -1  0] (11, 16, 0) 3776
[ 0 -1  0] (11, 15, 0) 3760
[0 0 0] (18, 14, 0) 5984
[ 0 -1  0] (18, 13, 0) 5968
[ 0 -1  0] (18, 12, 0) 5952
[1 0 0] (19, 12, 0) 6272
[1 0 0] (20, 12, 0) 6592
[1 0 0] (21, 12, 0) 6912
[1 0 0] (22, 12, 0) 7232
[1 0 0] (23, 12, 0) 7552
[1 0 0] (24, 12, 0) 7872
[1 0 0] (25, 12, 0) 8192
[1 0 0] (26, 12, 0) 8512
[1 0 0] (27, 12, 0) 8832
[0 0 0] (22, 19, 0) 7344
[ 0 -1  0] (22, 18, 0) 7328
[ 0 -1  0] (22, 17, 0) 7312
[ 0 -1  0] (22, 16, 0) 7296
[ 0 -1  0] (22, 15, 0) 7280
[ 0 -1  0] (22, 14, 0) 7264
[ 0 -1  0] (22, 13, 0) 7248
[ 0 -1  0] (22, 12, 0) 7232
[1 0 0] (23, 12, 0) 7552
[1 0 0] (24, 12, 0) 7872
[1 0 0] (25, 12, 0) 8192
[1 0 0] (26, 12, 0) 8512
[1 0 0] (27, 12, 0) 8832
[0 0 0] (32, 0, 4) 10244
[-1  0  0] (31, 0, 4) 9924
[-1  0  0] (30, 0, 4) 9604
[-1  0  0] (29, 0, 4) 9284
[-1  0  0] (28, 0, 4) 8964
[-1  0  0] (27, 0, 4) 8644
[0 1 0] (27, 1, 4) 8660
[0 1 0] (27, 2, 4) 8676
[0 1 0] (27, 3, 4) 8692
[0 1 0] (27, 4, 4) 8708
[0 1 0] (27, 5, 4) 8724
[0 1 0] (27, 6, 4) 8740
[0 1 0] (27, 7, 4) 8756
[0 1 0] (27, 8, 4) 8772
[0 1 0] (27, 9, 4) 8788
[0 1 0] (27, 10, 4) 8804
[0 1 0] (27, 11, 4) 8820
[0 1 0] (27, 12, 4) 8836
[0 0 0] (0, 12, 6) 198
[1 0 0] (1, 12, 6) 518
[1 0 0] (2, 12, 6) 838
[1 0 0] (3, 12, 6) 1158
[1 0 0] (4, 12, 6) 1478
[1 0 0] (5, 12, 6) 1798
[1 0 0] (6, 12, 6) 2118
[1 0 0] (7, 12, 6) 2438
[1 0 0] (8, 12, 6) 2758
[1 0 0] (9, 12, 6) 3078
[1 0 0] (10, 12, 6) 3398
[1 0 0] (11, 12, 6) 3718
[1 0 0] (12, 12, 6) 4038
[1 0 0] (13, 12, 6) 4358
[1 0 0] (14, 12, 6) 4678
[1 0 0] (15, 12, 6) 4998
[1 0 0] (16, 12, 6) 5318
[1 0 0] (17, 12, 6) 5638
[1 0 0] (18, 12, 6) 5958
[1 0 0] (19, 12, 6) 6278
[1 0 0] (20, 12, 6) 6598
[1 0 0] (21, 12, 6) 6918
[1 0 0] (22, 12, 6) 7238
[1 0 0] (23, 12, 6) 7558
[1 0 0] (24, 12, 6) 7878
[1 0 0] (25, 12, 6) 8198
[1 0 0] (26, 12, 6) 8518
[1 0 0] (27, 12, 6) 8838
[0 0 0] (28, 14, 6) 9190
[-1  0  0] (27, 14, 6) 8870
[ 0 -1  0] (27, 13, 6) 8854
[ 0 -1  0] (27, 12, 6) 8838
[0 0 0] (43, 19, 0) 14064
[-1  0  0] (42, 19, 0) 13744
[-1  0  0] (41, 19, 0) 13424
[-1  0  0] (40, 19, 0) 13104
[-1  0  0] (39, 19, 0) 12784
[-1  0  0] (38, 19, 0) 12464
[-1  0  0] (37, 19, 0) 12144
[-1  0  0] (36, 19, 0) 11824
[-1  0  0] (35, 19, 0) 11504
[-1  0  0] (34, 19, 0) 11184
[-1  0  0] (33, 19, 0) 10864
[-1  0  0] (32, 19, 0) 10544
[-1  0  0] (31, 19, 0) 10224
[-1  0  0] (30, 19, 0) 9904
[-1  0  0] (29, 19, 0) 9584
[-1  0  0] (28, 19, 0) 9264
[-1  0  0] (27, 19, 0) 8944
[ 0 -1  0] (27, 18, 0) 8928
[ 0 -1  0] (27, 17, 0) 8912
[ 0 -1  0] (27, 16, 0) 8896
[ 0 -1  0] (27, 15, 0) 8880
[ 0 -1  0] (27, 14, 0) 8864
[ 0 -1  0] (27, 13, 0) 8848
[ 0 -1  0] (27, 12, 0) 8832
[0 0 0] (43, 9, 0) 13904
[-1  0  0] (42, 9, 0) 13584
[-1  0  0] (41, 9, 0) 13264
[-1  0  0] (40, 9, 0) 12944
[-1  0  0] (39, 9, 0) 12624
[-1  0  0] (38, 9, 0) 12304
[-1  0  0] (37, 9, 0) 11984
[-1  0  0] (36, 9, 0) 11664
[-1  0  0] (35, 9, 0) 11344
[-1  0  0] (34, 9, 0) 11024
[-1  0  0] (33, 9, 0) 10704
[-1  0  0] (32, 9, 0) 10384
[-1  0  0] (31, 9, 0) 10064
[-1  0  0] (30, 9, 0) 9744
[-1  0  0] (29, 9, 0) 9424
[-1  0  0] (28, 9, 0) 9104
[-1  0  0] (27, 9, 0) 8784
[0 1 0] (27, 10, 0) 8800
[0 1 0] (27, 11, 0) 8816
[0 1 0] (27, 12, 0) 8832
[0 0 0] (14, 10, 2) 4642
[ 0 -1  0] (14, 9, 2) 4626
[ 0 -1  0] (14, 8, 2) 4610
[ 0 -1  0] (14, 7, 2) 4594
[1 0 0] (15, 7, 2) 4914
[1 0 0] (16, 7, 2) 5234
[1 0 0] (17, 7, 2) 5554
[1 0 0] (18, 7, 2) 5874
[1 0 0] (19, 7, 2) 6194
[1 0 0] (20, 7, 2) 6514
[1 0 0] (21, 7, 2) 6834
[1 0 0] (22, 7, 2) 7154
[0 0 0] (22, 0, 0) 7040
[0 1 0] (22, 1, 0) 7056
[0 1 0] (22, 2, 0) 7072
[0 1 0] (22, 3, 0) 7088
[0 1 0] (22, 4, 0) 7104
[0 1 0] (22, 5, 0) 7120
[0 1 0] (22, 6, 0) 7136
[0 1 0] (22, 7, 0) 7152
[0 0 0] (0, 0, 0) 0
[0 1 0] (0, 1, 0) 16
[0 1 0] (0, 2, 0) 32
[0 1 0] (0, 3, 0) 48
[0 1 0] (0, 4, 0) 64
[0 1 0] (0, 5, 0) 80
[0 1 0] (0, 6, 0) 96
[0 1 0] (0, 7, 0) 112
[1 0 0] (1, 7, 0) 432
[1 0 0] (2, 7, 0) 752
[1 0 0] (3, 7, 0) 1072
[1 0 0] (4, 7, 0) 1392
[1 0 0] (5, 7, 0) 1712
[1 0 0] (6, 7, 0) 2032
[1 0 0] (7, 7, 0) 2352
[1 0 0] (8, 7, 0) 2672
[1 0 0] (9, 7, 0) 2992
[1 0 0] (10, 7, 0) 3312
[1 0 0] (11, 7, 0) 3632
[1 0 0] (12, 7, 0) 3952
[1 0 0] (13, 7, 0) 4272
[1 0 0] (14, 7, 0) 4592
[1 0 0] (15, 7, 0) 4912
[1 0 0] (16, 7, 0) 5232
[1 0 0] (17, 7, 0) 5552
[1 0 0] (18, 7, 0) 5872
[1 0 0] (19, 7, 0) 6192
[1 0 0] (20, 7, 0) 6512
[1 0 0] (21, 7, 0) 6832
[1 0 0] (22, 7, 0) 7152
[0 0 0] (32, 10, 4) 10404
[-1  0  0] (31, 10, 4) 10084
[-1  0  0] (30, 10, 4) 9764
[-1  0  0] (29, 10, 4) 9444
[-1  0  0] (28, 10, 4) 9124
[-1  0  0] (27, 10, 4) 8804
[-1  0  0] (26, 10, 4) 8484
[-1  0  0] (25, 10, 4) 8164
[-1  0  0] (24, 10, 4) 7844
[-1  0  0] (23, 10, 4) 7524
[-1  0  0] (22, 10, 4) 7204
[ 0 -1  0] (22, 9, 4) 7188
[ 0 -1  0] (22, 8, 4) 7172
[ 0 -1  0] (22, 7, 4) 7156
[0 0 0] (30, 16, 4) 9860
[-1  0  0] (29, 16, 4) 9540
[-1  0  0] (28, 16, 4) 9220
[-1  0  0] (27, 16, 4) 8900
[-1  0  0] (26, 16, 4) 8580
[-1  0  0] (25, 16, 4) 8260
[-1  0  0] (24, 16, 4) 7940
[-1  0  0] (23, 16, 4) 7620
[-1  0  0] (22, 16, 4) 7300
[ 0 -1  0] (22, 15, 4) 7284
[ 0 -1  0] (22, 14, 4) 7268
[ 0 -1  0] (22, 13, 4) 7252
[ 0 -1  0] (22, 12, 4) 7236
[ 0 -1  0] (22, 11, 4) 7220
[ 0 -1  0] (22, 10, 4) 7204
[ 0 -1  0] (22, 9, 4) 7188
[ 0 -1  0] (22, 8, 4) 7172
[ 0 -1  0] (22, 7, 4) 7156
[0 0 0] (34, 4, 4) 10948
[-1  0  0] (33, 4, 4) 10628
[-1  0  0] (32, 4, 4) 10308
[-1  0  0] (31, 4, 4) 9988
[-1  0  0] (30, 4, 4) 9668
[-1  0  0] (29, 4, 4) 9348
[-1  0  0] (28, 4, 4) 9028
[-1  0  0] (27, 4, 4) 8708
[-1  0  0] (26, 4, 4) 8388
[-1  0  0] (25, 4, 4) 8068
[-1  0  0] (24, 4, 4) 7748
[-1  0  0] (23, 4, 4) 7428
[-1  0  0] (22, 4, 4) 7108
[0 1 0] (22, 5, 4) 7124
[0 1 0] (22, 6, 4) 7140
[0 1 0] (22, 7, 4) 7156
[0 0 0] (14, 10, 2) 4642
[ 0 -1  0] (14, 9, 2) 4626
[ 0 -1  0] (14, 8, 2) 4610
[ 0 -1  0] (14, 7, 2) 4594
[ 0 -1  0] (14, 6, 2) 4578
[1 0 0] (15, 6, 2) 4898
[1 0 0] (16, 6, 2) 5218
[1 0 0] (17, 6, 2) 5538
[1 0 0] (18, 6, 2) 5858
[1 0 0] (19, 6, 2) 6178
[1 0 0] (20, 6, 2) 6498
[1 0 0] (21, 6, 2) 6818
[1 0 0] (22, 6, 2) 7138
[0 0 0] (16, 0, 6) 5126
[0 1 0] (16, 1, 6) 5142
[0 1 0] (16, 2, 6) 5158
[0 1 0] (16, 3, 6) 5174
[0 1 0] (16, 4, 6) 5190
[0 1 0] (16, 5, 6) 5206
[0 1 0] (16, 6, 6) 5222
[1 0 0] (17, 6, 6) 5542
[1 0 0] (18, 6, 6) 5862
[1 0 0] (19, 6, 6) 6182
[1 0 0] (20, 6, 6) 6502
[1 0 0] (21, 6, 6) 6822
[1 0 0] (22, 6, 6) 7142
[0 0 0] (6, 14, 4) 2148
[ 0 -1  0] (6, 13, 4) 2132
[ 0 -1  0] (6, 12, 4) 2116
[ 0 -1  0] (6, 11, 4) 2100
[ 0 -1  0] (6, 10, 4) 2084
[ 0 -1  0] (6, 9, 4) 2068
[ 0 -1  0] (6, 8, 4) 2052
[ 0 -1  0] (6, 7, 4) 2036
[ 0 -1  0] (6, 6, 4) 2020
[1 0 0] (7, 6, 4) 2340
[1 0 0] (8, 6, 4) 2660
[1 0 0] (9, 6, 4) 2980
[1 0 0] (10, 6, 4) 3300
[1 0 0] (11, 6, 4) 3620
[1 0 0] (12, 6, 4) 3940
[1 0 0] (13, 6, 4) 4260
[1 0 0] (14, 6, 4) 4580
[1 0 0] (15, 6, 4) 4900
[1 0 0] (16, 6, 4) 5220
[1 0 0] (17, 6, 4) 5540
[1 0 0] (18, 6, 4) 5860
[1 0 0] (19, 6, 4) 6180
[1 0 0] (20, 6, 4) 6500
[1 0 0] (21, 6, 4) 6820
[1 0 0] (22, 6, 4) 7140
[0 0 0] (28, 14, 6) 9190
[-1  0  0] (27, 14, 6) 8870
[-1  0  0] (26, 14, 6) 8550
[-1  0  0] (25, 14, 6) 8230
[-1  0  0] (24, 14, 6) 7910
[-1  0  0] (23, 14, 6) 7590
[-1  0  0] (22, 14, 6) 7270
[ 0 -1  0] (22, 13, 6) 7254
[ 0 -1  0] (22, 12, 6) 7238
[ 0 -1  0] (22, 11, 6) 7222
[ 0 -1  0] (22, 10, 6) 7206
[ 0 -1  0] (22, 9, 6) 7190
[ 0 -1  0] (22, 8, 6) 7174
[ 0 -1  0] (22, 7, 6) 7158
[ 0 -1  0] (22, 6, 6) 7142
[0 0 0] (22, 0, 0) 7040
[0 1 0] (22, 1, 0) 7056
[0 1 0] (22, 2, 0) 7072
[0 1 0] (22, 3, 0) 7088
[0 1 0] (22, 4, 0) 7104
[0 1 0] (22, 5, 0) 7120
[0 1 0] (22, 6, 0) 7136
[0 0 0] (43, 0, 0) 13760
[-1  0  0] (42, 0, 0) 13440
[-1  0  0] (41, 0, 0) 13120
[-1  0  0] (40, 0, 0) 12800
[-1  0  0] (39, 0, 0) 12480
[-1  0  0] (38, 0, 0) 12160
[-1  0  0] (37, 0, 0) 11840
[-1  0  0] (36, 0, 0) 11520
[-1  0  0] (35, 0, 0) 11200
[-1  0  0] (34, 0, 0) 10880
[-1  0  0] (33, 0, 0) 10560
[-1  0  0] (32, 0, 0) 10240
[-1  0  0] (31, 0, 0) 9920
[-1  0  0] (30, 0, 0) 9600
[-1  0  0] (29, 0, 0) 9280
[-1  0  0] (28, 0, 0) 8960
[-1  0  0] (27, 0, 0) 8640
[-1  0  0] (26, 0, 0) 8320
[-1  0  0] (25, 0, 0) 8000
[-1  0  0] (24, 0, 0) 7680
[-1  0  0] (23, 0, 0) 7360
[-1  0  0] (22, 0, 0) 7040
[0 1 0] (22, 1, 0) 7056
[0 1 0] (22, 2, 0) 7072
[0 1 0] (22, 3, 0) 7088
[0 1 0] (22, 4, 0) 7104
[0 1 0] (22, 5, 0) 7120
[0 1 0] (22, 6, 0) 7136

2.3. Visualize the accessability lattice

p = pv.Plotter(notebook=True)

base_lattice = shft_lattice + cor_lattice

# Set the grid dimensions: shape + 1 because we want to inject our values on the CELL data
grid = pv.UniformGrid()
grid.dimensions = np.array(base_lattice.shape) + 1
# The bottom left corner of the data set
grid.origin = base_lattice.minbound - base_lattice.unit * 0.5
# These are the cell sizes along each axis
grid.spacing = base_lattice.unit 

# adding the boundingbox wireframe
p.add_mesh(grid.outline(), color="grey", label="Domain")

# adding the avilability lattice
# init_avail_lattice.fast_vis(p)

# adding axes
p.add_axes()
p.show_bounds(grid="back", location="back", color="#aaaaaa")

#Make a dictonary for the annotations




# Add the data values to the cell data
grid.cell_arrays["Agents"] = base_lattice.flatten(order="F").astype(int)  # Flatten the array!
# filtering the voxels
threshed = grid.threshold([0.9, 2.1])
# adding the voxels
p.add_mesh(threshed, name='sphere', show_edges=True, opacity=1.0, show_scalar_bar=True, annotations = Function_list, scalar_bar_args=sargs, cmap="tab20b")


# p.add_slider_widget(create_mesh, [0, n_frames], title='Time', value=0, event_type="always", style="classic", pointa=(0.1, 0.1), pointb=(0.9, 0.1))
p.show(use_ipyvtk=True)
[(253.02459757597026, 152.2245973852354, 231.42459588319835),
 (48.60000133514404, -52.19999885559082, 26.99999964237213),
 (0.0, 0.0, 1.0)]

Credits

csv_path = os.path.relpath('../data/shaftandcorridors.csv')
base_lattice.to_csv(csv_path)
__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 Path Finding and Corridorfor Generative Spatial Relations"

Last update: January 25, 2021