hotfix number 46 and optimization number 956 on windows
This commit is contained in:
@@ -6,12 +6,11 @@ from buildings.elements.Window import Window
|
||||
from buildings.elements.Balcony import Balcony
|
||||
|
||||
class Facade:
|
||||
def __init__(self, rdata, vertices : list[Vertice], height : int, length : int, is_inner_or_outer : COLLUMN_STYLE):
|
||||
def __init__(self, rdata, vertices : list[Vertice], is_inner_or_outer : COLLUMN_STYLE):
|
||||
self.rdata = rdata
|
||||
self.vertices = vertices
|
||||
self.is_inner_or_outer = is_inner_or_outer
|
||||
self.height = height
|
||||
self.length = length
|
||||
self.height, self.length = self.get_dimentions()
|
||||
self.padding = 0
|
||||
self.window = self.get_window()
|
||||
self.has_balcony = self.has_balcony()
|
||||
@@ -25,8 +24,8 @@ class Facade:
|
||||
for vertice in self.vertices:
|
||||
vertice.fill(editor, materials[0], self.height, xpadding = self.padding, zpadding = self.padding)
|
||||
with editor.pushTransform(Transform(vertice.point1.position,rotation = vertice.facing.value)):
|
||||
self.build_inter_floor(vertice)
|
||||
self.window.build(editor, vertice.get_len(), self.height, materials)
|
||||
self.window.build(editor, materials)
|
||||
self.build_inter_floor()
|
||||
|
||||
def get_window(self) -> Window:
|
||||
if self.is_inner_or_outer == COLLUMN_STYLE.OUTER or self.is_inner_or_outer == COLLUMN_STYLE.BOTH:
|
||||
@@ -35,20 +34,23 @@ class Facade:
|
||||
max_width = self.length-2*self.padding
|
||||
max_height = min(self.height, self.rdata["windows"]["size"]["max_height"])
|
||||
|
||||
return Window(self.rdata["windows"] ,max_width, max_height)
|
||||
return Window(self.rdata["windows"] ,max_width, max_height, self.length, self.height)
|
||||
|
||||
def get_balcony(self) -> Balcony:
|
||||
len = rd.randint(self.rdata["balcony"]["size"]["min_len"], self.rdata["balcony"]["size"]["max_len"])
|
||||
max_width = self.length-2*self.padding
|
||||
return Balcony(len, max_width, self.window)
|
||||
return Balcony(self.rdata["balcony"], max_width, self.window)
|
||||
|
||||
def build_inter_floor(self):
|
||||
if self.has_inter_floor:
|
||||
geometry.placeCuboid(self.editor,(0,self.height,-1),(self.length,self.height,-1),Block(self.materials[4], {"facing": "south", "half": "top"}))
|
||||
geometry.placeCuboid(self.editor,(0,self.height,0),(self.length-1,self.height,0),Block(self.materials[0]))
|
||||
geometry.placeCuboid(self.editor,(0,self.height,-1),(self.length-1,self.height,-1),Block(self.materials[4], {"facing": "south", "half": "top"}))
|
||||
|
||||
def has_balcony(self) -> bool:
|
||||
return self.rdata["balcony"] >= rd.random()
|
||||
return self.rdata["balcony"]["proba"] >= rd.random()
|
||||
|
||||
def has_inter_floor(self) -> bool:
|
||||
return self.rdata["inter_floor"] >= rd.random()
|
||||
|
||||
def get_dimentions(self) -> tuple[int]:
|
||||
return ( self.vertices[0].get_height(), self.vertices[0].get_len())
|
||||
|
||||
@@ -2,12 +2,20 @@ import random as rd
|
||||
from buildings.elements.Window import Window
|
||||
|
||||
class Balcony:
|
||||
def __init__(self, rdata, length : int, max_width : int, windows : Window):
|
||||
def __init__(self, rdata, max_width : int, windows : Window):
|
||||
self.rdata = rdata
|
||||
self.length = length
|
||||
self.max_width = max_width
|
||||
self.windows = windows
|
||||
self.length = self.get_len()
|
||||
self.has_multiple = self.has_multiple_balcony()
|
||||
|
||||
def has_multiple_balcony(self):
|
||||
def follow_window(self) -> bool:
|
||||
pass
|
||||
|
||||
|
||||
def has_multiple_balcony(self) -> bool:
|
||||
if self.max_width < self.rdata["balcony"]["multiple"]["min_width"]: return False
|
||||
return self.rdata["balcony"]["multiple"]["proba"] >= rd.random()
|
||||
return self.rdata["balcony"]["multiple"]["proba"] >= rd.random()
|
||||
|
||||
def get_len(self) -> int:
|
||||
return rd.randint(self.rdata["balcony"]["size"]["min_len"], self.rdata["balcony"]["size"]["max_len"])
|
||||
22
buildings/elements/Glass.py
Normal file
22
buildings/elements/Glass.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from gdpc import Editor
|
||||
from buildings.geometry.Vertice import Vertice
|
||||
|
||||
class Glass:
|
||||
def __init__(self, x1 : int, x2 : int, group1 : list[Vertice], group2 : list[Vertice] = None):
|
||||
self.x1, self.x2 = x1, x2
|
||||
self.group1, self.group2 = group1, group2
|
||||
|
||||
|
||||
def build(self, editor : Editor, material1 : str, material2 : str):
|
||||
for elt in self.group1:
|
||||
elt.fill(editor, material1)
|
||||
if self.group2 is None: return
|
||||
for elt in self.group2:
|
||||
elt.fill(editor, material2)
|
||||
|
||||
def reset_groups(self):
|
||||
self.group1, self.group2 = [], []
|
||||
|
||||
def get_len(self):
|
||||
return self.x2 - self.x1 + 1
|
||||
|
||||
@@ -5,83 +5,31 @@ from utils.Enums import COLLUMN_STYLE, BORDER_RADIUS
|
||||
from utils.functions import *
|
||||
from buildings.geometry.Point import Point
|
||||
from buildings.geometry.Vertice import Vertice
|
||||
from buildings.elements.Glass import Glass
|
||||
|
||||
class Window:
|
||||
def __init__(self, rdata, max_width : int, max_height : int):
|
||||
def __init__(self, rdata, max_width : int, max_height : int, facade_len : int, facade_height : int):
|
||||
self.rdata = rdata
|
||||
self.width, self.height = self.get_size(max_width, max_height)
|
||||
self.is_grounded = self.is_grounded()
|
||||
self.has_multiple_windows = self.has_multiple_windows()
|
||||
self.is_alternate = self.is_alternate()
|
||||
self.has_vertical_crossbar, self.has_horizontal_crossbar = self.has_crossbars()
|
||||
self.border_radius = self.border_radius()
|
||||
self.padding = 0
|
||||
self.has_multiple = self.has_multiple_windows()
|
||||
self.has_vertical_crossbar, self.has_horizontal_crossbar = self.has_crossbars()
|
||||
self.padding, self.ypadding = self.get_padding(facade_len, facade_height)
|
||||
self.windows = self.get_windows()
|
||||
self.editor, self.materials = None,None
|
||||
|
||||
def build(self, editor : Editor, facade_len : int, facade_height : int, materials : list[str]):
|
||||
def build(self, editor : Editor, materials : list[str]):
|
||||
self.editor = editor
|
||||
self.materials = materials
|
||||
|
||||
# correction to avoid asymetry
|
||||
self.padding = (facade_len - self.width)//2
|
||||
self.width = facade_len - self.padding*2
|
||||
|
||||
if not self.is_grounded: editor.transform @= Transform((0,(facade_height-self.height)//2,0))
|
||||
editor.transform @= Transform((self.padding,0,0))
|
||||
|
||||
if self.has_multiple_windows: self.build_multiple_windows()
|
||||
else :
|
||||
self.place_glasses(0, self.width)
|
||||
|
||||
def build_multiple_windows(self):
|
||||
slices = rd.randint(3, self.width//self.rdata["size"]["min_width"])
|
||||
mid = math.ceil(slices/2)
|
||||
windows_count = mid
|
||||
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
|
||||
|
||||
is_even= slices % 2 == 0
|
||||
is_window, gap = True, 0
|
||||
remainder = self.width - (window_size*windows_count + inter_size*inter_count)
|
||||
for i in range(1,slices+1):
|
||||
wsize,isize = window_size, inter_size
|
||||
if is_even and i == mid: wsize, isize = wsize*2, isize*2
|
||||
if i == mid: wsize, isize = wsize + remainder, isize + remainder
|
||||
|
||||
# kepp a spacing between windows, "is revert" is used to keep symetry
|
||||
if is_window:
|
||||
self.place_glasses(gap, gap+wsize)
|
||||
gap += wsize
|
||||
else :
|
||||
gap += isize
|
||||
|
||||
is_window = not is_window
|
||||
|
||||
def place_glasses(self, x1 : int, x2 : int):
|
||||
len = x2 - x1
|
||||
if self.is_alternate:
|
||||
mid = x1 + len//2
|
||||
|
||||
is_block, is_even = False, len % 2 == 0
|
||||
for x in range(x1,x2):
|
||||
if is_even and x == mid: is_block = not is_block # to keep symetry
|
||||
id = 1 if not is_block else 2
|
||||
geometry.placeCuboid(self.editor,(x,0,0),(x,self.height,0),Block(self.materials[id]))
|
||||
is_block = not is_block
|
||||
|
||||
else:
|
||||
geometry.placeCuboid(self.editor,(x1,0,0),(x2-1,self.height,0),Block(self.materials[1]))
|
||||
|
||||
self.build_crossbars(x1, x2-1, len)
|
||||
if len > 1: self.build_border_radius(x1, x2-1)
|
||||
|
||||
def get_size(self, max_width : int ,max_height : int) -> tuple[int,int]:
|
||||
return (
|
||||
rd.randint(self.rdata["size"]["min_width"],max_width),
|
||||
rd.randint(self.rdata["size"]["min_height"],max_height)
|
||||
)
|
||||
|
||||
with editor.pushTransform(Transform((self.padding,self.ypadding,0))):
|
||||
for g in self.windows:
|
||||
len = g.get_len()
|
||||
g.build(editor, materials[1], materials[2])
|
||||
self.build_crossbars(g.x1, g.x2, len)
|
||||
if len > 1: self.build_border_radius(g.x1, g.x2)
|
||||
|
||||
def build_crossbars(self, x1 : int, x2 : int, len : int):
|
||||
if self.has_vertical_crossbar and self.height >= self.rdata["crossbars"]["min_height_for_vertical_crossbar"]:
|
||||
y = self.height//2
|
||||
@@ -97,10 +45,64 @@ class Window:
|
||||
if self.border_radius == BORDER_RADIUS.TOP_AND_BOTTOM:
|
||||
self.editor.placeBlock((x1,0,0),Block(self.materials[4], {"facing": "west"}))
|
||||
self.editor.placeBlock((x2,0,0),Block(self.materials[4], {"facing": "east"}))
|
||||
|
||||
def is_grounded(self):
|
||||
# if the window is grounded or if there is a padding between the window and the ground
|
||||
return self.rdata["grounded"] >= rd.random()
|
||||
|
||||
|
||||
def get_windows(self) -> list[Glass]:
|
||||
windows = []
|
||||
if not self.has_multiple: windows = [Glass(0,self.width-1,[self.create_window(0, self.width)])]
|
||||
else: windows = self.get_multiple_windows()
|
||||
if self.is_alternate: self.alternate(windows)
|
||||
|
||||
return windows
|
||||
|
||||
def get_multiple_windows(self) -> list[Glass]:
|
||||
windows = []
|
||||
slices = rd.randint(3, self.width//self.rdata["size"]["min_width"])
|
||||
mid = math.ceil(slices/2)
|
||||
windows_count = mid
|
||||
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
|
||||
|
||||
is_even= slices % 2 == 0
|
||||
is_window, gap = True, 0
|
||||
remainder = self.width - (window_size*windows_count + inter_size*inter_count)
|
||||
if windows_count % 2 == 1 and inter_count % 2 == 1:
|
||||
inter_count -= 1
|
||||
remainder += inter_size
|
||||
is_even = not is_even
|
||||
print(window_size,windows_count,inter_size,inter_count,remainder,self.width,"\n\n")
|
||||
for i in range(1,slices+1):
|
||||
wsize,isize = window_size, inter_size
|
||||
if is_even and i == mid: wsize, isize = wsize*2, isize*2
|
||||
if i == mid: wsize, isize = wsize + remainder, isize + remainder
|
||||
|
||||
if is_window:
|
||||
windows.append(Glass(gap, gap+wsize-1,[self.create_window(gap, wsize)]))
|
||||
gap += wsize
|
||||
else :
|
||||
gap += isize
|
||||
|
||||
is_window = not is_window
|
||||
|
||||
return windows
|
||||
|
||||
def alternate(self, windows : list[Glass]):
|
||||
for g in windows:
|
||||
g.reset_groups()
|
||||
len = g.get_len()
|
||||
mid = g.x1 + len//2
|
||||
|
||||
is_block, is_even = False, len % 2 == 0
|
||||
for x in range(g.x1,g.x2+1):
|
||||
if is_even and x == mid: is_block = not is_block # to keep symetry
|
||||
if is_block: g.group2.append(self.create_window(x))
|
||||
else : g.group1.append(self.create_window(x))
|
||||
is_block = not is_block
|
||||
|
||||
def create_window(self, x1 : int, length : int = None) -> Vertice:
|
||||
x2 = x1 if length is None else x1 + length -1
|
||||
return Vertice(Point(x1,0,0), Point(x2,self.height,0))
|
||||
|
||||
def has_multiple_windows(self):
|
||||
if self.width > self.rdata["size"]["max_width"]: return True
|
||||
@@ -112,6 +114,27 @@ class Window:
|
||||
# if the window alternate between glass_blocks and glass_panes
|
||||
return self.rdata["alternate"] >= rd.random()
|
||||
|
||||
|
||||
def get_size(self, max_width : int ,max_height : int) -> tuple[int,int]:
|
||||
return (
|
||||
rd.randint(self.rdata["size"]["min_width"],max_width),
|
||||
rd.randint(self.rdata["size"]["min_height"],max_height)
|
||||
)
|
||||
|
||||
def get_padding(self, facade_len : int, facade_height : int) -> tuple[int]:
|
||||
padding,ypadding = 0,0
|
||||
if not self.is_grounded: ypadding = (facade_height - self.height)//2
|
||||
|
||||
# correction to avoid asymetry
|
||||
padding = (facade_len - self.width)//2
|
||||
self.width = facade_len - padding*2
|
||||
|
||||
return (padding, ypadding)
|
||||
|
||||
def is_grounded(self):
|
||||
# if the window is grounded or if there is a padding between the window and the ground
|
||||
return self.rdata["grounded"] >= rd.random()
|
||||
|
||||
def has_crossbars(self):
|
||||
# if the window has crossbars
|
||||
data = self.rdata["crossbars"]
|
||||
|
||||
@@ -9,8 +9,12 @@ class Rectangle:
|
||||
def get_position(self):
|
||||
return (self.point1.position, self.point2.position)
|
||||
|
||||
def get_height(self):
|
||||
return self.point2.y - self.point1.y + 1
|
||||
|
||||
def fill(self,editor : Editor, material : str, y : 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 y is None: y = self.point2.y
|
||||
|
||||
geometry.placeCuboid(editor, (self.point1.x+xpadding, 0, self.point1.z+zpadding), (self.point2.x-xpadding, y, self.point2.z-zpadding), Block(material))
|
||||
|
||||
@@ -3,7 +3,7 @@ from buildings.geometry.Point import Point
|
||||
from buildings.geometry.Rectangle import Rectangle
|
||||
|
||||
class Vertice(Rectangle):
|
||||
def __init__(self, point1 : Point, point2 : Point, facing : DIRECTION):
|
||||
def __init__(self, point1 : Point, point2 : Point, facing : DIRECTION = None):
|
||||
Rectangle.__init__(self, point1, point2)
|
||||
self.facing = facing
|
||||
|
||||
|
||||
Reference in New Issue
Block a user