no style but entrance and roof added

This commit is contained in:
AKreuzer
2024-06-14 03:22:16 +02:00
parent e3dc4ba79a
commit d95ae00fde
14 changed files with 133 additions and 41 deletions

View File

@@ -4,6 +4,7 @@ from gdpc import Editor, Block, geometry
from buildings.Foundations import Foundations from buildings.Foundations import Foundations
from buildings.Facade import Facade from buildings.Facade import Facade
from buildings.Entrance import Entrance from buildings.Entrance import Entrance
from buildings.Roof import Roof
class Building: class Building:
def __init__(self,rdata, position : tuple[int,int], size : tuple[int, int], matrice : list[list[int]], floors : int): def __init__(self,rdata, position : tuple[int,int], size : tuple[int, int], matrice : list[list[int]], floors : int):
@@ -18,10 +19,14 @@ class Building:
self.foundations = Foundations(rdata["foundations"], size, matrice, tile_size,) self.foundations = Foundations(rdata["foundations"], size, matrice, tile_size,)
self.facade = Facade(rdata["facade"], self.foundations.vertices, self.foundations.is_inner_or_outer) self.facade = Facade(rdata["facade"], self.foundations.vertices, self.foundations.is_inner_or_outer)
self.entrance = Entrance(rdata, self.foundations.vertices, DIRECTION.EAST, self.foundations.is_inner_or_outer) self.entrance = Entrance(rdata, self.foundations.vertices, DIRECTION.EAST, self.foundations.is_inner_or_outer)
self.roof = Roof(rdata["roof"], self.foundations.polygon)
def build(self, editor : Editor, materials : list[str]): def build(self, editor : Editor, materials : list[str]):
for y in range(self.floors): for y in range(self.floors+1):
with editor.pushTransform((self.position[0], y*(self.foundations.floor_height+1), self.position[1])): with editor.pushTransform((self.position[0], y*(self.foundations.floor_height+1) -1, self.position[1])):
if y == self.floors:
self.roof.build(editor, materials)
break
self.foundations.build(editor, materials) self.foundations.build(editor, materials)
if y == 0: self.entrance.build(editor, materials) if y == 0: self.entrance.build(editor, materials)
else : self.facade.build(editor, materials) else : self.facade.build(editor, materials)

View File

