start windows
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import random as rd
|
import random as rd
|
||||||
from Enums import COLLUMN_STYLE
|
from utils.Enums import COLLUMN_STYLE
|
||||||
from buildings.Foundations import Foundations
|
from buildings.Foundations import Foundations
|
||||||
from buildings.Facade import Facade
|
from buildings.Facade import Facade
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,46 @@
|
|||||||
from Enums import COLLUMN_STYLE
|
import random as rd
|
||||||
|
from utils.Enums import COLLUMN_STYLE, DIRECTION
|
||||||
|
from gdpc import Editor
|
||||||
from buildings.geometry.Vertice import Vertice
|
from buildings.geometry.Vertice import Vertice
|
||||||
from buildings.geometry.Rectangle import Rectangle
|
from buildings.geometry.Rectangle import Rectangle
|
||||||
from buildings.elements.Window import Window
|
from buildings.elements.Window import Window
|
||||||
|
|
||||||
class Facade:
|
class Facade:
|
||||||
def __init__(self, vertices : list[Vertice], height : int, is_inner_or_outer : COLLUMN_STYLE):
|
def __init__(self, rdata, vertices : list[Vertice], height : int, lenght : int, is_inner_or_outer : COLLUMN_STYLE):
|
||||||
|
self.rdata = rdata
|
||||||
self.vertices = vertices
|
self.vertices = vertices
|
||||||
self.is_inner_or_outer = is_inner_or_outer
|
self.is_inner_or_outer = is_inner_or_outer
|
||||||
self.height = height
|
self.height = height
|
||||||
|
self.lenght = lenght
|
||||||
self.window_size = self.get_window_size()
|
self.window_size = self.get_window_size()
|
||||||
self.window = self.get_window()
|
self.window = self.get_window()
|
||||||
self.has_balcony = self.has_balcony()
|
self.has_balcony = self.has_balcony()
|
||||||
self.has_inter_floor = self.has_inter_floor()
|
self.has_inter_floor = self.has_inter_floor()
|
||||||
|
|
||||||
def build_facade(self):
|
def build(self, editor : Editor, materials : list[str], y : int):
|
||||||
pass
|
padding = 0
|
||||||
|
if self.is_inner_or_outer == COLLUMN_STYLE.OUTER or self.is_inner_or_outer == COLLUMN_STYLE.BOTH:
|
||||||
|
padding = 1
|
||||||
|
|
||||||
|
for vertice in self.vertices:
|
||||||
|
xpadding, zpadding = 0, 0
|
||||||
|
if vertice.facing == DIRECTION.NORTH or vertice.facing == DIRECTION.SOUTH:
|
||||||
|
xpadding = padding
|
||||||
|
else: zpadding = padding
|
||||||
|
|
||||||
|
vertice.fill(editor, materials[0], y, y + self.height, xpadding = xpadding, zpadding = zpadding)
|
||||||
|
self.window.build(editor, vertice, self.height, y, materials)
|
||||||
|
|
||||||
def get_window_size(self) -> tuple[int,int]:
|
def get_window_size(self) -> tuple[int,int]:
|
||||||
pass
|
max_width = self.lenght
|
||||||
|
max_height = min(self.height, self.rdata["windows"]["size"]["max_height"])
|
||||||
|
if self.is_inner_or_outer == COLLUMN_STYLE.OUTER or self.is_inner_or_outer == COLLUMN_STYLE.BOTH:
|
||||||
|
max_width -= 2
|
||||||
|
|
||||||
|
return (
|
||||||
|
rd.randint(self.rdata["windows"]["size"]["min_width"],max_width),
|
||||||
|
rd.randint(self.rdata["windows"]["size"]["min_height"],max_height)
|
||||||
|
)
|
||||||
|
|
||||||
def has_balcony(self) -> bool:
|
def has_balcony(self) -> bool:
|
||||||
pass
|
pass
|
||||||
@@ -26,4 +49,4 @@ class Facade:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def get_window(self) -> Window:
|
def get_window(self) -> Window:
|
||||||
pass
|
return Window(self.rdata["windows"] ,self.window_size)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import random as rd
|
import random as rd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import math
|
import math
|
||||||
from Enums import COLLUMN_STYLE
|
from utils.Enums import COLLUMN_STYLE
|
||||||
from buildings.geometry.Tile import Tile
|
from buildings.geometry.Tile import Tile
|
||||||
from buildings.geometry.Polygon import Polygon
|
from buildings.geometry.Polygon import Polygon
|
||||||
from buildings.geometry.Point import Point
|
from buildings.geometry.Point import Point
|
||||||
@@ -54,9 +54,9 @@ class Foundations:
|
|||||||
|
|
||||||
# this bullshit is to create tiles from the matrice and the distribution
|
# this bullshit is to create tiles from the matrice and the distribution
|
||||||
x_padding = self.position.x
|
x_padding = self.position.x
|
||||||
for x,xsize in enumerate(self.x_distribution):
|
for x,xsize in utils.Enumerate(self.x_distribution):
|
||||||
z_padding = self.position.z
|
z_padding = self.position.z
|
||||||
for z,zsize in enumerate(self.z_distribution):
|
for z,zsize in utils.Enumerate(self.z_distribution):
|
||||||
if self.matrice[x][z] == 1:
|
if self.matrice[x][z] == 1:
|
||||||
for xi in range(xsize):
|
for xi in range(xsize):
|
||||||
for zi in range(zsize):
|
for zi in range(zsize):
|
||||||
@@ -131,14 +131,13 @@ class Foundations:
|
|||||||
return self._suppr_doubblons_collumns(collumns)
|
return self._suppr_doubblons_collumns(collumns)
|
||||||
|
|
||||||
def _suppr_doubblons_collumns(self, collumns : list[Collumn]):
|
def _suppr_doubblons_collumns(self, collumns : list[Collumn]):
|
||||||
for index,collumn in enumerate(collumns):
|
for index,collumn in utils.Enumerate(collumns):
|
||||||
if index == len(collumns)-1: break
|
if index == len(collumns)-1: break
|
||||||
for compare in collumns[index+1:]:
|
for compare in collumns[index+1:]:
|
||||||
if collumn.point1.position == compare.point1.position :
|
if collumn.point1.position == compare.point1.position :
|
||||||
if compare.is_outer : collumn.set_is_outer(True)
|
if compare.is_outer : collumn.set_is_outer(True)
|
||||||
collumns.remove(compare)
|
collumns.remove(compare)
|
||||||
|
|
||||||
print(len(collumns))
|
|
||||||
return collumns
|
return collumns
|
||||||
|
|
||||||
|
|
||||||
@@ -1,7 +1,63 @@
|
|||||||
class Window:
|
import random as rd
|
||||||
def __init__(self, size : tuple[int,int]):
|
import math
|
||||||
self.size = size
|
from gdpc import Editor, Block, geometry
|
||||||
|
from utils.Enums import DIRECTION
|
||||||
|
from buildings.geometry.Vertice import Vertice
|
||||||
|
|
||||||
|
class Window:
|
||||||
|
def __init__(self, rdata, size : tuple[int,int]):
|
||||||
|
self.rdata = rdata
|
||||||
|
self.width, self.height = size
|
||||||
|
self.is_grounded = self.is_grounded()
|
||||||
|
self.has_multiple_windows = self.has_multiple_windows()
|
||||||
|
self.padding = 0
|
||||||
|
|
||||||
|
def build(self, editor : Editor, vertice : Vertice, height : int, y : int, materials : list[str]):
|
||||||
|
self.padding = (vertice.get_size() - self.width)//2
|
||||||
|
if not self.is_grounded: y += (height - self.height)//2
|
||||||
|
|
||||||
|
if self.has_multiple_windows: self.build_multiple_windows(editor, vertice, self.padding, self.height, y, materials)
|
||||||
|
else : vertice.fill(editor, materials[1], y, y + self.height, xpadding = self.padding, zpadding = self.padding)
|
||||||
|
|
||||||
|
def build_multiple_windows(self, editor : Editor, vertice : Vertice, padding : int, height : int, y : int, materials : list[str]):
|
||||||
|
slices = rd.randint(2, self.width//self.rdata["size"]["min_width"])
|
||||||
|
windows_count = math.ceil(slices/2)
|
||||||
|
inter_count = slices - windows_count
|
||||||
|
window_size = rd.randint(self.rdata["size"]["min_width"], self.width-inter_count // windows_count)
|
||||||
|
inter_size = (self.width - window_size*windows_count) // inter_count
|
||||||
|
|
||||||
|
revert, switching = slices % 2 == 0, math.ceil(slices/2)
|
||||||
|
is_revert, gap = False, 0
|
||||||
|
for i in range(1,slices+1):
|
||||||
|
modulo = i % 2
|
||||||
|
if revert and i == switching: is_revert = True
|
||||||
|
|
||||||
|
# kepp a spacing between windows, "is revert" is used to keep symetry
|
||||||
|
if modulo == 0 or (modulo == 1 and is_revert):
|
||||||
|
#set the values to orient windows in x or z axis
|
||||||
|
xpadding,xlen,zpadding,zlen = 0,0,0,0
|
||||||
|
if vertice.facing == DIRECTION.NORTH or vertice.facing == DIRECTION.SOUTH:
|
||||||
|
xpadding,xlen = self.padding + gap, window_size
|
||||||
|
else: zpadding,zlen = self.padding + gap, window_size
|
||||||
|
|
||||||
|
geometry.placeCuboid(editor,
|
||||||
|
(vertice.point1.x+xpadding, y, vertice.point1.z+zpadding),
|
||||||
|
(vertice.point1.x+xpadding+xlen, y+self.height, vertice.point1.z+zpadding+zlen),
|
||||||
|
Block(materials[1]))
|
||||||
|
gap += window_size
|
||||||
|
else :
|
||||||
|
gap += inter_size
|
||||||
|
|
||||||
|
def is_grounded(self):
|
||||||
|
# if the window is grounded or if there is a padding between the window and the ground
|
||||||
|
if self.rdata["grounded"] >= rd.random(): return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def has_multiple_windows(self):
|
||||||
|
if self.width > self.rdata["size"]["max_width"]: return True
|
||||||
|
if self.width >= self.rdata["multiple"]["min_width"]:
|
||||||
|
if self.rdata["multiple"]["proba"] >= rd.random(): return True
|
||||||
|
return False
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from Enums import DIRECTION
|
from utils.Enums import DIRECTION
|
||||||
from gdpc import Editor, Block, geometry
|
from gdpc import Editor, Block, geometry
|
||||||
from buildings.geometry.Tile import Tile
|
from buildings.geometry.Tile import Tile
|
||||||
from buildings.geometry.Point import Point
|
from buildings.geometry.Point import Point
|
||||||
@@ -70,7 +70,7 @@ class Polygon:
|
|||||||
def set_vertices_and_neighbors(self, tiles : list[Tile], vertices : list[Vertice]):
|
def set_vertices_and_neighbors(self, tiles : list[Tile], vertices : list[Vertice]):
|
||||||
for tile in tiles:
|
for tile in tiles:
|
||||||
targets = tile.get_neighbors_coords()
|
targets = tile.get_neighbors_coords()
|
||||||
for vertice_num,target in enumerate(targets):
|
for vertice_num,target in utils.Enumerate(targets):
|
||||||
has_neighbor = self._has_neighbor(target, tiles)
|
has_neighbor = self._has_neighbor(target, tiles)
|
||||||
if not has_neighbor:
|
if not has_neighbor:
|
||||||
vertice = tile.get_vertice(vertice_num)
|
vertice = tile.get_vertice(vertice_num)
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ class Rectangle:
|
|||||||
def get_position(self):
|
def get_position(self):
|
||||||
return (self.point1.position, self.point2.position)
|
return (self.point1.position, self.point2.position)
|
||||||
|
|
||||||
def fill(self,editor : Editor, material : str, y : int, y2 : int = None):
|
def fill(self,editor : Editor, material : str, y : int, y2 : int = None, xpadding : int = 0, zpadding : int = 0):
|
||||||
|
if self.point2.x - self.point1.x < 2*xpadding: xpadding = 0
|
||||||
|
if self.point2.z - self.point1.z < 2*zpadding: zpadding = 0
|
||||||
if y2 == None: y2 = y
|
if y2 == None: y2 = y
|
||||||
geometry.placeCuboid(editor, (self.point1.x, y, self.point1.z), (self.point2.x, y2, self.point2.z), Block(material))
|
|
||||||
|
geometry.placeCuboid(editor, (self.point1.x+xpadding, y, self.point1.z+zpadding), (self.point2.x-xpadding, y2, self.point2.z-zpadding), Block(material))
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from gdpc import Editor, Block, geometry
|
from gdpc import Editor, Block, geometry
|
||||||
from Enums import DIRECTION
|
from utils.Enums import DIRECTION
|
||||||
from buildings.geometry.Point import Point
|
from buildings.geometry.Point import Point
|
||||||
from buildings.geometry.Vertice import Vertice
|
from buildings.geometry.Vertice import Vertice
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
from Enums import DIRECTION
|
from utils.Enums import DIRECTION
|
||||||
from buildings.geometry.Point import Point
|
from buildings.geometry.Point import Point
|
||||||
from buildings.geometry.Rectangle import Rectangle
|
from buildings.geometry.Rectangle import Rectangle
|
||||||
|
|
||||||
class Vertice(Rectangle):
|
class Vertice(Rectangle):
|
||||||
def __init__(self, point1 : Point, point2 : Point, facing : str):
|
def __init__(self, point1 : Point, point2 : Point, facing : DIRECTION):
|
||||||
Rectangle.__init__(self, point1, point2)
|
Rectangle.__init__(self, point1, point2)
|
||||||
self.facing = facing
|
self.facing = facing
|
||||||
|
|
||||||
|
|||||||
41
main.py
41
main.py
@@ -1,22 +1,45 @@
|
|||||||
from gdpc import Editor, Block, geometry
|
from gdpc import Editor, Block, geometry
|
||||||
import networks.curve as curve
|
import networks.curve as curve
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import json
|
from utils.JsonReader import JsonReader
|
||||||
|
from utils.YamlReader import YamlReader
|
||||||
from buildings.Building import Building
|
from buildings.Building import Building
|
||||||
|
|
||||||
|
from buildings.geometry.Vertice import Vertice
|
||||||
|
from buildings.geometry.Point import Point
|
||||||
|
from utils.Enums import DIRECTION,COLLUMN_STYLE
|
||||||
|
from buildings.Facade import Facade
|
||||||
|
|
||||||
editor = Editor(buffering=True)
|
editor = Editor(buffering=True)
|
||||||
|
|
||||||
f = open('buildings\shapes.json')
|
f = JsonReader('buildings\shapes.json')
|
||||||
shapes = json.load(f)
|
shapes = f.data
|
||||||
|
|
||||||
|
y = YamlReader('params.yml')
|
||||||
|
random_data = y.data
|
||||||
|
|
||||||
|
geometry.placeCuboid(editor, (0,-60,-5), (100,-45,-5), Block("air"))
|
||||||
|
|
||||||
|
x = 0
|
||||||
|
facade = []
|
||||||
|
for i in range(3,13):
|
||||||
|
facade.append(Facade(random_data["buildings"]["facade"],[Vertice(Point(x,0,-5), Point(x+i,0,-5), DIRECTION.NORTH)],i,i,COLLUMN_STYLE.NONE))
|
||||||
|
x += i+2
|
||||||
|
|
||||||
|
for f in facade:
|
||||||
|
f.build(editor, ["stone_bricks", "glass_pane"], -60)
|
||||||
|
|
||||||
# F = Foundations((0,0), (20,20), shapes[0]['matrice'])
|
# F = Foundations((0,0), (20,20), shapes[0]['matrice'])
|
||||||
# F.polygon.fill_polygon(editor, "stone", -60)
|
# F.polygon.fill_polygon(editor, "stone", -60)
|
||||||
geometry.placeCuboid(editor, (-10,-60,-10), (85,-55,85), Block("air"))
|
|
||||||
B = Building((0,0), (75,75), shapes[7]['matrice'])
|
# geometry.placeCuboid(editor, (-10,-60,-10), (85,-55,85), Block("air"))
|
||||||
B.foundations.polygon.fill_vertice(editor, "pink_wool", -60)
|
# B = Building((0,0), (75,75), shapes[7]['matrice'])
|
||||||
for collumn in B.foundations.collumns:
|
# B.foundations.polygon.fill_vertice(editor, "pink_wool", -60)
|
||||||
collumn.fill(editor, "white_concrete", -60, -55)
|
# for collumn in B.foundations.collumns:
|
||||||
B.foundations.polygon.fill_polygon(editor, "white_concrete", -60)
|
# collumn.fill(editor, "white_concrete", -60, -55)
|
||||||
|
# B.foundations.polygon.fill_polygon(editor, "white_concrete", -60)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# # Get a block
|
# # Get a block
|
||||||
# block = editor.getBlock((0,48,0))
|
# block = editor.getBlock((0,48,0))
|
||||||
|
|||||||
37
params.yml
37
params.yml
@@ -1 +1,36 @@
|
|||||||
// contains all random variables
|
# contains all random variables
|
||||||
|
buildings:
|
||||||
|
tile_size:
|
||||||
|
min_tile_size: 3
|
||||||
|
max_tile_size: 12
|
||||||
|
|
||||||
|
foudations:
|
||||||
|
collumn_style :
|
||||||
|
# proportion of each style
|
||||||
|
- none: 1
|
||||||
|
- inner: 1
|
||||||
|
- outer: 1
|
||||||
|
- both: 1
|
||||||
|
floor:
|
||||||
|
min_height: 4
|
||||||
|
max_height: 7
|
||||||
|
|
||||||
|
facade:
|
||||||
|
windows:
|
||||||
|
size:
|
||||||
|
min_height: 2
|
||||||
|
max_height: 6
|
||||||
|
min_width: 1
|
||||||
|
max_width: 12
|
||||||
|
crossbars:
|
||||||
|
min_height_for_vertical_crossbar: 3
|
||||||
|
vertical_crossbar: 0.25
|
||||||
|
min_width_for_horizontal_crossbar: 3
|
||||||
|
horizontal_crossbar: 0.25
|
||||||
|
grounded: 0.5
|
||||||
|
multiple:
|
||||||
|
# min size and probability of multiple windows on the same vertice
|
||||||
|
min_width: 5
|
||||||
|
proba: 0.5
|
||||||
|
inter_floor: 0.5
|
||||||
|
balcony: 0.25
|
||||||
@@ -2,3 +2,4 @@ gdpc==7.1.0
|
|||||||
matplotlib==3.8.2
|
matplotlib==3.8.2
|
||||||
numpy==1.26.4
|
numpy==1.26.4
|
||||||
scipy==1.13.0
|
scipy==1.13.0
|
||||||
|
pyyaml==6.0.1
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ class DIRECTION(Enum):
|
|||||||
SOUTH = 3
|
SOUTH = 3
|
||||||
|
|
||||||
class COLLUMN_STYLE(Enum):
|
class COLLUMN_STYLE(Enum):
|
||||||
|
NONE = 0
|
||||||
INNER = 1
|
INNER = 1
|
||||||
OUTER = 2
|
OUTER = 2
|
||||||
BOTH = 3
|
BOTH = 3
|
||||||
11
utils/JsonReader.py
Normal file
11
utils/JsonReader.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
class JsonReader:
|
||||||
|
def __init__(self, json_file):
|
||||||
|
self.data = self._load_json(json_file)
|
||||||
|
|
||||||
|
def _load_json(self, json_file : str):
|
||||||
|
f = open(json_file)
|
||||||
|
js = json.load(f)
|
||||||
|
|
||||||
|
return js
|
||||||
11
utils/YamlReader.py
Normal file
11
utils/YamlReader.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import yaml
|
||||||
|
|
||||||
|
class YamlReader:
|
||||||
|
def __init__(self, yaml_file):
|
||||||
|
self.data = self._load_yaml(yaml_file)
|
||||||
|
|
||||||
|
def _load_yaml(self, yaml_file : str):
|
||||||
|
with open(yaml_file, 'r') as stream:
|
||||||
|
data_loaded = yaml.safe_load(stream)
|
||||||
|
|
||||||
|
return data_loaded
|
||||||
Reference in New Issue
Block a user