@@ -5,24 +5,55 @@ from buildings.geometry.Vertice import Vertice
from buildings.Facade import Facade from buildings.Facade import Facade
class Entrance: class Entrance:
def __init__(self, rdata, vertices : list[Vertice], direction : DIRECTION, collumn_style : COLLUMN_STYLE): def __init__(self,
self.vertices = vertices rdata,
vertices : list[Vertice],
direction : DIRECTION,
collumn_style : COLLUMN_STYLE):
self.vertices = self.correct_vertices(vertices)
self.direction = direction self.direction = direction
self.rdata = rdata self.rdata = rdata
self.collumn_style = collumn_style self.collumn_style = collumn_style
self.is_centered = self.is_centered() self.is_centered = self.is_centered()
self.door_vertice, self.facade = self.get_door_and_facade() self.door_vertice, self.facade = self.get_door_and_facade()
self.door_width, self.door_height, self.padding, self.ypadding = self.get_door_dimention()
self.editor, self.materials = None,None
def build(self, editor : Editor, materials : list[str]): def build(self, editor : Editor, materials : list[str]):
self.facade.build(editor, materials) self.editor = editor
self.door_vertice.fill(editor, materials[0]) self.materials = materials
self.correct_facade()
with self.editor.pushTransform((0,1,0)):
self.facade.build(self.editor, self.materials)
self.build_door()
def build_door(self):
# self.padding is the padding from the door to the facade, padding is the padding from the door+self.padding to the end of the vertice
padding = (len(self.door_vertice) - (self.padding*2 + self.door_width // 2)) // 2
self.door_vertice.fill(self.editor, self.materials[0],
y = self.door_height+self.ypadding,
xpadding = padding,
zpadding = padding)
# padding is now the padding from the door to the end of the vertice
padding += self.padding
self.door_vertice.fill(self.editor, "air",
y = self.door_height,
xpadding = padding,
zpadding = padding)
def correct_facade(self):
self.facade.has_balcony = False
def correct_vertices(self, vertices : list[Vertice]) -> list[Vertice]:
for v in vertices:
v.point2.set_position(y=v.point2.y-1)
return vertices
def is_centered(self) -> bool: def is_centered(self) -> bool:
return rd.random() <= self.rdata["entrance"]["centered"] return rd.random() <= self.rdata["entrance"]["centered"]
def get_door_and_facade(self) -> tuple[Vertice, Facade]: def get_door_and_facade(self) -> tuple[Vertice, Facade]:
oriented_vertices = self.get_oriented_vertices() oriented_vertices = self.get_oriented_vertices()
facade_vertices = self.vertices.copy()
door_vertice = None door_vertice = None
if self.is_centered: if self.is_centered:
@@ -31,41 +62,53 @@ class Entrance:
ver1, ver2 = oriented_vertices[mid], oriented_vertices[-mid-1] ver1, ver2 = oriented_vertices[mid], oriented_vertices[-mid-1]
if ver1.point1.x != ver2.point1.x and ver1.point1.z != ver2.point1.z: if ver1.point1.x != ver2.point1.x and ver1.point1.z != ver2.point1.z:
door_vertice = rd.choice(ver1, ver2) door_vertice = rd.choice([ver1, ver2])
facade_vertices.remove(door_vertice)
elif ver1.point1.position == ver2.point1.position: elif ver1.point1.position == ver2.point1.position:
door_vertice = ver1 door_vertice = ver1
facade_vertices.remove(door_vertice)
else : else :
door_vertice = Vertice(ver2.point1, ver1.point2) door_vertice = Vertice(ver2.point1.copy(), ver1.point2.copy())
facade_vertices.remove(ver1)
facade_vertices.remove(ver2)
else: else:
door_vertice = rd.choice(oriented_vertices) door_vertice = rd.choice(oriented_vertices)
facade_vertices.remove(door_vertice)
facade = Facade(self.rdata["facade"], facade_vertices, self.collumn_style) facade = Facade(self.rdata["facade"], self.vertices, self.collumn_style)
return(door_vertice, facade) return(door_vertice, facade)
def get_oriented_vertices(self) -> list[Vertice]: def get_oriented_vertices(self) -> list[Vertice]:
# Get all the vertice that can contain the door # Get all the vertice that can contain the door
# if direction is north or south, compare by x, else compare by z # if direction is north or south, compare by x, else compare by z
compare = lambda v: (v.point1.x,v.point1.z) if self.direction.value % 2 == 0 else (v.point1.z,v.point1.x) compare = lambda v: (v.point1.z,v.point1.x) if self.direction.value % 2 == 0 else (v.point1.x,v.point1.z)
# if direction is north or west, the most off_centered is the maximum, else it is the minimum # if direction is north or west, the most off_centered is the maximum, else it is the minimum
off_centered = lambda p1,p2: max(p1,p2) if self.direction == DIRECTION.NORTH or self.direction == DIRECTION.WEST else min(p1,p2) off_centered = lambda p1,p2: max(p1,p2) if self.direction == DIRECTION.NORTH or self.direction == DIRECTION.WEST else min(p1,p2)
oriented_vertices = [] oriented_vertices = []
for v in self.vertices: for v in self.vertices:
if v.facing != self.direction: continue if v.facing != self.direction: continue
oriented_vertices.append(v)
sortby,position = compare(v) sortby,position = compare(v)
alreadyset = False
for ov in oriented_vertices: for ov in oriented_vertices:
ov_sorted, ov_position = compare(ov) ov_sorted, ov_position = compare(ov)
if position == ov_position: if position == ov_position:
if off_centered(sortby,ov_sorted) == sortby: oriented_vertices.remove(ov) if off_centered(sortby,ov_sorted) == sortby: oriented_vertices.remove(ov)
else: oriented_vertices.remove(v) else: alreadyset = True
if not alreadyset: oriented_vertices.append(v)
return oriented_vertices return oriented_vertices
def get_door_dimention(self) -> tuple[int,int,int,int]: # return width, height, padding, ypadding
max_width = len(self.door_vertice) - 2
max_height = self.door_vertice.get_height() - 1
door_width = rd.randint(self.rdata["entrance"]["door"]["size"]["min_width"], self.rdata["entrance"]["door"]["size"]["max_width"])
door_height = rd.randint(self.rdata["entrance"]["door"]["size"]["min_height"], self.rdata["entrance"]["door"]["size"]["max_height"])
xpadding = rd.randint(1, self.rdata["entrance"]["door"]["padding"]["max"])
ypadding = rd.randint(1, self.rdata["entrance"]["door"]["padding"]["max_top"])
if door_width > max_width: door_width = max_width
if door_height > max_height: door_height = max_height
if xpadding*2 + door_width > max_width: xpadding += (max_width - (xpadding*2 + door_width)-1)//2
if ypadding + door_height > max_height: ypadding += max_height - (ypadding + door_height)
return door_width,door_height,xpadding,ypadding

View File

@@ -8,7 +8,10 @@ from buildings.elements.Window import Window
from buildings.elements.Balcony import Balcony from buildings.elements.Balcony import Balcony
class Facade: class Facade:
def __init__(self, rdata, vertices : list[Vertice], collumn_style : COLLUMN_STYLE): def __init__(self,
rdata,
vertices : list[Vertice],
collumn_style : COLLUMN_STYLE):
self.rdata = rdata self.rdata = rdata
self.vertices = vertices self.vertices = vertices
self.collumn_style = collumn_style self.collumn_style = collumn_style
@@ -81,6 +84,6 @@ class Facade:
def has_inter_floor(self) -> bool: def has_inter_floor(self) -> bool:
return (self.rdata["inter_floor"]["proba"] >= rd.random(), select_random(self.rdata["inter_floor"]["border_style"], INTER_FLOOR_BORDER)) return (self.rdata["inter_floor"]["proba"] >= rd.random(), select_random(self.rdata["inter_floor"]["border_style"], INTER_FLOOR_BORDER))
def get_dimentions(self) -> tuple[int]: def get_dimentions(self) -> tuple[int,int]:
return ( self.vertices[0].get_height(), len(self.vertices[0])) return ( self.vertices[0].get_height(), len(self.vertices[0]))

View File

@@ -45,7 +45,7 @@ class Foundations:
for collumn in self.collumns: for collumn in self.collumns:
if collumn.is_outer and self.is_inner_or_outer == COLLUMN_STYLE.INNER: continue if collumn.is_outer and self.is_inner_or_outer == COLLUMN_STYLE.INNER: continue
if not collumn.is_outer and self.is_inner_or_outer == COLLUMN_STYLE.OUTER: continue if not collumn.is_outer and self.is_inner_or_outer == COLLUMN_STYLE.OUTER: continue
collumn.fill(editor, materials[7], self.floor_height) collumn.fill(editor, materials[7], self.floor_height+1)
def add_tile(self, tile : Tile): def add_tile(self, tile : Tile):
self.tiles.append(tile) self.tiles.append(tile)

15
buildings/Roof.py Normal file
View File

@@ -0,0 +1,15 @@
import random as rd
from buildings.geometry.Polygon import Polygon
class Roof:
def __init__(self,rdata, polygon : Polygon):
self.rdata = rdata
self.polygon = polygon
self.has_rembard = self.has_rembard()
def build(self, editor, materials : list[str]):
self.polygon.fill(editor, materials[0])
if self.has_rembard: self.polygon.fill_vertice(editor, materials[9],1)
def has_rembard(self):
return rd.random() <= self.rdata["rembard"]

View File

@@ -15,3 +15,5 @@ limitateur taille
facade lisses/ immeubles collés facade lisses/ immeubles collés
matrices pré-distribués matrices pré-distribués
angles 270 angles 270
bug entrée au milieu du O
bug entrée dans le pillier

View File

@@ -7,7 +7,11 @@ from buildings.geometry.Vertice import Vertice
from buildings.elements.Window import Window from buildings.elements.Window import Window
class Balcony: class Balcony:
def __init__(self, rdata, max_width : int, windows : Window, collumn_style : COLLUMN_STYLE): def __init__(self,
rdata,
max_width : int,
windows : Window,
collumn_style : COLLUMN_STYLE):
self.rdata = rdata self.rdata = rdata
self.windows = windows self.windows = windows
self.max_width = max_width self.max_width = max_width

View File

@@ -5,7 +5,7 @@ class FacadeDetails:
self.zones = zones self.zones = zones
self.sizes = self.get_sizes() self.sizes = self.get_sizes()
def get_sizes(self) -> list[tuple[int]]: def get_sizes(self) -> list[tuple[int,int,int]]:
# foreach different zone sizes in self.zones, we will gen different details # foreach different zone sizes in self.zones, we will gen different details
sizes = [] sizes = []
center_for_symetry = len(self.zones) // 2 center_for_symetry = len(self.zones) // 2

View File

@@ -8,7 +8,12 @@ from buildings.geometry.Vertice import Vertice
from buildings.elements.WindowElt.Glass import Glass from buildings.elements.WindowElt.Glass import Glass
class Window: class Window:
def __init__(self, rdata, max_width : int, max_height : int, facade_len : int, facade_height : int): def __init__(self,
rdata,
max_width : int,
max_height : int,
facade_len : int,
facade_height : int):
self.rdata = rdata self.rdata = rdata
self.width, self.height = self.get_size(max_width, max_height) self.width, self.height = self.get_size(max_width, max_height)
self.is_grounded = self.is_grounded() self.is_grounded = self.is_grounded()
@@ -121,7 +126,7 @@ class Window:
rd.randint(self.rdata["size"]["min_height"],max_height) rd.randint(self.rdata["size"]["min_height"],max_height)
) )
def get_padding(self, facade_len : int, facade_height : int) -> tuple[int]: def get_padding(self, facade_len : int, facade_height : int) -> tuple[int,int]:
padding,ypadding = 0,0 padding,ypadding = 0,0
if not self.is_grounded: ypadding = (facade_height - self.height)//2 if not self.is_grounded: ypadding = (facade_height - self.height)//2

View File

@@ -1,12 +1,12 @@
class Point: class Point:
def __init__(self, x : int = 0, y : int = 0, z : int = 0, p : tuple[int] = None): def __init__(self, x : int = 0, y : int = 0, z : int = 0, p : tuple[int,int,int] = None):
if p != None: x,y,z = p if p != None: x,y,z = p
self.x = x self.x = x
self.y = y self.y = y
self.z = z self.z = z
self.position = (x,y,z) self.position = (x,y,z)
def set_position(self, x : int = 0, y : int = 0, z : int = 0, p : tuple[int] = None): def set_position(self, x : int = None, y : int = None, z : int = None, p : tuple[int,int,int] = None):
if p != None: x,y,z = p if p != None: x,y,z = p
self.x = x if x != None else self.x self.x = x if x != None else self.x
self.y = y if y != None else self.y self.y = y if y != None else self.y
@@ -15,3 +15,6 @@ class Point:
def __repr__(self): def __repr__(self):
return f"Point({self.position})" return f"Point({self.position})"
def copy(self) -> 'Point':
return Point(self.x, self.y, self.z)

View File

@@ -18,9 +18,10 @@ class Polygon:
rect.fill(editor, material, y2) rect.fill(editor, material, y2)
def fill_vertice(self, editor : Editor, material : str, y : int, y2 : int = None): def fill_vertice(self, editor : Editor, material : str, y : int, y2 : int = None):
if y2 == None: y2 = y if y2 == None: y2 = 0
for vertice in self.vertices: for vertice in self.vertices:
vertice.fill(editor, Block(material), y, y2) with editor.pushTransform(Transform((0,y,0))):
vertice.fill(editor, material, y2)
def compress(self, tiles : list[Tile], vertices : list[Vertice]): def compress(self, tiles : list[Tile], vertices : list[Vertice]):
remaining_tiles = tiles.copy() remaining_tiles = tiles.copy()
@@ -58,9 +59,9 @@ class Polygon:
has_next2 = self._has_next(neighbors[1], current.facing, remaining_vertices) has_next2 = self._has_next(neighbors[1], current.facing, remaining_vertices)
if has_next1: if has_next1:
current = Vertice(has_next1.point1, current.point2, current.facing) current = Vertice(has_next1.point1.copy(), current.point2.copy(), current.facing)
elif has_next2: elif has_next2:
current = Vertice(current.point1, has_next2.point2, current.facing) current = Vertice(current.point1.copy(), has_next2.point2.copy(), current.facing)
else: else:
self.vertices.append(current) self.vertices.append(current)
current = remaining_vertices.pop() current = remaining_vertices.pop()
@@ -89,7 +90,7 @@ class Polygon:
for tile in new_line: remaining_tiles.remove(tile) for tile in new_line: remaining_tiles.remove(tile)
line = new_line line = new_line
def _has_neighbor(self, target : tuple[int], tiles : list[Tile]) -> bool|Tile: def _has_neighbor(self, target : Point, tiles : list[Tile]) -> bool|Tile:
for tile in tiles: for tile in tiles:
if tile.pos.position == target.position: if tile.pos.position == target.position:
return tile return tile

View File

@@ -64,13 +64,13 @@ class Tile:
# 0 = north, 1 = east, 2 = south, 3 = west # 0 = north, 1 = east, 2 = south, 3 = west
match(vertice): match(vertice):
case 0 : case 0 :
return Vertice(self.north_west, self.north_east, DIRECTION.NORTH) return Vertice(self.north_west.copy(), self.north_east.copy(), DIRECTION.NORTH)
case 1 : case 1 :
return Vertice(self.north_east, self.south_east, DIRECTION.EAST) return Vertice(self.north_east.copy(), self.south_east.copy(), DIRECTION.EAST)
case 2 : case 2 :
return Vertice(self.south_west, self.south_east, DIRECTION.SOUTH) return Vertice(self.south_west.copy(), self.south_east.copy(), DIRECTION.SOUTH)
case 3 : case 3 :
return Vertice(self.north_west, self.south_west, DIRECTION.WEST) return Vertice(self.north_west.copy(), self.south_west.copy(), DIRECTION.WEST)
case DIRECTION.WEST : case DIRECTION.WEST :
return self.west_vertice return self.west_vertice
case DIRECTION.EAST : case DIRECTION.EAST :
@@ -82,7 +82,7 @@ class Tile:
def set_vertice(self, direction : DIRECTION, vertice : Vertice, height : int): def set_vertice(self, direction : DIRECTION, vertice : Vertice, height : int):
self.has_vertice = True self.has_vertice = True
vertice.point2.y = height vertice.point2.set_position(y = height)
match(direction): match(direction):
case DIRECTION.WEST : case DIRECTION.WEST :
self.west_vertice = vertice self.west_vertice = vertice

View File

@@ -33,7 +33,7 @@ buildings.append(Building(random_data["buildings"], (0, 35), (30,30), shapes[6][
buildings.append(Building(random_data["buildings"], (35, 35), (20,20), shapes[7]['matrice'], 1)) buildings.append(Building(random_data["buildings"], (35, 35), (20,20), shapes[7]['matrice'], 1))
for building in buildings : for building in buildings :
building.build(editor, ["stone_bricks","glass_pane","glass","cobblestone_wall","stone_brick_stairs","oak_planks","white_concrete","cobblestone","stone_brick_slab"]) building.build(editor, ["stone_bricks","glass_pane","glass","cobblestone_wall","stone_brick_stairs","oak_planks","white_concrete","cobblestone","stone_brick_slab","iron_bars"])
# # Get a block # # Get a block

View File

@@ -77,4 +77,15 @@ buildings:
min_height: 5 min_height: 5
max_height: 9 max_height: 9
door: door:
size:
min_height: 2
max_height: 4
min_width: 1
max_width: 3
padding:
max: 2
max_top: 2
roof:
rembard: 0.5