diff --git a/main.py b/main.py index 7639db0..e81366e 100644 --- a/main.py +++ b/main.py @@ -6,6 +6,7 @@ from world_maker.world_maker import * from world_maker.Skeleton import Skeleton, transpose_form_heightmap, simplify_coordinates from networks.geometry.Point3D import Point3D from networks.roads_2.Road import Road +from networks.legacy_roads import roads from world_maker.District import Road as Road_grid from House import * @@ -17,9 +18,11 @@ def main(): editor = Editor(buffering=True) buildArea = editor.getBuildArea() - set_roads(skeleton_mountain) - set_roads(skeleton_highway) - set_roads_grids(road_grid) + # set_roads(skeleton_mountain) + # set_roads(skeleton_highway) + # set_roads_grids(road_grid) + roads.setRoads(skeleton_mountain) + roads.setRoads(skeleton_highway) blocks = { "wall": "blackstone", @@ -39,6 +42,15 @@ def main(): entranceDirection = ["N", "S", "E", "W"] + for houses in rectangle_building: + start = (houses[0][0]+buildArea.begin[0], houses[0] + [1], houses[0][2]+buildArea.begin[2]) + end = (houses[1][0]+buildArea.begin[0], houses[1] + [1], houses[1][2]+buildArea.begin[2]) + house = House(editor, start, end, + entranceDirection[random.randint(0, 3)], blocks) + house.build() + for houses in rectangle_house_mountain: start = (houses[0][0]+buildArea.begin[0], houses[0] [1], houses[0][2]+buildArea.begin[2]) diff --git a/networks/legacy_roads/Skeleton.py b/networks/legacy_roads/Skeleton.py new file mode 100644 index 0000000..277f584 --- /dev/null +++ b/networks/legacy_roads/Skeleton.py @@ -0,0 +1,210 @@ +import numpy as np +import skan +from skimage.morphology import skeletonize +from skan.csr import skeleton_to_csgraph +from collections import Counter +from PIL import Image +import random + +from gdpc import Editor + + +class Skeleton: + def __init__(self): + self.lines = [] + self.intersections = [] + self.centers = [] + self.graph = [] + self.coordinates = [] + + def setSkeleton(self, data): + binary_skeleton = skeletonize(data) + + graph, coordinates = skeleton_to_csgraph(binary_skeleton) + self.graph = graph.tocoo() + + # List of lists. Inverted coordinates. + coordinates = list(coordinates) + print(coordinates) + for i in range(len(coordinates)): + coordinates[i] = list(coordinates[i]) + + print(coordinates) + coordinates_final = [] + + for i in range(len(coordinates[0])): + print((coordinates[0][i], coordinates[1][i], coordinates[2][i])) + coordinates_final.append( + (coordinates[0][i], coordinates[1][i], coordinates[2][i])) + + self.coordinates = coordinates_final + + def findNextElements(self, key): + """Find the very nearest elements""" + + line = [] + + values = np.array(self.graph.row) + indices = np.where(values == key)[0] + + for i in range(len(indices)): + if self.graph.row[indices[i]] == key: + line.append(self.graph.col[indices[i]]) + return line + + def findLine(self, key): + nextKeys = self.findNextElements(key) + + if len(nextKeys) >= 3: # Intersections. + return nextKeys + + if len(nextKeys) == 2 or len(nextKeys) == 1: # In line or endpoints. + line = [] + line.append(key) + line.insert(0, nextKeys[0]) + if len(nextKeys) == 2: + line.insert(len(line), nextKeys[1]) + + nextKeys = line[0], line[-1] + + while len(nextKeys) == 2 or len(nextKeys) == 1: + extremity = [] + for key in nextKeys: + nextKeys = self.findNextElements(key) + + if len(nextKeys) <= 2: + # Add the neighbors that is not already in the line. + for element in nextKeys: + if element not in line: + extremity.append(element) + line.append(element) + + if len(nextKeys) >= 3: + # Add the intersection only. + extremity.append(key) + + nextKeys = [] + for key in extremity: + ends = self.findNextElements(key) + if len(ends) == 2: + nextKeys.append(key) + return line + + def parseGraph(self): + for key, value in sorted( + Counter(self.graph.row).items(), key=lambda kv: kv[1], reverse=True + ): + # Start from the biggest intersections. + if value != 2: # We don't want to be in the middle of a line. + line = self.findLine(key) + + # We have now all the connected points if it's an + # intersection. We need to find the line. + + if value != 1: + # It's not an endpoint. + self.centers.append(key) + self.intersections.append(line) + for i in line: + line = self.findLine(i) + + if i in line: + # The key is inside the result : it's a line. + alreadyInside = False + for l in self.lines: + # Verification if not already inside. + if Counter(l) == Counter(line): + alreadyInside = True + # print(line, "inside", lines) + + if alreadyInside == False: + self.lines.append(line) + else: + # The key is not inside the result, it's an + # intersection directly connected to the key. + line = [key, i] + alreadyInside = False + for l in self.lines: + # Verification if not already inside. + if Counter(l) == Counter(line): + alreadyInside = True + # print(line, "inside", lines) + + if alreadyInside == False: + self.lines.append(line) + + def map(self): + """ + + Generate an image to visualize 2D path of the skeleton. + + Returns: + image: 2D path of the skeleton on top of the heightmap. + """ + editor = Editor() + + buildArea = editor.getBuildArea() + buildRect = buildArea.toRect() + xzStart = buildRect.begin + xzDistance = (max(buildRect.end[0], buildRect.begin[0]) - min(buildRect.end[0], buildRect.begin[0]), max( + buildRect.end[1], buildRect.begin[1]) - min(buildRect.end[1], buildRect.begin[1])) + + heightmap = Image.open("data/heightmap.png").convert('RGB') + roadsArea = Image.new("L", xzDistance, 0) + width, height = heightmap.size + + # Lines + for i in range(len(self.lines)): + r, g, b = (random.randint(0, 255), random.randint( + 0, 255), random.randint(0, 255)) + + for j in range(len(self.lines[i])): + + z = self.coordinates[self.lines[i][j]][0] + y = self.coordinates[self.lines[i][j]][1] + x = self.coordinates[self.lines[i][j]][2] + + heightmap.putpixel( + ( + int(z), + int(x), + ), + (r + j, g + j, b + j), + ) + + roadsArea.putpixel( + ( + int(z), + int(x), + ), + (255), + ) + + # Centers + for i in range(len(self.centers)): + print(self.coordinates[self.centers[i]]) + heightmap.putpixel( + (int(self.coordinates[self.centers[i]][0]), int( + self.coordinates[self.centers[i]][2])), + (255, 255, 0), + ) + + roadsArea.putpixel( + (int(self.coordinates[self.centers[i]][0]), int( + self.coordinates[self.centers[i]][2])), + (255), + ) + + # # Intersections + # for i in range(len(self.intersections)): + # intersection = [] + # for j in range(len(self.intersections[i])): + # intersection.append(self.coordinates[self.intersections[i][j]]) + + # for i in range(len(intersection)): + # heightmap.putpixel( + # (int(self.intersections[i][2]), int(self.intersections[i][0])), + # (255, 0, 255), + # ) + + return heightmap, roadsArea diff --git a/networks/legacy_roads/house.py b/networks/legacy_roads/house.py new file mode 100644 index 0000000..141b67f --- /dev/null +++ b/networks/legacy_roads/house.py @@ -0,0 +1,2005 @@ +from gdpc import * +import networks.legacy_roads.list_block +from random import randint + + +def delete(co1,co2): + editor = Editor(buffering= True) + x=abs((co2[0])-(co1[0])) + z=abs((co2[2])-(co1[2])) + y= abs(co2[1]-co1[1]) + for i in range(y): + for j in range(z): + for a in range(x): + editor.placeBlock((co1[0]+a,co1[1]+i,co1[2]+j),air) + + +def mur_sol(co1,co2,block): + x1=co1[0] + y1=co1[1] + z1=co1[2] + x2=co2[0] + y2=co2[1] + z2=co2[2] + + + if x1<0 or x2<0: + if x1<0 and x2>0: + tailleX=co2[0]-co1[0] + midtailleX=(tailleX//2)+x1 + elif x1<0 and x2<0: + + tailleX=abs(co2[0])-abs(co1[0]) + midtailleX=(tailleX//2)+x1 + else: + + tailleX=co2[0]-co1[0] + midtailleX=(tailleX//2)+x1 + + if z1<0 or z2<0: + if z1<0 and z2>0: + tailleZ=co2[2]-co1[2] + midtailleZ=(tailleZ//2)+z1 + elif z1<0 and z2<0: + + tailleZ=abs(co2[2])-abs(co1[2]) + midtailleZ=(tailleZ//2)+z1 + else: + + tailleZ=co2[2]-co1[2] + midtailleZ=(tailleZ//2)+z1 + editor = Editor(buffering= True) + + if y1==y2: + + for i in range(abs(co2[0]-(co1[0]))): + for j in range((abs((co2[2])-(co1[2])))): + editor.placeBlock((co1[0]+i,co1[1],co1[2]+j),block) + elif x1==x2: + if z1<0 or z2<0: + if z1<0 and z2>=0: + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range((z2-z1)): + + editor.placeBlock((co1[0],co1[1]+i,co1[2]+j),block) + elif z1<0 and z2<0: + + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range(abs(z2-z1)): + + editor.placeBlock((co1[0],co1[1]+i,co1[2]+j),block) + else: + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range((abs(co2[2])-abs(co1[2]))): + + editor.placeBlock((co1[0],co1[1]+i,co1[2]+j),block) + + + elif z2==z1: + if x1<0 or x2<0: + if x1<0 and x2>=0: + print(abs(abs(co2[1])-abs(co1[1]))) + print(x2-x1) + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range(x2-x1): + + editor.placeBlock((co1[0]+j,co1[1]+i,co1[2]),block) + elif x1<0 and x2<0: + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range(abs(x2-x1)): + + editor.placeBlock((co1[0]+j,co1[1]+i,co1[2]),block) + else: + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range( (abs(co2[0])-abs(co1[0]))): + + editor.placeBlock((co1[0]+j,co1[1]+i,co1[2]),block) + + + + + + + +def poserEscalier(co1,co2,type): + + editor = Editor(buffering= True) + x1=co1[0] + y1=co1[1] + z1=co1[2] + x2=co2[0] + y2=co2[1] + z2=co2[2] + + if x1==x2: + + if z1<0 or z2<0: + + if z1<0 and z2>=0: + + for i in range((z2-z1)): + print(1) + editor.placeBlock((co1[0],co1[1],co1[2]+i),type) + elif z1<0 and z2<0: + + + for i in range(abs(z2-z1)): + + editor.placeBlock((co1[0],co1[1],co1[2]+i),type) + else: + print(z1) + + for i in range((abs(co2[2])-abs(co1[2]))): + editor.placeBlock((co1[0],co1[1],co1[2]+i),type) + + + elif z2==z1: + print(x1) + if x1<0 or x2<0: + if x1<0 and x2>=0: + + + for i in range(x2-x1): + + editor.placeBlock((co1[0]+i,co1[1],co1[2]),type) + elif x1<0 and x2<0: + + for i in range(abs(x2-x1)): + + editor.placeBlock((co1[0]+i,co1[1],co1[2]),type) + else: + + for i in range((abs(co2[0])-abs(co1[0]))): + editor.placeBlock((co1[0]+i,co1[1],co1[2]),type) + + +def poserPorte(co,type): + editor = Editor(buffering= True) + editor.placeBlock((co[0],co[1],co[2]),type) + + + +def poserToit(co1,co2,hauteurMax,cotegarage,style,direction): + x1=co1[0] + y1=co1[1] + z1=co1[2] + x2=co2[0] + y2=co2[1] + z2=co2[2] + + toit_esca_devant=Block(style['toit_esca'],{"facing": "east"}) + toit_esca_derriere=Block(style['toit_esca'],{"facing": "west"}) + toit_esca_droite=Block(style['toit_esca'],{"facing": "north"}) + toit_esca_gauche=Block(style['toit_esca'],{"facing": "south"}) + toit_esca_devant_ret=Block(style['toit_esca'],{"facing": "east","half":"top"}) + toit_esca_derriere_ret=Block(style['toit_esca'],{"facing": "west","half":"top"}) + toit_esca_droite_ret=Block(style['toit_esca'],{"facing": "north","half":"top"}) + toit_esca_gauch_rete=Block(style['toit_esca'],{"facing": "south","half":"top"}) + toit_planche=Block(style['toit_planche']) + toit_slab=Block(style['toit_slab']) + mur=Block(style['mur']) + + + editor = Editor(buffering= True) + if x1<0 or x2<0: + if x1<0 and x2>=0: + tailleX=x2-x1 + midtailleX=(tailleX//2)+x1 + elif x1<0 and x2<0: + + tailleX=abs(co2[0]-co1[0]) + midtailleX=(tailleX//2)+x1 + else: + + tailleX=co2[0]-co1[0] + midtailleX=(tailleX//2)+x1 + + if z1<0 or z2<0: + if z1<0 and z2>=0: + tailleZ=co2[2]-co1[2] + midtailleZ=(tailleZ//2)+z1 + elif z1<0 and z2<0: + + tailleZ=abs(co2[2]-co1[2]) + midtailleZ=(tailleZ//2)+z1 + else: + + tailleZ=co2[2]-co1[2] + midtailleZ=(tailleZ//2)+z1 + + + if direction=='west': + if cotegarage=='left': + if x1==0 and z1==0: + for i in range(3): + if i==2: + mur_sol((x1-1,y1+4+i,z1+i),(x2-i,y1+4+i,midtailleZ-i),toit_planche) + mur_sol((midtailleX+i,y1+4+i,midtailleZ-i),(x2-i,y1+4+i,z2+1),toit_planche) + mur_sol((x1-1,y1+5+i,z1+i),(x2-i,y1+5+i,midtailleZ-i),toit_slab) + mur_sol((midtailleX+i,y1+5+i,midtailleZ-i),(x2-i,y1+5+i,z2+1),toit_slab) + + else: + mur_sol((x1,y1+4+i,z1+i),(x2-i,y1+4+i,midtailleZ-i),mur) + mur_sol((midtailleX+i,y1+4+i,midtailleZ-i),(x2-i,y1+4+i,z2),mur) + + poserEscalier((x1-1,y1+4+i,z1-1+i),(x2+3-i,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1+i),(x2-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,midtailleZ-i),(midtailleX+2+i,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,midtailleZ+1-i),(midtailleX-1+i,y1+4+i,z2+1),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + editor.placeBlock((x1-1,y1+4+i,z1+i),toit_esca_droite_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ-i-1),toit_esca_gauch_rete) + editor.placeBlock((x2-1-i,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((midtailleX+i,y1+4+i,z2),toit_esca_derriere_ret) + elif x1==0: + for i in range(3): + if i==2: + mur_sol((x1-1,y1+4+i,z1+i),(x2+2-i,y1+4+i,midtailleZ-i),toit_planche) + mur_sol((midtailleX+i,y1+4+i,midtailleZ-i),(x2-i,y1+4+i,z2+1),toit_planche) + mur_sol((x1-1,y1+5+i,z1+i),(x2+2-i,y1+5+i,midtailleZ-i),toit_slab) + mur_sol((midtailleX+i,y1+5+i,midtailleZ-i),(x2-i,y1+5+i,z2+1),toit_slab) + + else: + mur_sol((x1,y1+4+i,z1+i),(x2-i,y1+4+i,midtailleZ-i),mur) + mur_sol((midtailleX+i,y1+4+i,midtailleZ-i),(x2-i,y1+4+i,z2),mur) + + poserEscalier((x1-1,y1+4+i,z1-1+i),(x2+3-i,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1+i),(x2-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,midtailleZ-i),(midtailleX+2+i,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,midtailleZ+1-i),(midtailleX-1+i,y1+4+i,z2+1),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + editor.placeBlock((x1-1,y1+4+i,z1+i),toit_esca_droite_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ-i-1),toit_esca_gauch_rete) + editor.placeBlock((x2-1-i,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((midtailleX+i,y1+4+i,z2),toit_esca_derriere_ret) + + elif z1==0: + for i in range(3): + if i==2: + mur_sol((x1-1,y1+4+i,z1+i),(x2-i,y1+4+i,midtailleZ-i),toit_planche) + mur_sol((midtailleX+i,y1+4+i,midtailleZ-i),(x2-i,y1+4+i,z2+1),toit_planche) + mur_sol((x1-1,y1+5+i,z1+i),(x2-i,y1+5+i,midtailleZ-i),toit_slab) + mur_sol((midtailleX+i,y1+5+i,midtailleZ-i),(x2-i,y1+5+i,z2+1),toit_slab) + + else: + mur_sol((x1,y1+4+i,z1+i),(x2-i,y1+4+i,midtailleZ-i),mur) + mur_sol((midtailleX+i,y1+4+i,midtailleZ-i),(x2-i,y1+4+i,z2),mur) + + poserEscalier((x1-1,y1+4+i,z1-1+i),(x2+1-i,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1+i),(x2-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,midtailleZ-i),(midtailleX+i,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,midtailleZ+1-i),(midtailleX-1+i,y1+4+i,z2+1),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + editor.placeBlock((x1-1,y1+4+i,z1+i),toit_esca_droite_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ-i-1),toit_esca_gauch_rete) + editor.placeBlock((x2-1-i,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((midtailleX+i,y1+4+i,z2),toit_esca_derriere_ret) + + + + + else: + for i in range(3): + if i==2: + mur_sol((x1-1,y1+4+i,z1+i),(x2-i,y1+4+i,midtailleZ-i),toit_planche) + mur_sol((midtailleX+i,y1+4+i,midtailleZ-i),(x2-i,y1+4+i,z2+1),toit_planche) + mur_sol((x1-1,y1+5+i,z1+i),(x2-i,y1+5+i,midtailleZ-i),toit_slab) + mur_sol((midtailleX+i,y1+5+i,midtailleZ-i),(x2-i,y1+5+i,z2+1),toit_slab) + + else: + mur_sol((x1,y1+4+i,z1+i),(x2-i,y1+4+i,midtailleZ-i),mur) + mur_sol((midtailleX+i,y1+4+i,midtailleZ-i),(x2-i,y1+4+i,z2),mur) + + + poserEscalier((x1-1,y1+4+i,z1-1+i),(x2+1-i,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1+i),(x2-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,midtailleZ-i),(midtailleX+i,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,midtailleZ+1-i),(midtailleX-1+i,y1+4+i,z2+1),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + editor.placeBlock((x1-1,y1+4+i,z1+i),toit_esca_droite_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ-i-1),toit_esca_gauch_rete) + editor.placeBlock((x2-1-i,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((midtailleX+i,y1+4+i,z2),toit_esca_derriere_ret) + + + elif cotegarage=='right': + if x1==0 and z1==0: + + for i in range(3): + if i==2: + + + mur_sol((midtailleX+i,y1+4+i,z1-1),(x2-i,y1+4+i,z2-i),toit_planche) + mur_sol((x1-1,y1+4+i,midtailleZ+i),(x2-i,y1+4+i,z2-i),toit_planche) + mur_sol((midtailleX+i,y1+5+i,z1-1),(x2-i,y1+5+i,z2-i),toit_slab) + mur_sol((x1-1,y1+5+i,midtailleZ+i),(x2-i,y1+5+i,z2-i),toit_slab) + + else: + mur_sol((midtailleX+i,y1+4+i,z1),(x2-i,y1+4+i,z2-i),mur) + mur_sol((x1,y1+4+i,midtailleZ+i),(x2-i,y1+4+i,z2-i),mur) + + poserEscalier((x1-1,y1+4+i,midtailleZ-1+i),(midtailleX+2+i,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1-1),(x2-i,y1+4+i,z2+3-i),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,z2-i),(x2-i+2,y1+4-i,z2-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,z1-1),(midtailleX-1+i,y1+4+i,midtailleZ+1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + editor.placeBlock((midtailleX+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((x2-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + editor.placeBlock((x1-1,y1+4+i,z2-1-i),toit_esca_gauch_rete) + pass + elif x1==0: + for i in range(3): + if i==2: + + + mur_sol((midtailleX+i,y1+4+i,z1-1),(x2-i,y1+4+i,z2-i),toit_planche) + mur_sol((x1-1,y1+4+i,midtailleZ+i),(x2-i,y1+4+i,z2-i),toit_planche) + mur_sol((midtailleX+i,y1+5+i,z1-1),(x2-i,y1+5+i,z2-i),toit_slab) + mur_sol((x1-1,y1+5+i,midtailleZ+i),(x2-i,y1+5+i,z2-i),toit_slab) + + else: + mur_sol((midtailleX+i,y1+4+i,z1),(x2-i,y1+4+i,z2-i),mur) + mur_sol((x1,y1+4+i,midtailleZ+i),(x2-i,y1+4+i,z2-i),mur) + + poserEscalier((x1-1,y1+4+i,midtailleZ-1+i),(midtailleX+2+i,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1-1),(x2-i,y1+4+i,z2+1-i),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,z2-i),(x2-i+2,y1+4-i,z2-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,z1-1),(midtailleX-1+i,y1+4+i,midtailleZ+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + editor.placeBlock((midtailleX+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((x2-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + editor.placeBlock((x1-1,y1+4+i,z2-1-i),toit_esca_gauch_rete) + pass + + elif z1==0: + + for i in range(3): + if i==2: + + + mur_sol((midtailleX+i,y1+4+i,z1-1),(x2-i,y1+4+i,z2-i),toit_planche) + mur_sol((x1-1,y1+4+i,midtailleZ+i),(x2-i,y1+4+i,z2-i),toit_planche) + mur_sol((midtailleX+i,y1+5+i,z1-1),(x2-i,y1+5+i,z2-i+1),toit_slab) + mur_sol((x1-1,y1+5+i,midtailleZ+i),(x2-i,y1+5+i,z2-i),toit_slab) + + else: + mur_sol((midtailleX+i,y1+4+i,z1),(x2-i,y1+4+i,z2-i),mur) + mur_sol((x1,y1+4+i,midtailleZ+i),(x2-i,y1+4+i,z2-i),mur) + + poserEscalier((x1-1,y1+4+i,midtailleZ-1+i),(midtailleX+i,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1-1),(x2-i,y1+4+i,z2+2-i),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,z2-i),(x2-i+1,y1+4-i,z2-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,z1-1),(midtailleX-1+i,y1+4+i,midtailleZ+1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + editor.placeBlock((midtailleX+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((x2-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + editor.placeBlock((x1-1,y1+4+i,z2-1-i),toit_esca_gauch_rete) + + else: + + for i in range(3): + if i==2: + + + mur_sol((midtailleX+i,y1+4+i,z1-1),(x2-i,y1+4+i,z2-i),toit_planche) + mur_sol((x1-1,y1+4+i,midtailleZ+i),(x2-i,y1+4+i,z2-i),toit_planche) + mur_sol((midtailleX+i,y1+5+i,z1-1),(x2-i,y1+5+i,z2-i),toit_slab) + mur_sol((x1-1,y1+5+i,midtailleZ+i),(x2-i,y1+5+i,z2-i),toit_slab) + + else: + mur_sol((midtailleX+i,y1+4+i,z1),(x2-i,y1+4+i,z2-i),mur) + mur_sol((x1,y1+4+i,midtailleZ+i),(x2-i,y1+4+i,z2-i),mur) + + + poserEscalier((x1-1,y1+4+i,midtailleZ-1+i),(midtailleX+i,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1-1),(x2-i,y1+4+i,z2-i),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,z2-i),(x2-i+1,y1+4-i,z2-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,z1-1),(midtailleX-1+i,y1+4+i,midtailleZ+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + editor.placeBlock((midtailleX+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((x2-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + editor.placeBlock((x1-1,y1+4+i,z2-1-i),toit_esca_gauch_rete) + pass + + + + + + + + + + elif direction=='east': + + + if cotegarage=='left': + if x1==0 and z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+1+i,y1+5+i,midtailleZ+1+i),(x2+1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+1+i,y1+5+i,z1-1),(midtailleX-i,y1+5+i,midtailleZ+2),toit_planche) + mur_sol((x1+1+i,y1+6+i,midtailleZ+1+i),(x2+1,y1+6+i,z2-1-i),toit_slab) + mur_sol((x1+1+i,y1+6+i,z1-1),(midtailleX-i,y1+6+i,midtailleZ+2),toit_slab) + i=2 + + else: + mur_sol((x1+1+i,y1+5+i,midtailleZ+1+i),(x2,y1+5+i,z2-1-i),mur) + mur_sol((x1+1+i,y1+5+i,z1),(midtailleX-i,y1+5+i,midtailleZ+2),mur) + + poserEscalier((midtailleX+1-i,y1+4+i,midtailleZ-1+i),(x2+1,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((midtailleX+1-i,y1+4+i,z1-1),(midtailleX+1-i,y1+4+i,midtailleZ+i+1),toit_esca_derriere) + poserEscalier((x1+i,y1+4+i,z2-i),(x2+1,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((x1-1+i,y1+4+i,z1-1),(x1-1+i,y1+4+i,z2+3-i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + editor.placeBlock((x2,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((midtailleX-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z1-1),toit_esca_derriere_ret) + + + + elif x1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+1+i,y1+5+i,midtailleZ+1+i),(x2+1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+1+i,y1+5+i,z1-1),(midtailleX-i,y1+5+i,midtailleZ+2),toit_planche) + mur_sol((x1+1+i,y1+6+i,midtailleZ+1+i),(x2+1,y1+6+i,z2-1-i),toit_slab) + mur_sol((x1+1+i,y1+6+i,z1-1),(midtailleX-i,y1+6+i,midtailleZ+2),toit_slab) + i=2 + + else: + mur_sol((x1+1+i,y1+5+i,midtailleZ+1+i),(x2,y1+5+i,z2-1-i),mur) + mur_sol((x1+1+i,y1+5+i,z1),(midtailleX-i,y1+5+i,midtailleZ+2),mur) + + poserEscalier((midtailleX+1-i,y1+4+i,midtailleZ-1+i),(x2+1,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((midtailleX+1-i,y1+4+i,z1-1),(midtailleX+1-i,y1+4+i,midtailleZ+i),toit_esca_derriere) + poserEscalier((x1+i,y1+4+i,z2-i),(x2+1,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((x1-1+i,y1+4+i,z1-1),(x1-1+i,y1+4+i,z2+1-i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + editor.placeBlock((x2,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((midtailleX-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z1-1),toit_esca_derriere_ret) + + + + elif z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+1+i,y1+5+i,midtailleZ+1+i),(x2+1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+1+i,y1+5+i,z1-1),(midtailleX-i,y1+5+i,midtailleZ+2),toit_planche) + mur_sol((x1+1+i,y1+6+i,midtailleZ+1+i),(x2+1,y1+6+i,z2-1-i),toit_slab) + mur_sol((x1+1+i,y1+6+i,z1-1),(midtailleX-i,y1+6+i,midtailleZ+2),toit_slab) + i=2 + + else: + mur_sol((x1+1+i,y1+5+i,midtailleZ+1+i),(x2,y1+5+i,z2-1-i),mur) + mur_sol((x1+1+i,y1+5+i,z1),(midtailleX-i,y1+5+i,midtailleZ+2),mur) + + poserEscalier((midtailleX+1-i,y1+4+i,midtailleZ-1+i),(x2+1,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((midtailleX+1-i,y1+4+i,z1-1),(midtailleX+1-i,y1+4+i,midtailleZ+i+1),toit_esca_derriere) + poserEscalier((x1+i,y1+4+i,z2-i),(x2+1,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((x1-1+i,y1+4+i,z1-1),(x1-1+i,y1+4+i,z2+3-i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + editor.placeBlock((x2,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((midtailleX-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z1-1),toit_esca_derriere_ret) + + + + + else: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+1+i,y1+5+i,midtailleZ+1+i),(x2+1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+1+i,y1+5+i,z1-1),(midtailleX-i,y1+5+i,midtailleZ+2),toit_planche) + mur_sol((x1+1+i,y1+6+i,midtailleZ+1+i),(x2+1,y1+6+i,z2-1-i),toit_slab) + mur_sol((x1+1+i,y1+6+i,z1-1),(midtailleX-i,y1+6+i,midtailleZ+2),toit_slab) + i=2 + + else: + mur_sol((x1+1+i,y1+5+i,midtailleZ+1+i),(x2,y1+5+i,z2-1-i),mur) + mur_sol((x1+1+i,y1+5+i,z1),(midtailleX-i,y1+5+i,midtailleZ+2),mur) + + poserEscalier((midtailleX+1-i,y1+4+i,midtailleZ-1+i),(x2+1,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((midtailleX+1-i,y1+4+i,z1-1),(midtailleX+1-i,y1+4+i,midtailleZ+i),toit_esca_derriere) + poserEscalier((x1+i,y1+4+i,z2-i),(x2+1,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((x1-1+i,y1+4+i,z1-1),(x1-1+i,y1+4+i,z2+1-i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + editor.placeBlock((x2,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((midtailleX-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z1-1),toit_esca_derriere_ret) + + + elif cotegarage=='right': + if x1==0 and z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+2,y1+5+i,z1+i+1),(x2+1,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((x1+i+1,y1+5+i,midtailleZ-2),(midtailleX-i,y1+5+i,z2+1),toit_planche) + mur_sol((x1+2,y1+6+i,z1+i+1),(x2+1,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((x1+i+1,y1+6+i,midtailleZ-2),(midtailleX-i,y1+6+i,z2+1),toit_slab) + i=2 + + else: + mur_sol((x1+2,y1+5+i,z1+i+1),(x2,y1+5+i,midtailleZ-i-1),mur) + mur_sol((x1+i+1,y1+5+i,midtailleZ),(midtailleX-i,y1+5+i,z2),mur) + + poserEscalier((x1+i,y1+4+i,z1-1+i),(x2+1,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((midtailleX+1-i,y1+4+i,midtailleZ-i),(midtailleX+1-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((midtailleX+2-i,y1+4+i,midtailleZ-i),(x2+1,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((x1-1+i,y1+4+i,z1+i),(x1-1+i,y1+4+i,z2+1),toit_esca_devant) + editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2,y1+4+i,z1+i),toit_esca_droite_ret) + editor.placeBlock((x2,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((midtailleX-i,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z2),toit_esca_derriere_ret) + + + + elif x1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+2,y1+5+i,z1+i+1),(x2+1,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((x1+i+1,y1+5+i,midtailleZ-2),(midtailleX-i,y1+5+i,z2+1),toit_planche) + mur_sol((x1+2,y1+6+i,z1+i+1),(x2+1,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((x1+i+1,y1+6+i,midtailleZ-2),(midtailleX-i,y1+6+i,z2+1),toit_slab) + i=2 + + else: + mur_sol((x1+2,y1+5+i,z1+i+1),(x2,y1+5+i,midtailleZ-i-1),mur) + mur_sol((x1+i+1,y1+5+i,midtailleZ),(midtailleX-i,y1+5+i,z2),mur) + + poserEscalier((x1+i,y1+4+i,z1-1+i),(x2+1,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((midtailleX+1-i,y1+4+i,midtailleZ-i),(midtailleX+1-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((midtailleX+2-i,y1+4+i,midtailleZ-i),(x2+1,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((x1-1+i,y1+4+i,z1+i),(x1-1+i,y1+4+i,z2+1),toit_esca_devant) + editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2,y1+4+i,z1+i),toit_esca_droite_ret) + editor.placeBlock((x2,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((midtailleX-i,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z2),toit_esca_derriere_ret) + + + elif z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+2,y1+5+i,z1+i+1),(x2+1,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((x1+i+1,y1+5+i,midtailleZ-2),(midtailleX-i,y1+5+i,z2+1),toit_planche) + mur_sol((x1+2,y1+6+i,z1+i+1),(x2+1,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((x1+i+1,y1+6+i,midtailleZ-2),(midtailleX-i,y1+6+i,z2+1),toit_slab) + i=2 + + else: + mur_sol((x1+2,y1+5+i,z1+i+1),(x2,y1+5+i,midtailleZ-i-1),mur) + mur_sol((x1+i+1,y1+5+i,midtailleZ),(midtailleX-i,y1+5+i,z2),mur) + + poserEscalier((x1+i,y1+4+i,z1-1+i),(x2+1,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((midtailleX+1-i,y1+4+i,midtailleZ-i),(midtailleX+1-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((midtailleX+2-i,y1+4+i,midtailleZ-i),(x2+1,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((x1-1+i,y1+4+i,z1+i),(x1-1+i,y1+4+i,z2+1),toit_esca_devant) + editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2,y1+4+i,z1+i),toit_esca_droite_ret) + editor.placeBlock((x2,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((midtailleX-i,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z2),toit_esca_derriere_ret) + + + + + else: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+2,y1+5+i,z1+i+1),(x2+1,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((x1+i+1,y1+5+i,midtailleZ-2),(midtailleX-i,y1+5+i,z2+1),toit_planche) + mur_sol((x1+2,y1+6+i,z1+i+1),(x2+1,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((x1+i+1,y1+6+i,midtailleZ-2),(midtailleX-i,y1+6+i,z2+1),toit_slab) + i=2 + + else: + mur_sol((x1+2,y1+5+i,z1+i+1),(x2,y1+5+i,midtailleZ-i-1),mur) + mur_sol((x1+i+1,y1+5+i,midtailleZ),(midtailleX-i,y1+5+i,z2),mur) + + poserEscalier((x1+i,y1+4+i,z1-1+i),(x2+1,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((midtailleX+1-i,y1+4+i,midtailleZ-i),(midtailleX+1-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((midtailleX+2-i,y1+4+i,midtailleZ-i),(x2+1,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((x1-1+i,y1+4+i,z1+i),(x1-1+i,y1+4+i,z2+1),toit_esca_devant) + editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2,y1+4+i,z1+i),toit_esca_droite_ret) + editor.placeBlock((x2,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((midtailleX-i,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z2),toit_esca_derriere_ret) + + + + elif direction=='north': + + + if cotegarage=='left': + if x1==0 and z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1-1,y1+5+i,midtailleZ+i+1),(x2-1-i,y1+5+i,z2-i-1),toit_planche) + mur_sol((midtailleX+i+1,y1+5+i,z1-1),(x2-i-1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1-1,y1+6+i,midtailleZ+i+1),(x2-1-i,y1+6+i,z2-i-1),toit_slab) + mur_sol((midtailleX+i+1,y1+6+i,z1-1),(x2-i-1,y1+6+i,z2-1-i),toit_slab) + i=2 + + else: + pass + mur_sol((x1,y1+5+i,midtailleZ+i+1),(x2-i,y1+5+i,z2-i-1),mur) + mur_sol((midtailleX+i+1,y1+5+i,z1),(x2-i-1,y1+5+i,z2-i),mur) + + poserEscalier((x1-1,y1+4+i,midtailleZ-1+i),(midtailleX+1+i,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1-1),(x2-i,y1+4+i,z2+3-i),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,z2-i),(x2+3-i,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((midtailleX+i-1,y1+4+i,z1-1),(midtailleX+i-1,y1+4+i,midtailleZ+2+i),toit_esca_devant) + + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((midtailleX+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((x2-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1-1,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((x1-1,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + + + + elif x1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1-1,y1+5+i,midtailleZ+i+1),(x2-1-i,y1+5+i,z2-i-1),toit_planche) + mur_sol((midtailleX+i+1,y1+5+i,z1-1),(x2-i-1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1-1,y1+6+i,midtailleZ+i+1),(x2-1-i,y1+6+i,z2-i-1),toit_slab) + mur_sol((midtailleX+i+1,y1+6+i,z1-1),(x2-i-1,y1+6+i,z2-1-i),toit_slab) + i=2 + + else: + pass + mur_sol((x1,y1+5+i,midtailleZ+i+1),(x2-i,y1+5+i,z2-i-1),mur) + mur_sol((midtailleX+i+1,y1+5+i,z1),(x2-i-1,y1+5+i,z2-i),mur) + + poserEscalier((x1-1,y1+4+i,midtailleZ-1+i),(midtailleX+1+i,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1-1),(x2-i,y1+4+i,z2-i),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,z2-i),(x2+3-i,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((midtailleX+i-1,y1+4+i,z1-1),(midtailleX+i-1,y1+4+i,midtailleZ+i),toit_esca_devant) + + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((midtailleX+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((x2-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1-1,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((x1-1,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + elif z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1-1,y1+5+i,midtailleZ+i+1),(x2-1-i,y1+5+i,z2-i-1),toit_planche) + mur_sol((midtailleX+i+1,y1+5+i,z1-1),(x2-i-1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1-1,y1+6+i,midtailleZ+i+1),(x2-1-i,y1+6+i,z2-i-1),toit_slab) + mur_sol((midtailleX+i+1,y1+6+i,z1-1),(x2-i-1,y1+6+i,z2-1-i),toit_slab) + i=2 + + else: + pass + mur_sol((x1,y1+5+i,midtailleZ+i+1),(x2-i,y1+5+i,z2-i-1),mur) + mur_sol((midtailleX+i+1,y1+5+i,z1),(x2-i-1,y1+5+i,z2-i),mur) + + poserEscalier((x1-1,y1+4+i,midtailleZ-1+i),(midtailleX+1+i,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1-1),(x2-i,y1+4+i,z2+3-i),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,z2-i),(x2-i,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((midtailleX+i-1,y1+4+i,z1-1),(midtailleX+i-1,y1+4+i,midtailleZ+2+i),toit_esca_devant) + + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((midtailleX+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((x2-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1-1,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((x1-1,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + + + + + else: + for i in range(3): + if i==2: + i=1 + mur_sol((x1-1,y1+5+i,midtailleZ+i+1),(x2-1-i,y1+5+i,z2-i-1),toit_planche) + mur_sol((midtailleX+i+1,y1+5+i,z1-1),(x2-i-1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1-1,y1+6+i,midtailleZ+i+1),(x2-1-i,y1+6+i,z2-i-1),toit_slab) + mur_sol((midtailleX+i+1,y1+6+i,z1-1),(x2-i-1,y1+6+i,z2-1-i),toit_slab) + i=2 + + else: + pass + mur_sol((x1,y1+5+i,midtailleZ+i+1),(x2-i,y1+5+i,z2-i-1),mur) + mur_sol((midtailleX+i+1,y1+5+i,z1),(x2-i-1,y1+5+i,z2-i),mur) + + poserEscalier((x1-1,y1+4+i,midtailleZ-1+i),(midtailleX+1+i,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1-1),(x2-i,y1+4+i,z2+1-i),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,z2-i),(x2-i,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((midtailleX+i-1,y1+4+i,z1-1),(midtailleX+i-1,y1+4+i,midtailleZ+i),toit_esca_devant) + + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((midtailleX+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((x2-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x1-1,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((x1-1,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + + + elif cotegarage=='right': + if x1==0 and z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+i+1,y1+5+i,midtailleZ+1+i),(x2+1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+i+1,y1+5+i,z1-1),(midtailleX-i-1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+i+1,y1+6+i,midtailleZ+1+i),(x2+1,y1+6+i,z2-1-i),toit_slab) + mur_sol((x1+i+1,y1+6+i,z1-1),(midtailleX-i-1,y1+6+i,z2-1-i),toit_slab) + i=2 + + else: + pass + mur_sol((x1+i,y1+5+i,midtailleZ+i+1),(x2,y1+5+i,z2-i-1),mur) + mur_sol((x1+i+1,y1+5+i,z1),(midtailleX-i-1,y1+5+i,z2-i),mur) + + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-1+i),(x2+1,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((midtailleX-i,y1+4+i,z1-1),(midtailleX-i,y1+4+i,midtailleZ+1+i),toit_esca_derriere) + poserEscalier((x1+i,y1+4+i,z2-i),(x2+1,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((x1+i-1,y1+4+i,z1-1),(x1+i-1,y1+4+i,z2+3-i),toit_esca_devant) + + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x1+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((midtailleX-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x2,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((x2,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + + + + elif x1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+i+1,y1+5+i,midtailleZ+1+i),(x2+1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+i+1,y1+5+i,z1-1),(midtailleX-i-1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+i+1,y1+6+i,midtailleZ+1+i),(x2+1,y1+6+i,z2-1-i),toit_slab) + mur_sol((x1+i+1,y1+6+i,z1-1),(midtailleX-i-1,y1+6+i,z2-1-i),toit_slab) + i=2 + + else: + pass + mur_sol((x1+i,y1+5+i,midtailleZ+i+1),(x2,y1+5+i,z2-i-1),mur) + mur_sol((x1+i+1,y1+5+i,z1),(midtailleX-i-1,y1+5+i,z2-i),mur) + + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-1+i),(x2+1,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((midtailleX-i,y1+4+i,z1-1),(midtailleX-i,y1+4+i,midtailleZ+i),toit_esca_derriere) + poserEscalier((x1+i,y1+4+i,z2-i),(x2+1,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((x1+i-1,y1+4+i,z1-1),(x1+i-1,y1+4+i,z2+1-i),toit_esca_devant) + + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x1+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((midtailleX-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x2,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((x2,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + + + elif z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+i+1,y1+5+i,midtailleZ+1+i),(x2+1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+i+1,y1+5+i,z1-1),(midtailleX-i-1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+i+1,y1+6+i,midtailleZ+1+i),(x2+1,y1+6+i,z2-1-i),toit_slab) + mur_sol((x1+i+1,y1+6+i,z1-1),(midtailleX-i-1,y1+6+i,z2-1-i),toit_slab) + i=2 + + else: + pass + mur_sol((x1+i,y1+5+i,midtailleZ+i+1),(x2,y1+5+i,z2-i-1),mur) + mur_sol((x1+i+1,y1+5+i,z1),(midtailleX-i-1,y1+5+i,z2-i),mur) + + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-1+i),(x2+1,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((midtailleX-i,y1+4+i,z1-1),(midtailleX-i,y1+4+i,midtailleZ+1+i),toit_esca_derriere) + poserEscalier((x1+i,y1+4+i,z2-i),(x2+1,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((x1+i-1,y1+4+i,z1-1),(x1+i-1,y1+4+i,z2+3-i),toit_esca_devant) + + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x1+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((midtailleX-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x2,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((x2,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + + + + + else: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+i+1,y1+5+i,midtailleZ+1+i),(x2+1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+i+1,y1+5+i,z1-1),(midtailleX-i-1,y1+5+i,z2-1-i),toit_planche) + mur_sol((x1+i+1,y1+6+i,midtailleZ+1+i),(x2+1,y1+6+i,z2-1-i),toit_slab) + mur_sol((x1+i+1,y1+6+i,z1-1),(midtailleX-i-1,y1+6+i,z2-1-i),toit_slab) + i=2 + + else: + pass + mur_sol((x1+i,y1+5+i,midtailleZ+i+1),(x2,y1+5+i,z2-i-1),mur) + mur_sol((x1+i+1,y1+5+i,z1),(midtailleX-i-1,y1+5+i,z2-i),mur) + + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-1+i),(x2+1,y1+4+i,midtailleZ-1+i),toit_esca_gauche) + poserEscalier((midtailleX-i,y1+4+i,z1-1),(midtailleX-i,y1+4+i,midtailleZ+i),toit_esca_derriere) + poserEscalier((x1+i,y1+4+i,z2-i),(x2+1,y1+4+i,z2-i),toit_esca_droite) + poserEscalier((x1+i-1,y1+4+i,z1-1),(x1+i-1,y1+4+i,z2+1-i),toit_esca_devant) + + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x1+i,y1+4+i,z1-1),toit_esca_derriere_ret) + editor.placeBlock((midtailleX-1-i,y1+4+i,z1-1),toit_esca_devant_ret) + editor.placeBlock((x2,y1+4+i,z2-1-i),toit_esca_gauch_rete) + editor.placeBlock((x2,y1+4+i,midtailleZ+i),toit_esca_droite_ret) + + + elif direction=='south': + + + if cotegarage=='left': + if x1==0 and z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+1+i,y1+5+i,z1+i+1),(x2+1,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((x1+i+1,y1+5+i,z1+1+i),(midtailleX-i-1,y1+5+i,z2+1),toit_planche) + mur_sol((x1+1+i,y1+6+i,z1+i+1),(x2+1,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((x1+i+1,y1+6+i,z1+1+i),(midtailleX-i-1,y1+6+i,z2+1),toit_slab) + i=2 + + else: + pass + mur_sol((x1+1+i,y1+5+i,z1+i+1),(x2,y1+5+i,midtailleZ-i-1),mur) + mur_sol((x1+i+1,y1+5+i,z1+1+i),(midtailleX-i-1,y1+5+i,z2),mur) + + poserEscalier((x1+i,y1+4+i,z1-1+i),(x2+1,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-i),(midtailleX-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-i),(x2+1,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((x1+i-1,y1+4+i,z1+i),(x1+i-1,y1+4+i,z2+1),toit_esca_devant) + editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((midtailleX-i-1,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z2),toit_esca_derriere_ret) + editor.placeBlock((x2,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((x2,y1+4+i,z1+i),toit_esca_droite_ret) + + + + elif x1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+1+i,y1+5+i,z1+i+1),(x2+1,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((x1+i+1,y1+5+i,z1+1+i),(midtailleX-i-1,y1+5+i,z2+1),toit_planche) + mur_sol((x1+1+i,y1+6+i,z1+i+1),(x2+1,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((x1+i+1,y1+6+i,z1+1+i),(midtailleX-i-1,y1+6+i,z2+1),toit_slab) + i=2 + + else: + pass + mur_sol((x1+1+i,y1+5+i,z1+i+1),(x2,y1+5+i,midtailleZ-i-1),mur) + mur_sol((x1+i+1,y1+5+i,z1+1+i),(midtailleX-i-1,y1+5+i,z2),mur) + + poserEscalier((x1+i,y1+4+i,z1-1+i),(x2+1,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-i),(midtailleX-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-i),(x2+1,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((x1+i-1,y1+4+i,z1+i),(x1+i-1,y1+4+i,z2+1),toit_esca_devant) + editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((midtailleX-i-1,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z2),toit_esca_derriere_ret) + editor.placeBlock((x2,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((x2,y1+4+i,z1+i),toit_esca_droite_ret) + elif z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+1+i,y1+5+i,z1+i+1),(x2+1,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((x1+i+1,y1+5+i,z1+1+i),(midtailleX-i-1,y1+5+i,z2+1),toit_planche) + mur_sol((x1+1+i,y1+6+i,z1+i+1),(x2+1,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((x1+i+1,y1+6+i,z1+1+i),(midtailleX-i-1,y1+6+i,z2+1),toit_slab) + i=2 + + else: + pass + mur_sol((x1+1+i,y1+5+i,z1+i+1),(x2,y1+5+i,midtailleZ-i-1),mur) + mur_sol((x1+i+1,y1+5+i,z1+1+i),(midtailleX-i-1,y1+5+i,z2),mur) + + poserEscalier((x1+i,y1+4+i,z1-1+i),(x2+1,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-i),(midtailleX-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-i),(x2+1,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((x1+i-1,y1+4+i,z1+i),(x1+i-1,y1+4+i,z2+1),toit_esca_devant) + editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((midtailleX-i-1,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z2),toit_esca_derriere_ret) + editor.placeBlock((x2,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((x2,y1+4+i,z1+i),toit_esca_droite_ret) + + + + + else: + for i in range(3): + if i==2: + i=1 + mur_sol((x1+1+i,y1+5+i,z1+i+1),(x2+1,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((x1+i+1,y1+5+i,z1+1+i),(midtailleX-i-1,y1+5+i,z2+1),toit_planche) + mur_sol((x1+1+i,y1+6+i,z1+i+1),(x2+1,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((x1+i+1,y1+6+i,z1+1+i),(midtailleX-i-1,y1+6+i,z2+1),toit_slab) + i=2 + + else: + pass + mur_sol((x1+1+i,y1+5+i,z1+i+1),(x2,y1+5+i,midtailleZ-i-1),mur) + mur_sol((x1+i+1,y1+5+i,z1+1+i),(midtailleX-i-1,y1+5+i,z2),mur) + + poserEscalier((x1+i,y1+4+i,z1-1+i),(x2+1,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-i),(midtailleX-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((midtailleX-i,y1+4+i,midtailleZ-i),(x2+1,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((x1+i-1,y1+4+i,z1+i),(x1+i-1,y1+4+i,z2+1),toit_esca_devant) + editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((midtailleX-i-1,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((x1+i,y1+4+i,z2),toit_esca_derriere_ret) + editor.placeBlock((x2,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((x2,y1+4+i,z1+i),toit_esca_droite_ret) + + + elif cotegarage=='right': + if x1==0 and z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1-1,y1+5+i,z1+i+1),(x2-1-i,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((midtailleX+i+1,y1+5+i,z1+1+i),(x2-i-1,y1+5+i,z2+1),toit_planche) + mur_sol((x1-1,y1+6+i,z1+i+1),(x2-1-i,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((midtailleX+i+1,y1+6+i,z1+1+i),(x2-i-1,y1+6+i,z2+1),toit_slab) + i=2 + + else: + pass + mur_sol((x1,y1+5+i,z1+i+1),(x2-1-i,y1+5+i,midtailleZ-i-1),mur) + mur_sol((midtailleX+i+1,y1+5+i,z1+1+i),(x2-i-1,y1+5+i,z2),mur) + + poserEscalier((x1-1,y1+4+i,z1-1+i),(x2+3-i,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1+i),(x2-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,midtailleZ-i),(midtailleX+1+i,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,midtailleZ-i),(midtailleX-1+i,y1+4+i,z2+1),toit_esca_devant) + #editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2-i-1,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((midtailleX+i,y1+4+i,z2),toit_esca_derriere_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((x1-1,y1+4+i,z1+i),toit_esca_droite_ret) + + + + elif x1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1-1,y1+5+i,z1+i+1),(x2-1-i,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((midtailleX+i+1,y1+5+i,z1+1+i),(x2-i-1,y1+5+i,z2+1),toit_planche) + mur_sol((x1-1,y1+6+i,z1+i+1),(x2-1-i,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((midtailleX+i+1,y1+6+i,z1+1+i),(x2-i-1,y1+6+i,z2+1),toit_slab) + i=2 + + else: + pass + mur_sol((x1,y1+5+i,z1+i+1),(x2-1-i,y1+5+i,midtailleZ-i-1),mur) + mur_sol((midtailleX+i+1,y1+5+i,z1+1+i),(x2-i-1,y1+5+i,z2),mur) + + poserEscalier((x1-1,y1+4+i,z1-1+i),(x2+3-i,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1+i),(x2-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,midtailleZ-i),(midtailleX+1+i,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,midtailleZ-i),(midtailleX-1+i,y1+4+i,z2+1),toit_esca_devant) + #editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2-i-1,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((midtailleX+i,y1+4+i,z2),toit_esca_derriere_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((x1-1,y1+4+i,z1+i),toit_esca_droite_ret) + elif z1==0: + for i in range(3): + if i==2: + i=1 + mur_sol((x1-1,y1+5+i,z1+i+1),(x2-1-i,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((midtailleX+i+1,y1+5+i,z1+1+i),(x2-i-1,y1+5+i,z2+1),toit_planche) + mur_sol((x1-1,y1+6+i,z1+i+1),(x2-1-i,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((midtailleX+i+1,y1+6+i,z1+1+i),(x2-i-1,y1+6+i,z2+1),toit_slab) + i=2 + + else: + pass + mur_sol((x1,y1+5+i,z1+i+1),(x2-1-i,y1+5+i,midtailleZ-i-1),mur) + mur_sol((midtailleX+i+1,y1+5+i,z1+1+i),(x2-i-1,y1+5+i,z2),mur) + + poserEscalier((x1-1,y1+4+i,z1-1+i),(x2+1-i,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1+i),(x2-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,midtailleZ-i),(midtailleX+1+i,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,midtailleZ-i),(midtailleX-1+i,y1+4+i,z2+1),toit_esca_devant) + #editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2-i-1,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((midtailleX+i,y1+4+i,z2),toit_esca_derriere_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((x1-1,y1+4+i,z1+i),toit_esca_droite_ret) + + + + + else: + for i in range(3): + if i==2: + i=1 + mur_sol((x1-1,y1+5+i,z1+i+1),(x2-1-i,y1+5+i,midtailleZ-i-1),toit_planche) + mur_sol((midtailleX+i+1,y1+5+i,z1+1+i),(x2-i-1,y1+5+i,z2+1),toit_planche) + mur_sol((x1-1,y1+6+i,z1+i+1),(x2-1-i,y1+6+i,midtailleZ-i-1),toit_slab) + mur_sol((midtailleX+i+1,y1+6+i,z1+1+i),(x2-i-1,y1+6+i,z2+1),toit_slab) + i=2 + + else: + pass + mur_sol((x1,y1+5+i,z1+i+1),(x2-1-i,y1+5+i,midtailleZ-i-1),mur) + mur_sol((midtailleX+i+1,y1+5+i,z1+1+i),(x2-i-1,y1+5+i,z2),mur) + + poserEscalier((x1-1,y1+4+i,z1-1+i),(x2+1-i,y1+4+i,z1-1+i),toit_esca_gauche) + poserEscalier((x2-i,y1+4+i,z1+i),(x2-i,y1+4+i,z2+1),toit_esca_derriere) + poserEscalier((x1-1,y1+4+i,midtailleZ-i),(midtailleX+1+i,y1+4+i,midtailleZ-i),toit_esca_droite) + poserEscalier((midtailleX-1+i,y1+4+i,midtailleZ-i),(midtailleX-1+i,y1+4+i,z2+1),toit_esca_devant) + #editor.placeBlock((x1-1+i,y1+4+i,z1-1+i),toit_esca_devant) + if hauteurMax==5+i: + break + for i in range(2): + pass + editor.placeBlock((x2-i-1,y1+4+i,z2),toit_esca_devant_ret) + editor.placeBlock((midtailleX+i,y1+4+i,z2),toit_esca_derriere_ret) + editor.placeBlock((x1-1,y1+4+i,midtailleZ-1-i),toit_esca_gauch_rete) + editor.placeBlock((x1-1,y1+4+i,z1+i),toit_esca_droite_ret) + +def poserFenetre(co1,co2,type): + editor = Editor(buffering= True) + + x=abs((co2[0])-(co1[0])) + z=abs((co2[2])-(co1[2])) + y= abs(co2[1]-co1[1]) + + if co1[0]==co2[0]: + if z%2==0: + if z==4: + + editor.placeBlock((co1[0],co1[1]+1,co1[2]+1),type) + editor.placeBlock((co1[0],co1[1]+1,co1[2]+2),type) + else: + + for i in range(z//2): + if i%2==0: + editor.placeBlock((co1[0],co1[1]+1,co1[2]+i*2),type) + editor.placeBlock((co1[0],co1[1]+1,co1[2]+i*2+1),type) + else: + if z<=5: + for i in range(z): + + + editor.placeBlock((co1[0],co1[1]+1,co1[2]+i),type) + else: + + for i in range((z//3)): + if 3*(i+1)+(i)>abs(co2[2]-co1[2]): + break + else: + editor.placeBlock((co1[0],co1[1]+1,co1[2]+i*4),type) + editor.placeBlock((co1[0],co1[1]+1,co1[2]+i*4+1),type) + editor.placeBlock((co1[0],co1[1]+1,co1[2]+i*4+2),type) + + + + + if co1[2]==co2[2]: + + if x%2==0: + if x==4: + + editor.placeBlock((co1[0]+1,co1[1]+1,co1[2]),type) + editor.placeBlock((co1[0]+2,co1[1]+1,co1[2]),type) + else: + for i in range(x//2): + if i%2==0: + editor.placeBlock((co1[0]+i*2,co1[1]+1,co1[2]),type) + editor.placeBlock((co1[0]+i*2+1,co1[1]+1,co1[2]),type) + else: + if x<=5: + + + for i in range(x): + + + editor.placeBlock((co1[0]+i,co1[1]+1,co1[2]),type) + else: + + for i in range((x//3)): + if 3*(i+1)+i>abs(co2[0]-co1[0]): + break + else: + editor.placeBlock((co1[0]+i*4,co1[1]+1,co1[2]),type) + editor.placeBlock((co1[0]+i*4+1,co1[1]+1,co1[2]),type) + editor.placeBlock((co1[0]+i*4+2,co1[1]+1,co1[2]),type) + + + + + + + +def poserGarage(co1,co2): + + x1=co1[0] + y1=co1[1] + z1=co1[2] + x2=co2[0] + y2=co2[1] + z2=co2[2] + editor = Editor(buffering= True) + if x1<0 or x2<0: + if x1<0 and x2>=0: + x=x2-x1 + + elif x1<0 and x2<0: + + x=abs(co2[0]-co1[0]) + + else: + + x=co2[0]-co1[0] + + if z1<0 or z2<0: + if z1<0 and z2>=0: + z=co2[2]-co1[2] + + elif z1<0 and z2<0: + + z=abs(co2[2]-co1[2]) + + else: + + z=co2[2]-co1[2] + + + + + + + if x1==x2: + if z1<0 or z2<0: + if z1<0 and z2>=0: + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range((z2-z1)): + + editor.placeBlock((co1[0],co1[1]+i,co1[2]+j),block_quartz) + elif z1<0 and z2<0: + + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range(abs(z2-z1)): + + editor.placeBlock((co1[0],co1[1]+i,co1[2]+j),block_quartz) + else: + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range((abs(co2[2])-abs(co1[2]))): + + editor.placeBlock((co1[0],co1[1]+i,co1[2]+j),block_quartz) + + + elif z2==z1: + if x1<0 or x2<0: + if x1<0 and x2>=0: + print(abs(abs(co2[1])-abs(co1[1]))) + print(x2-x1) + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range(x2-x1): + + editor.placeBlock((co1[0]+j,co1[1]+i,co1[2]),block_quartz) + elif x1<0 and x2<0: + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range(abs(x2-x1)): + + editor.placeBlock((co1[0]+j,co1[1]+i,co1[2]),block_quartz) + else: + for i in range(abs(abs(co2[1])-abs(co1[1]))): + for j in range( (abs(co2[0])-abs(co1[0]))): + + editor.placeBlock((co1[0]+j,co1[1]+i,co1[2]),block_quartz) + + + + + + + + if co1[0]==co2[0]: + + if z%3==0: + for i in range(z//3): + editor.placeBlock((co1[0],co2[1],co1[2]+i*3),stairs_quartz_droite) + editor.placeBlock((co1[0],co2[1],co1[2]+1+i*3),quartz_slab_up) + editor.placeBlock((co1[0],co2[1],co1[2]+2+i*3),stairs_quartz_gauche) + elif z%2==0: + for i in range(z): + if i%2==0: + editor.placeBlock((co1[0],co2[1],co1[2]+i),stairs_quartz_droite) + else: + editor.placeBlock((co1[0],co2[1],co1[2]+i),stairs_quartz_gauche) + if z%5==0: + for i in range((z//5)): + + editor.placeBlock((co1[0],co2[1],co1[2]+i*5),stairs_quartz_droite) + editor.placeBlock((co1[0],co2[1],co1[2]+1+i*5),stairs_quartz_gauche) + editor.placeBlock((co1[0],co2[1],co1[2]+2+i*5),block_quartz) + editor.placeBlock((co1[0],co2[1],co1[2]+3+i*5),stairs_quartz_droite) + editor.placeBlock((co1[0],co2[1],co1[2]+4+i*5),stairs_quartz_gauche) + + elif co1[2]==co2[2]: + + if x%3==0: + + for i in range(x//3): + editor.placeBlock((co1[0]+i*3,co2[1],co1[2]),stairs_quartz_derriere) + editor.placeBlock((co1[0]+1+i*3,co2[1],co1[2]),quartz_slab_up) + editor.placeBlock((co1[0]+2+i*3,co2[1],co1[2]),stairs_quartz_devant) + elif x%2==0: + for i in range(x): + if i%2==0: + editor.placeBlock((co1[0]+i,co2[1],co1[2]),stairs_quartz_derriere) + else: + editor.placeBlock((co1[0]+i,co2[1],co1[2]),stairs_quartz_devant) + elif x%5==0: + for i in range((x//5)): + + editor.placeBlock((co1[0]+i*5,co2[1],co1[2]),stairs_quartz_derriere) + editor.placeBlock((co1[0]+1+i*5,co2[1],co1[2]),stairs_quartz_devant) + editor.placeBlock((co1[0]+2+i*5,co2[1],co1[2]),block_quartz) + editor.placeBlock((co1[0]+3+i*5,co2[1],co1[2]),stairs_quartz_derriere) + editor.placeBlock((co1[0]+4+i*5,co2[1],co1[2]),stairs_quartz_devant) + + + + + + + +def house(co1,co2,cotegarage,hauteurMax,nb_style,direction):# ,etage): + """ + Minimun 10*10 + """ + + if nb_style==0: + style=style_basique + elif nb_style==1: + style=style_birch + elif nb_style==2: + style=style_end + else: + style=style_jungle + + + sol=Block(style['sol']) + mur=Block(style['mur']) + grass=Block(style['grass']) + chemin=Block(style['chemin']) + fence=Block(style['fence']) + + glass=Block(style['glass']) + + + + + + + + + tailleX=abs(co2[0])-abs(co1[0]) + + hauteurMin=min(co2[1],co1[1]) + tailleZ=abs(co2[2])-abs(co1[2]) + + editor = Editor(buffering= True) + + + + x1=co1[0] + y1=co1[1] + z1=co1[2] + x2=co2[0] + y2=co2[1] + z2=co2[2] + + if x1<0 or x2<0: + if x1<0 and x2>=0: + tailleX=x2-x1 + midtailleX=(tailleX//2)+x1 + elif x1<0 and x2<0: + print(abs(co2[0]-co1[0]),(tailleX//2)+x1) + tailleX=abs(co2[0]-co1[0]) + midtailleX=(tailleX//2)+x1 + else: + + tailleX=co2[0]-co1[0] + midtailleX=(tailleX//2)+x1 + + if z1<0 or z2<0: + if z1<0 and z2>=0: + tailleZ=co2[2]-co1[2] + midtailleZ=(tailleZ//2)+z1 + elif z1<0 and z2<0: + + tailleZ=abs(co2[2]-co1[2]) + midtailleZ=(tailleZ//2)+z1 + else: + + tailleZ=co2[2]-co1[2] + midtailleZ=(tailleZ//2)+z1 + + + + + + if direction=='west': + door=Block(style['door'],{"facing": "east"}) + if cotegarage=='right': + + + + + #murs + poserGarage((x1+1,y1+1,midtailleZ+1),(x1+1,y1+3,z2-1)) + mur_sol((x1,y1+1,z2-1),(x2,y1+5,z2-1),mur) + mur_sol((x1,y1+1,midtailleZ),(x1,y1+5,z2 ),mur) + mur_sol((x2-1,y1+1,z1),(x2-1,y1+5,z2),mur) + mur_sol((x1,y1+1,midtailleZ),(midtailleX+1,y1+5,midtailleZ),mur) + mur_sol((midtailleX,y1+1,z1),(x2,y1+5,z1),mur) + mur_sol((midtailleX,y1+1,z1),(midtailleX,y1+5,midtailleZ),mur) + + + mur_sol((x1,y1+1,midtailleZ+1),(x1,y1+4,z2-1 ),air) + + #sols/plafonds + mur_sol((midtailleX,y1+4,z1),(x2,y1+4,z2),mur) + mur_sol((midtailleX,y1,z1),(x2,y1,z2),sol) + mur_sol((x1,y1+4,midtailleZ),(midtailleX,y1+4,z2),mur) + mur_sol((x1,y1,midtailleZ),(midtailleX,y1,z2),sol) + mur_sol((x1,y1,z1),(midtailleX,y1,midtailleZ),grass) + + + + poserFenetre((midtailleX,y1+1,z1+1),(midtailleX,y1+5,midtailleZ-1),glass) + poserFenetre((midtailleX+1,y1+1,z1),(x2-1,y1+5,z1),glass) + poserFenetre((x1+2,y1+1,midtailleZ),(midtailleX-1,y1+5,midtailleZ),glass) + poserFenetre((x2-1,y1+1,z1+1),(x2-1,y1+5,z2-1),glass) + poserFenetre((x1+2,y1+1,z2-1),(x2-1,y1+4,z2-1),glass) + + if ((z2-z1)//2)%2==0: + + poserPorte((x1+tailleX//2,hauteurMin+1,z1+(tailleZ//4)),door) + poserPorte((x1+tailleX//2,hauteurMin+1,z1+(tailleZ//4)-1),door) + mur_sol((x1,y1,z1+(tailleZ//4)-1),(x1+tailleX//2,y1,z1+(tailleZ//4)+1),chemin) + for i in range(tailleX): + for j in range(tailleZ): + if(z1+j != z1+(tailleZ//4) and z1+j != z1+(tailleZ//4)-1 ) and (x1+i< x1+(tailleX//2) and z1+j=z2-tailleZ//2 ) and(x1+i==x1 or z2-j==z2) and z2-j != z2-(tailleZ//4)-1 and z2-j != z2-(tailleZ//4): + + editor.placeBlock((x1+i,y1+1,z2-1-j),fence) + else: + + poserPorte((x1+tailleX//2,hauteurMin+1,z2-(tailleZ//4)-1),door) + mur_sol((x1,y1,z2-(tailleZ//4)-1),(x1+tailleX//2,y1,z2-(tailleZ//4)),chemin) + for i in range(tailleX): + for j in range(tailleZ): + if (x1+i< x1+(tailleX//2) and z2-j>=z2-tailleZ//2 ) and (x1+i==x1 or z2-j==z2) and z2-j != z2-(tailleZ//4): + + editor.placeBlock((x1+i,y1+1,z2-1-j),fence) + + + + + poserToit(co1,co2,hauteurMax,cotegarage,style,direction) + + + + + + + + + + elif direction=='east' : + door=Block(style['door'],{"facing": "west"}) + if cotegarage=='right': + + + + + #murs + #murs + poserGarage((x2-2,y1+1,z1+1),(x2-2,y1+3,midtailleZ-1)) + mur_sol((x1,y1+1,z1),(x2,y1+5,z1),mur) + mur_sol((x1,y1+1,z1),(x1,y1+5,z2 ),mur) + mur_sol((x2-1,y1+1,z1),(x2-1,y1+5,midtailleZ),mur) + mur_sol((midtailleX,y1+1,midtailleZ),(midtailleX,y1+5,z2),mur) + mur_sol((midtailleX,y1+1,midtailleZ-1),(x2,y1+5,midtailleZ-1),mur) + mur_sol((x1,y1+1,z2-1),(midtailleX,y1+5,z2-1),mur) + + + mur_sol((x2-1,y1+1,z1+1),(x2-1,y1+4,midtailleZ-1),air) + + + #sols/plafonds + mur_sol((x1,y1+4,z1),(x2,y1+4,midtailleZ),mur) + mur_sol((x1,y1,z1),(x2,y1,midtailleZ),sol) + mur_sol((x1,y1+4,midtailleZ),(midtailleX+1,y1+4,z2),mur) + mur_sol((x1,y1,midtailleZ),(midtailleX+1,y1,z2),sol) + mur_sol((midtailleX+1,y1,midtailleZ),(x2,y1,z2),grass) + + poserFenetre((x1+1,y1+1,z2-1),(midtailleX-1,y1+5,z2-1),glass) + poserFenetre((midtailleX+1,y1+1,midtailleZ-1),(x2-2,y1+5,midtailleZ-1),glass) + poserFenetre((midtailleX,y1+1,midtailleZ+1),(midtailleX,y1+5,z2-1),glass) + poserFenetre((x1+1,y1+1,z1),(x2-1,y1+5,z1),glass) + poserFenetre((x1,y1+1,z1+1),(x1,y1+5,z2-1 ),glass) + + + + + + if (tailleZ-((z2-z1)//2))%2==0: + + poserPorte((x1+tailleX//2,hauteurMin+1,z2-1-(tailleZ//4)),door) + poserPorte((x1+tailleX//2,hauteurMin+1,z2-(tailleZ//4)-2),door) + mur_sol((midtailleX,y1,z2-2-(tailleZ//4)),(x2,y1,z2-(tailleZ//4)-4),chemin) + for i in range(tailleX): + for j in range(tailleZ): + if (midtailleX+1+i< x2 and z1+j>=midtailleZ ) and (midtailleX+i+1==x2-1 or z1+j==z2-1) and z1+j != z2-1-(tailleZ//4) and z1+j != z2-2-(tailleZ//4) : + + editor.placeBlock((midtailleX+1+i,y1+1,z1+j),fence) + else: + + poserPorte((x1+tailleX//2,hauteurMin+1,z2-1-(tailleZ//4)),door) + mur_sol((midtailleX,y1,z2-1-(tailleZ//4)),(x2,y1,z2-(tailleZ//4)-2),chemin) + for i in range(tailleX): + for j in range(tailleZ): + if (midtailleX+1+i< x2 and z1+j>=midtailleZ ) and (midtailleX+i+1==x2-1 or z1+j==z2-1) and z1+j != z2-1-(tailleZ//4): + + editor.placeBlock((midtailleX+i+1,y1+1,z1+j),fence) + + + + + poserToit(co1,co2,hauteurMax,cotegarage,style,direction ) + + + + + elif cotegarage=='left': + + + + + + + + + + + + #murs + poserGarage((x2-2,y1+1,midtailleZ+1),(x2-2,y1+3,z2-1)) + mur_sol((x1,y1+1,z1),(midtailleX,y1+5,z1),mur) + mur_sol((x1,y1+1,z1),(x1,y1+5,z2 ),mur) + mur_sol((x2-1,y1+1,midtailleZ),(x2-1,y1+5,z2),mur) + mur_sol((midtailleX,y1+1,z1),(midtailleX,y1+5,midtailleZ),mur) + mur_sol((midtailleX,y1+1,midtailleZ),(x2,y1+5,midtailleZ),mur) + mur_sol((x1,y1+1,z2-1),(x2,y1+5,z2-1),mur) + + + mur_sol((x2-1,y1+1,midtailleZ+1),(x2-1,y1+4,z2-1),air) + + + #sols/plafonds + mur_sol((x1,y1+4,midtailleZ),(x2,y1+4,z2),mur) + mur_sol((x1,y1,midtailleZ),(x2,y1,z2),sol) + mur_sol((x1,y1+4,z1),(midtailleX+1,y1+4,midtailleZ),mur) + mur_sol((x1,y1,z1),(midtailleX+1,y1,midtailleZ),sol) + mur_sol((midtailleX+1,y1,z1),(x2,y1,midtailleZ),grass) + + poserFenetre((x1+1,y1+1,z1),(midtailleX,y1+5,z1),glass) + poserFenetre((x1,y1+1,z1+1),(x1,y1+5,z2-1 ),glass) + poserFenetre((midtailleX,y1+1,z1+1),(midtailleX,y1+5,midtailleZ-1),glass) + poserFenetre((midtailleX+2,y1+1,midtailleZ),(x2-2,y1+5,midtailleZ),glass) + poserFenetre((x1+1,y1+1,z2-1),(x2-1,y1+5,z2-1),glass) + + + + + + if ((z2-z1)//2)%2==0: + + poserPorte((x1+tailleX//2,hauteurMin+1,z1+(tailleZ//4)),door) + poserPorte((x1+tailleX//2,hauteurMin+1,z1+(tailleZ//4)+1),door) + mur_sol((midtailleX,y1,z1+(tailleZ//4)),(x2,y1,z1+(tailleZ//4)+2),chemin) + for i in range(tailleX): + for j in range(tailleZ): + if (midtailleX+1+i< x2 and z1+j= midtailleX and z1+j= midtailleX and z1+j= midtailleX and z1+j=midtailleZ )and (x1+i==x1 or z1+j==z2-1) and x1+i != x1+tailleX//4 and x1+i != x1+1+tailleX//4: + + editor.placeBlock((x1+i,y1+1,z1+j),fence) + else: + + poserPorte((x1+tailleX//4,hauteurMin+1,midtailleZ-1),door) + mur_sol((x1+tailleX//4,y1,midtailleZ),(x1+1+tailleX//4,y1,z2),chemin) + for i in range(tailleX): + for j in range(tailleZ): + if (x1+i< midtailleX and z1+j>=midtailleZ )and (x1+i==x1 or z1+j==z2-1) and x1+i != x1+tailleX//4: + + editor.placeBlock((x1+i,y1+1,z1+j),fence) + + + + + poserToit(co1,co2,hauteurMax,cotegarage,style,direction ) + + + + elif cotegarage=='left': + #murs + #murs + poserGarage((x1+1,y1+1,z2-2),(midtailleX-1,y1+3,z2-2)) + mur_sol((midtailleX,y1+1,midtailleZ-1),(x2,y1+5,midtailleZ-1),mur) + mur_sol((x2-1,y1+1,z1),(x2-1,y1+5,midtailleZ ),mur) + mur_sol((x1,y1+1,z1),(x1,y1+5,z2),mur) + mur_sol((x1,y1+1,z1),(x2,y1+5,z1),mur) + mur_sol((midtailleX-1,y1+1,midtailleZ ),(midtailleX-1,y1+5,z2),mur) + + + + + + + #sols/plafonds + mur_sol((x1,y1+4,z1),(x2,y1+4,z2),mur) + mur_sol((x1,y1,z1),(x2,y1,z2),sol) + + mur_sol((midtailleX,y1+4,midtailleZ),(x2,y1+4,z2),air) + + mur_sol((midtailleX,y1,midtailleZ),(x2,y1,z2),grass) + + poserFenetre((midtailleX+1,y1+1,midtailleZ-1),(x2-1,y1+5,midtailleZ-1),glass) + poserFenetre((x2-1,y1+1,z1+1),(x2-1,y1+5,midtailleZ-1 ),glass) + poserFenetre((x1,y1+1,z1+1),(x1,y1+5,z2-1),glass) + poserFenetre((x1+1,y1+1,z1),(x2-1,y1+5,z1),glass) + poserFenetre((midtailleX-1,y1+1,midtailleZ+1 ),(midtailleX-1,y1+5,z2-2),glass) + + + + + + if (((x2-x1)//2))%2==0: + + poserPorte((x2-tailleX//4,hauteurMin+1,midtailleZ),door) + poserPorte((x2-1-tailleX//4,hauteurMin+1,midtailleZ),door) + mur_sol((x2-1-tailleX//4,y1,midtailleZ),(x2-3-tailleX//4,y1,z2),chemin) + for i in range(tailleX): + for j in range(tailleZ): + if (x1+i>= midtailleX and z1+j>=midtailleZ )and (x1+i==x2-1 or z1+j==z2-1) and x1+i != x2-2-tailleX//4 and x1+i != x2-1-tailleX//4: + + editor.placeBlock((x1+i,y1+1,z1+j),fence) + else: + + poserPorte((x2-1-tailleX//4,hauteurMin+1,midtailleZ-1),door) + mur_sol((x2-1-tailleX//4,y1,midtailleZ),(x2-2-tailleX//4,y1,z2),chemin) + for i in range(tailleX): + for j in range(tailleZ): + if (x1+i>= midtailleX and z1+j>=midtailleZ )and (x1+i==x2-1 or z1+j==z2-1) and x1+i != x2-1-tailleX//4: + + editor.placeBlock((x1+i,y1+1,z1+j),fence) + + + + + poserToit(co1,co2,hauteurMax,cotegarage,style,direction ) + + + +if __name__=="__main__": + + + + + + nb_style=randint(0,3) + + delete((-40,-60,-40),(50,-40,50)) + + house((-20,-60,-20),(-10,-60,-10),"right",10,nb_style,'north') + + + + + + + + + + diff --git a/networks/legacy_roads/list_block.py b/networks/legacy_roads/list_block.py new file mode 100644 index 0000000..b3dd29d --- /dev/null +++ b/networks/legacy_roads/list_block.py @@ -0,0 +1,117 @@ +from gdpc import Block + + +air = Block('air') + +stairs_devant = Block("oak_stairs", {"facing": "east"}) +stairs_derriere = Block("oak_stairs", {"facing": "west"}) +stairs_droite = Block("oak_stairs", {"facing": "north"}) +stairs_gauche = Block("oak_stairs", {"facing": "south"}) + +stairs_devant_retourner = Block( + "oak_stairs", {"facing": "east", "half": "top"}) +stairs_derriere_retourner = Block( + "oak_stairs", {"facing": "west", "half": "top"}) +stairs_droite_retourner = Block( + "oak_stairs", {"facing": "north", "half": "top"}) +stairs_gauche_retourner = Block( + "oak_stairs", {"facing": "south", "half": "top"}) + + +stairs_quartz_devant = Block( + "quartz_stairs", {"facing": "east", "half": "top"}) +stairs_quartz_derriere = Block( + "quartz_stairs", {"facing": "west", "half": "top"}) +stairs_quartz_droite = Block( + "quartz_stairs", {"facing": "north", "half": "top"}) +stairs_quartz_gauche = Block( + "quartz_stairs", {"facing": "south", "half": "top"}) + + +door_east = Block("oak_door", {"facing": "east"}) + + +oak_planks = Block("oak_planks") +oak_log = Block("oak_log") +spruce_wood = Block("spruce_wood") + + +black_stained_glass = Block("black_stained_glass") + + +white_concrete_powder = Block("white_concrete_powder") +white_concrete = Block("white_concrete") + +grass_block = Block("grass_block") +podzol = Block("podzol") + +block_quartz = Block("quartz_block") + + +block_white_concrete = Block("white_concrete") + + +oak_slab = Block('oak_slab') +quartz_slab_up = Block('quartz_slab', {"type": "top"}) + +oak_fence = Block('oak_fence') + + +style_basique = { + 'mur': "white_concrete", + 'sol': "oak_planks", + 'grass': "grass_block", + 'chemin': "quartz_block", + 'fence': 'oak_fence', + 'toit_esca': 'oak_stairs', + 'toit_planche': "oak_planks", + 'toit_slab': 'oak_slab', + 'glass': "glass", + 'door': 'oak_door' + + +} + +style_jungle = { + 'mur': "light_gray_concrete", + 'sol': "acacia_planks", + 'grass': "grass_block", + 'chemin': "podzol", + 'fence': 'acacia_fence', + 'toit_esca': 'acacia_stairs', + 'toit_planche': "acacia_planks", + 'toit_slab': 'acacia_slab', + 'glass': "glass", + 'door': 'acacia_door' + + +} +style_end = { + 'mur': "purple_concrete", + 'sol': "crimson_planks", + 'grass': "grass_block", + 'chemin': "amethyst_block", + 'fence': 'crimson_fence', + 'toit_esca': 'crimson_stairs', + 'toit_planche': "crimson_planks", + 'toit_slab': 'crimson_slab', + 'glass': "glass", + 'door': 'crimson_door' + + +} + +style_birch = { + 'mur': "yellow_concrete", + 'sol': "birch_planks", + 'grass': "grass_block", + 'chemin': "rooted_dirt", + 'fence': 'birch_fence', + 'toit_esca': 'birch_stairs', + 'toit_planche': "birch_planks", + 'toit_slab': 'birch_slab', + 'glass': "glass", + 'door': 'birch_door' + + +} diff --git a/networks/legacy_roads/maths.py b/networks/legacy_roads/maths.py new file mode 100644 index 0000000..c6afee8 --- /dev/null +++ b/networks/legacy_roads/maths.py @@ -0,0 +1,1155 @@ +from math import sqrt +from math import pi +from math import cos, sin +import matplotlib.pyplot as plt +import numpy as np +from scipy import interpolate + + +def line(xyz1, xyz2, pixelPerfect=True): + """ + Calculate a line between two points in 3D space. + + https://www.geeksforgeeks.org/bresenhams-algorithm-for-3-d-line-drawing/ + + Args: + xyz1 (tuple): First coordinates. + xyz2 (tuple): Second coordinates. + pixelPerfect (bool, optional): Blocks will be placed diagonally, + not side by side if pixelPerfect is True. Defaults to True. + + Returns: + list: List of blocks. + """ + (x1, y1, z1) = xyz1 + (x2, y2, z2) = xyz2 + x1, y1, z1, x2, y2, z2 = ( + round(x1), + round(y1), + round(z1), + round(x2), + round(y2), + round(z2), + ) + + ListOfPoints = [] + ListOfPoints.append((x1, y1, z1)) + dx = abs(x2 - x1) + dy = abs(y2 - y1) + dz = abs(z2 - z1) + if x2 > x1: + xs = 1 + else: + xs = -1 + if y2 > y1: + ys = 1 + else: + ys = -1 + if z2 > z1: + zs = 1 + else: + zs = -1 + + # Driving axis is X-axis + if dx >= dy and dx >= dz: + p1 = 2 * dy - dx + p2 = 2 * dz - dx + while x1 != x2: + x1 += xs + ListOfPoints.append((x1, y1, z1)) + if p1 >= 0: + y1 += ys + if not pixelPerfect: + if ListOfPoints[-1][1] != y1: + ListOfPoints.append((x1, y1, z1)) + p1 -= 2 * dx + if p2 >= 0: + z1 += zs + if not pixelPerfect: + if ListOfPoints[-1][2] != z1: + ListOfPoints.append((x1, y1, z1)) + p2 -= 2 * dx + p1 += 2 * dy + p2 += 2 * dz + + # Driving axis is Y-axis + elif dy >= dx and dy >= dz: + p1 = 2 * dx - dy + p2 = 2 * dz - dy + while y1 != y2: + y1 += ys + ListOfPoints.append((x1, y1, z1)) + if p1 >= 0: + x1 += xs + if not pixelPerfect: + if ListOfPoints[-1][0] != x1: + ListOfPoints.append((x1, y1, z1)) + p1 -= 2 * dy + if p2 >= 0: + z1 += zs + if not pixelPerfect: + if ListOfPoints[-1][2] != z1: + ListOfPoints.append((x1, y1, z1)) + p2 -= 2 * dy + p1 += 2 * dx + p2 += 2 * dz + + # Driving axis is Z-axis + else: + p1 = 2 * dy - dz + p2 = 2 * dx - dz + while z1 != z2: + z1 += zs + ListOfPoints.append((x1, y1, z1)) + if p1 >= 0: + y1 += ys + if not pixelPerfect: + if ListOfPoints[-1][1] != y1: + ListOfPoints.append((x1, y1, z1)) + p1 -= 2 * dz + if p2 >= 0: + x1 += xs + if not pixelPerfect: + if ListOfPoints[-1][0] != x1: + ListOfPoints.append((x1, y1, z1)) + p2 -= 2 * dz + p1 += 2 * dy + p2 += 2 * dx + return ListOfPoints + + +def offset(distance, xy1, xy2): + """ + Compute the coordinates of perpendicular points from two points. 2D + only. + + Args: + distance (int): Distance from the line[xy1;xy2] of the + perpendicular points. + xy1 (tuple): First position. + xy2 (tuple): Second position. + + Returns: + tuple: The coordinates of perpendicular points. + A: Perpendicular from [xy1;xy2] at distance from pos1. + B: perpendicular from [xy1;xy2] at -distance from pos1. + C: perpendicular from [xy2;xy1] at distance from pos2. + D: perpendicular from [xy2;xy1] at -distance from pos2. + """ + A, B = perpendicular(distance * 2, xy1, xy2) + C, D = perpendicular(distance * 2, xy2, xy1) + return ([A, D], [B, C]) + + +def perpendicular(distance, xy1, xy2): + """ + Return a tuple of the perpendicular coordinates. + + Args: + distance (int): Distance from the line[xy1;xy2]. + xy1 (tuple): First coordinates. + xy2 (tuple): Second coordinates. + + Returns: + tuple: Coordinates of the line length distance, perpendicular + to [xy1; xy2] at xy1. + """ + (x1, y1) = xy1 + (x2, y2) = xy2 + dx = x1 - x2 + dy = y1 - y2 + dist = sqrt(dx * dx + dy * dy) + dx /= dist + dy /= dist + x3 = x1 + (distance / 2) * dy + y3 = y1 - (distance / 2) * dx + x4 = x1 - (distance / 2) * dy + y4 = y1 + (distance / 2) * dx + return ((round(x3), round(y3)), (round(x4), round(y4))) + + +def curve(points, number_true_pts=40, debug=False): + """ + Returns a 3d curve. + + https://stackoverflow.com/questions/18962175/spline-interpolation-coefficients-of-a-line-curve-in-3d-space + + Args: + points (np.array): Points where the curves should pass. + number_true_pts (int, optional): Number of points to compute. Defaults to 40. + debug (bool, optional): Just a visual graphic. Defaults to False. + + Returns: + tuple: Tuple of list of each coordinate. + """ + # Remove duplicates. + points = tuple(map(tuple, points)) + points = sorted(set(points), key=points.index) + + x_sample = [] + y_sample = [] + z_sample = [] + + for i in range(len(points)): + x_sample.append(points[i][0]) + z_sample.append(points[i][1]) + y_sample.append(points[i][2]) + + x_sample = np.array(x_sample) + y_sample = np.array(y_sample) + z_sample = np.array(z_sample) + + tck, u = interpolate.splprep([x_sample, y_sample, z_sample], s=2, k=2) + x_knots, y_knots, z_knots = interpolate.splev(tck[0], tck) + u_fine = np.linspace(0, 1, number_true_pts) + x_fine, y_fine, z_fine = interpolate.splev(u_fine, tck) + + if debug: + fig2 = plt.figure(2) + ax3d = fig2.add_subplot(111, projection="3d") + ax3d.plot(x_sample, y_sample, z_sample, "r*") + ax3d.plot(x_knots, y_knots, z_knots, "go") + ax3d.plot(x_fine, y_fine, z_fine, "r") + fig2.show() + plt.show() + + x = x_fine.tolist() + z = y_fine.tolist() + y = z_fine.tolist() + + for i in x: + i = round(i) + for i in y: + i = round(i) + for i in z: + i = round(i) + + return x, y, z + + +def curveOffset(x, y, z, distance=5): + """ + Offset a curve. + + Args: + x (list): List of x coordinates. + y (list): List of y coordinates. + z (list): List of z coordinates. + distance (int, optional): Distance of offsetting. Defaults to 5. + + Returns: + tuple: Lists of points from the upper curve and the lower curve. + + TODO: + The accuracy can be improved by finding the inner and outer arc: + connect the points of the arc and not calculate their + middle. + """ + lineA = [] + lineB = [] + line0 = [] + line1 = [] + + # Offsetting + for i in range(len(x) - 1): + parallel = offset(distance, (x[i], z[i]), (x[i + 1], z[i + 1])) + lineA.append( + ( + (parallel[0][0][0], y[i], parallel[0][0][1]), + (parallel[0][1][0], y[i + 1], parallel[0][1][1]), + ) + ) + lineB.append( + ( + (parallel[1][0][0], y[i], parallel[1][0][1]), + (parallel[1][1][0], y[i + 1], parallel[1][1][1]), + ) + ) + + # First points + # print(x, y, z, distance) + # print(x, len(x)) + # print("lineA:", lineA) + # print("parallel:", parallel) + line0.append( + ( + round(lineA[0][0][0]), + round(lineA[0][0][1]), + round(lineA[0][0][2]), + ) + ) + line1.append( + ( + round(lineB[0][0][0]), + round(lineB[0][0][1]), + round(lineB[0][0][2]), + ) + ) + + # Middle of between segments + for i in range(len(lineA) - 1): + line0.append( + ( + round((lineA[i][1][0] + lineA[i + 1][0][0]) / 2), + round((lineA[i][1][1] + lineA[i + 1][0][1]) / 2), + round((lineA[i][1][2] + lineA[i + 1][0][2]) / 2), + ) + ) + line1.append( + ( + round((lineB[i][1][0] + lineB[i + 1][0][0]) / 2), + round((lineB[i][1][1] + lineB[i + 1][0][1]) / 2), + round((lineB[i][1][2] + lineB[i + 1][0][2]) / 2), + ) + ) + + # Last points + line0.append( + ( + round(lineA[-1][1][0]), + round(lineA[-1][1][1]), + round(lineA[-1][1][2]), + ) + ) + line1.append( + ( + round(lineB[-1][1][0]), + round(lineB[-1][1][1]), + round(lineB[-1][1][2]), + ) + ) + + return line0, line1 + + +def pixelPerfect(path): + """ + Remove blocks that are side by side in the path. Keep the blocks + that are in diagonal. + + Args: + path (list): List of coordinates from a path. + + Returns: + list: List cleaned. + + TODO: + Add 3D. + """ + # NotPixelPerfect detection + if len(path) == 1 or len(path) == 0: + return path + else: + notPixelPerfect = [] + c = 0 + while c < len(path): + if c > 0 and c + 1 < len(path): + if ( + ( + path[c - 1][0] == path[c][0] + or path[c - 1][1] == path[c][1] + ) + and ( + path[c + 1][0] == path[c][0] + or path[c + 1][1] == path[c][1] + ) + and path[c - 1][1] != path[c + 1][1] + and path[c - 1][0] != path[c + 1][0] + ): + notPixelPerfect.append(path[c]) + c += 1 + + # Double notPixelPerfect detection + if len(notPixelPerfect) == 1 or len(notPixelPerfect) == 0: + return notPixelPerfect + else: + d = 0 + while d < len(notPixelPerfect): + if d + 1 < len(notPixelPerfect): + if ( + notPixelPerfect[d][0] == notPixelPerfect[d + 1][0] + and (notPixelPerfect[d][1] - notPixelPerfect[d + 1][1]) + in {1, -1} + ) or ( + notPixelPerfect[d][1] == notPixelPerfect[d + 1][1] + and (notPixelPerfect[d][0] - notPixelPerfect[d + 1][0]) + in {1, -1} + ): + notPixelPerfect.remove(notPixelPerfect[d + 1]) + d += 1 + + # Remove notPixelPerfect from path + for i in range(len(notPixelPerfect)): + path.remove(notPixelPerfect[i]) + + return path + + +def cleanLine(path): # HERE + """ + Clean and smooth a list of blocks. Works in 2d but supports 3d. + + Args: + path (list): List of blocks. + + Returns: + list: List cleaned. + + TODO: + Do not work perfectly since 16/04/2021. + Add new patterns. + Problem with i -= 10 : solved but not understand why. + 16/04/2021. + """ + + pathTemp = [] + for i in path: + if i not in pathTemp: + pathTemp.append(i) + path = pathTemp + + i = 0 + + while i < len(path): + + # 2 blocks, 90 degrees, 2 blocks = 1 block, 1 block, 1 block + if i + 3 < len(path): + if ( + path[i][0] == path[i + 1][0] + and path[i + 2][-1] == path[i + 3][-1] + ): + if len(path[i + 1]) == 3: + path.insert( + (i + 1), + (path[i + 2][0], path[i + 2][1], path[i + 1][-1]), + ) + else: + path.insert((i + 1), (path[i + 2][0], path[i + 1][-1])) + del path[i + 2] # 2nd block + del path[i + 2] # 3rd block + i -= 1 + continue + elif ( + path[i][-1] == path[i + 1][-1] + and path[i + 2][0] == path[i + 3][0] + ): + if len(path[i + 1]) == 3: + path.insert( + (i + 1), + (path[i + 1][0], path[i + 1][1], path[i + 2][-1]), + ) + else: + path.insert( + (i + 1), + (path[i + 1][0], path[i + 2][-1]), + ) + del path[i + 2] # 2nd block + del path[i + 2] # 3rd block + i -= 1 + continue + + # 1 block, 3 blocks, 1 block = 1 block, 2 blocks, 2 blocks + if i - 1 >= 0 and i + 5 <= len(path): + if ( + ( + path[i + 1][-1] == path[i + 2][-1] + and path[i + 2][-1] == path[i + 3][-1] + ) + and ( + path[i + 1][-1] != path[i][-1] + and path[i + 3][-1] != path[i + 4][-1] + ) + and ( + path[i - 1][-1] != path[i][-1] + and path[i + 4][-1] != path[i + 5][-1] + ) + ): + if len(path[i]) == 3: + path.insert( + (i + 1), (path[i + 1][0], path[i + 1][1], path[i][-1]) + ) + else: + path.insert((i + 1), (path[i + 1][0], path[i][-1])) + del path[i + 2] # 2nd block + i -= 1 + continue + elif ( + ( + path[i + 1][0] == path[i + 2][0] + and path[i + 2][0] == path[i + 3][0] + ) + and ( + path[i + 1][0] != path[i][0] + and path[i + 3][0] != path[i + 4][0] + ) + and ( + path[i - 1][0] != path[i][0] + and path[i + 4][0] != path[i + 5][0] + ) + ): + if len(path[i]) == 3: + path.insert( + (i + 1), (path[i][0], path[i][1], path[i + 1][-1]) + ) + else: + path.insert((i + 1), (path[i][0], path[i + 1][-1])) + del path[i + 2] # 2nd block + i -= 1 + continue + + i += 1 + + return path + + +def distance2D(A, B): # TODO : Can be better. + return sqrt((B[0] - A[0]) ** 2 + (B[1] - A[1]) ** 2) + + +def curveSurface( + points, + distance, + resolution=7, + pixelPerfect=False, + factor=2, + start=0, + returnLine=True, +): # HERE + """ + Create a curve with a thickness. + + Args: + points (numpy.ndarray): Points where the curve should go. + distance (int): Thickness. + resolution (int, optional): Number of blocks that separate each + point to calculate parallel curves. 0 to use the points + calculated to create the curve. Defaults to 7. + pixelPerfect (bool, optional): True to avoid heaps. Defaults to + False. + factor (int, optional): Number of sub-line that will be + calculated to avoid hole with coordinates. Defaults to 2. + + Returns: + dict: Key 0 is the list of coordinates of the center line. + Positive keys are lists of coordinates of lines on the right + side, negative keys are for the left side. + + >>> curveSurface( + np.array( + [ + [12, 248, -103], + [-5, 219, -85], + [-22, 205, -128], + [-51, 70, -240], + [40, 198, -166], + [19, 241, -102], + [-6, 62, -223], + ] + ), + 5, + resolution=7, + ) + """ + if len((points)) >= 3: + # Calculate resolution of the main curve depending of the total curve length. + lenCurve = 0 + for i in range(len(points) - 1): + lenCurve += sqrt( + ((points[i][0] - points[i + 1][0]) ** 2) + + ((points[i][1] - points[i + 1][1]) ** 2) + + ((points[i][2] - points[i + 1][2]) ** 2) + ) + number_true_pts = round(lenCurve / 6) + + # Calculate the main line. + X, Y, Z = curve(points, number_true_pts) + if len(X) < 2: + X, Y, Z = ( + (points[0][0], points[1][0]), + (points[0][1], points[1][1]), + (points[0][2], points[1][2]), + ) + else: + X, Y, Z = ( + (points[0][0], points[1][0]), + (points[0][1], points[1][1]), + (points[0][2], points[1][2]), + ) + + centerLineTemp = [] + for i in range(len(X) - 1): + xyz0 = X[i], Y[i], Z[i] + xyz1 = (X[i + 1], Y[i + 1], Z[i + 1]) + centerLineTemp.extend(line(xyz0, xyz1)) + + if not returnLine: + returnPoints = [] + for i in range(len(X)): + returnPoints.append((round(X[i]), round(Y[i]), round(Z[i]))) + + # Clean the main line. + # centerLine = cleanLine(centerLineTemp) + centerLine = centerLineTemp + + # Offset. + centerPoints = [] + + if resolution != 0: + for i in range(0, len(centerLine), resolution): + centerPoints.append(centerLine[i]) + else: + for i in range(len(X)): + centerPoints.append((X[i], Y[i], Z[i])) + + X = [centerPoints[i][0] for i in range(len(centerPoints))] + Y = [centerPoints[i][1] for i in range(len(centerPoints))] + Z = [centerPoints[i][2] for i in range(len(centerPoints))] + + rightPoints = [] + leftPoints = [] + + # print(centerLine, "XYZ centerPoint to offset") + # print(cleanLine(centerLineTemp), "with cleanLine") + for i in range(start * factor, distance * factor): + rightPoint, leftPoint = curveOffset(X, Y, Z, i / factor) + rightPoints.append(rightPoint) + leftPoints.append(leftPoint) + + rightLine = [] + leftLine = [] + rightSide = [] + leftSide = [] + + if returnLine == True: # Creating lines on each side between each point. + for i in range(len(rightPoints)): + for j in range(len(rightPoints[i]) - 1): + rightLine.extend( + line( + rightPoints[i][j], + rightPoints[i][j + 1], + pixelPerfect, + ) + ) + rightSide.append(rightLine) + rightLine = [] + + for i in range(len(leftPoints)): + for j in range(len(leftPoints[i]) - 1): + leftLine.extend( + line( + leftPoints[i][j], + leftPoints[i][j + 1], + pixelPerfect, + ) + ) + leftSide.append(leftLine) + leftLine = [] + + else: # Do not create lines. Points instead. + for i in range(len(rightPoints)): + for j in range(len(rightPoints[i])): + rightLine.append(rightPoints[i][j]) + rightSide.append(rightLine) + rightLine = [] + + for i in range(len(leftPoints)): + for j in range(len(leftPoints[i])): + leftLine.append(leftPoints[i][j]) + leftSide.append(leftLine) + leftLine = [] + + # Returns. 0 is the center line, positive values ​​are lines on the + # right, negative values ​​are lines on the left. + smoothCurveSurfaceDict = {} + if returnLine: + smoothCurveSurfaceDict[0] = centerLine + else: + smoothCurveSurfaceDict[0] = returnPoints + + countLine = 0 + for l in rightSide: + # l = cleanLine(l) + countLine += 1 + smoothCurveSurfaceDict[countLine] = l + countLine = 0 + for l in leftSide: + # l = cleanLine(l) + countLine -= 1 + smoothCurveSurfaceDict[countLine] = l + + return smoothCurveSurfaceDict + + +def getAngle(xy0, xy1, xy2): + """ + Compute angle (in degrees) for xy0, xy1, xy2 corner. + + https://stackoverflow.com/questions/13226038/calculating-angle-between-two-vectors-in-python + + Args: + xy0 (numpy.ndarray): Points in the form of [x,y]. + xy1 (numpy.ndarray): Points in the form of [x,y]. + xy2 (numpy.ndarray): Points in the form of [x,y]. + + Returns: + float: Angle negative for counterclockwise angle, angle positive + for counterclockwise angle. + """ + if xy2 is None: + xy2 = xy1 + np.array([1, 0]) + v0 = np.array(xy0) - np.array(xy1) + v1 = np.array(xy2) - np.array(xy1) + + angle = np.math.atan2(np.linalg.det([v0, v1]), np.dot(v0, v1)) + return np.degrees(angle) + + +def lineIntersection(line0, line1, fullLine=True): + """ + Find (or not) intersection between two lines. Works in 2d but + supports 3d. + + https://stackoverflow.com/questions/20677795/how-do-i-compute-the-intersection-point-of-two-lines + + Args: + line0 (tuple): Tuple of tuple of coordinates. + line1 (tuple): Tuple of tuple of coordinates. + fullLine (bool, optional): True to find intersections along + full line - not just in the segment. + + Returns: + tuple: Coordinates (2d). + + >>> lineIntersection(((0, 0), (0, 5)), ((2.5, 2.5), (-2.5, 2.5))) + """ + xdiff = (line0[0][0] - line0[1][0], line1[0][0] - line1[1][0]) + ydiff = (line0[0][-1] - line0[1][-1], line1[0][-1] - line1[1][-1]) + + def det(a, b): + return a[0] * b[-1] - a[-1] * b[0] + + div = det(xdiff, ydiff) + if div == 0: + return None + + d = (det(*line0), det(*line1)) + x = det(d, xdiff) / div + y = det(d, ydiff) / div + + if not fullLine: + if ( + min(line0[0][0], line0[1][0]) <= x <= max(line0[0][0], line0[1][0]) + and min(line1[0][0], line1[1][0]) + <= x + <= max(line1[0][0], line1[1][0]) + and min(line0[0][-1], line0[1][-1]) + <= y + <= max(line0[0][-1], line0[1][-1]) + and min(line1[0][-1], line1[1][-1]) + <= y + <= max(line1[0][-1], line1[1][-1]) + ): + return x, y + else: + return None + else: + return x, y + + +def circleLineSegmentIntersection( + circleCenter, circleRadius, xy0, xy1, fullLine=True, tangentTol=1e-9 +): + """ + Find the points at which a circle intersects a line-segment. This + can happen at 0, 1, or 2 points. Works in 2d but supports 3d. + + https://stackoverflow.com/questions/30844482/what-is-most-efficient-way-to-find-the-intersection-of-a-line-and-a-circle-in-py + Note: We follow: http://mathworld.wolfram.com/Circle-LineIntersection.html + + Args: + circleCenter (tuple): The (x, y) location of the circle center. + circleRadius (int): The radius of the circle. + xy0 (tuple): The (x, y) location of the first point of the + segment. + xy1 ([tuple]): The (x, y) location of the second point of the + segment. + fullLine (bool, optional): True to find intersections along + full line - not just in the segment. False will just return + intersections within the segment. Defaults to True. + tangentTol (float, optional): Numerical tolerance at which we + decide the intersections are close enough to consider it a + tangent. Defaults to 1e-9. + + Returns: + list: A list of length 0, 1, or 2, where each element is a point + at which the circle intercepts a line segment (2d). + """ + + (p1x, p1y), (p2x, p2y), (cx, cy) = ( + (xy0[0], xy0[-1]), + (xy1[0], xy1[-1]), + (circleCenter[0], circleCenter[1]), + ) + (x1, y1), (x2, y2) = (p1x - cx, p1y - cy), (p2x - cx, p2y - cy) + dx, dy = (x2 - x1), (y2 - y1) + dr = (dx ** 2 + dy ** 2) ** 0.5 + big_d = x1 * y2 - x2 * y1 + discriminant = circleRadius ** 2 * dr ** 2 - big_d ** 2 + + if discriminant < 0: # No intersection between circle and line + return [] + else: # There may be 0, 1, or 2 intersections with the segment + intersections = [ + ( + cx + + ( + big_d * dy + + sign * (-1 if dy < 0 else 1) * dx * discriminant ** 0.5 + ) + / dr ** 2, + cy + + (-big_d * dx + sign * abs(dy) * discriminant ** 0.5) + / dr ** 2, + ) + for sign in ((1, -1) if dy < 0 else (-1, 1)) + ] # This makes sure the order along the segment is correct + if ( + not fullLine + ): # If only considering the segment, filter out intersections that do not fall within the segment + fraction_along_segment = [ + (xi - p1x) / dx if abs(dx) > abs(dy) else (yi - p1y) / dy + for xi, yi in intersections + ] + intersections = [ + pt + for pt, frac in zip(intersections, fraction_along_segment) + if 0 <= frac <= 1 + ] + if ( + len(intersections) == 2 and abs(discriminant) <= tangentTol + ): # If line is tangent to circle, return just one point (as both intersections have same location) + return [intersections[0]] + else: + return intersections + + +def circle(xyC, r): + """ + Can be used for circle or disc. + + Args: + xyC (tuple): Coordinates of the center. + r (int): Radius of the circle. + + Returns: + dict: Keys are distance from the circle. Value is a list of all + coordinates at this distance. 0 for a circle. Negative values + for a disc, positive values for a hole. + """ + area = ( + (round(xyC[0]) - round(r), round(xyC[1]) - round(r)), + (round(xyC[0]) + round(r) + 1, round(xyC[1]) + round(r) + 1), + ) + + circle = {} + for x in range(area[0][0], area[1][0]): + for y in range(area[0][1], area[1][1]): + d = round(distance2D((x, y), (xyC))) - r + if circle.get(d) == None: + circle[d] = [] + circle[d].append((x, y)) + return circle + + +def circleIntersections(xy0, r0, xy1, r1): + # https://stackoverflow.com/questions/55816902/finding-the-intersection-of-two-circles + + x0, y0 = xy0 + x1, y1 = xy1 + d = sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2) + + # Non intersecting. + if d > r0 + r1: + return None + # One circle within other. + if d < abs(r0 - r1): + return None + # Coincident circles. + if d == 0 and r0 == r1: + return None + else: + a = (r0 ** 2 - r1 ** 2 + d ** 2) / (2 * d) + h = sqrt(r0 ** 2 - a ** 2) + x2 = x0 + a * (x1 - x0) / d + y2 = y0 + a * (y1 - y0) / d + x3 = x2 + h * (y1 - y0) / d + y3 = y2 - h * (x1 - x0) / d + + x4 = x2 - h * (y1 - y0) / d + y4 = y2 + h * (x1 - x0) / d + + return ((x3, y3), (x4, y4)) + + +def InTriangle(point, xy0, xy1, xy2): + # https://stackoverflow.com/questions/2049582/how-to-determine-if-a-point-is-in-a-2d-triangle#:~:text=A%20simple%20way%20is%20to,point%20is%20inside%20the%20triangle. + dX = point[0] - xy0[0] + dY = point[1] - xy0[1] + dX20 = xy2[0] - xy0[0] + dY20 = xy2[1] - xy0[1] + dX10 = xy1[0] - xy0[0] + dY10 = xy1[1] - xy0[1] + + s_p = (dY20 * dX) - (dX20 * dY) + t_p = (dX10 * dY) - (dY10 * dX) + D = (dX10 * dY20) - (dY10 * dX20) + + if D > 0: + return (s_p >= 0) and (t_p >= 0) and (s_p + t_p) <= D + else: + return (s_p <= 0) and (t_p <= 0) and (s_p + t_p) >= D + + +def circlePoints(xyC, r, n=100): + # https://stackoverflow.com/questions/8487893/generate-all-the-points-on-the-circumference-of-a-circle + points = [ + (cos(2 * pi / n * x) * r, sin(2 * pi / n * x) * r) + for x in range(0, n + 1) + ] + + for i in range(len(points)): + points[i] = ( + points[i][0] + xyC[0], + points[i][1] + xyC[1], + ) + + return points + + +def optimizedPath(coords, start=None): + # https://stackoverflow.com/questions/45829155/sort-points-in-order-to-have-a-continuous-curve-using-python + if start is None: + start = coords[0] + pass_by = coords + path = [start] + pass_by.remove(start) + while pass_by: + nearest = min(pass_by, key=lambda x: distance2D(path[-1], x)) + path.append(nearest) + pass_by.remove(nearest) + return path + + +def nearest(points, start): + return min(points, key=lambda x: distance2D(start, x)) + + +def sortRotation(points): + """ + Sort point in a rotation order. Works in 2d but supports 3d. + + https://stackoverflow.com/questions/58377015/counterclockwise-sorting-of-x-y-data + + Args: + points: List of points to sort in the form of [(x, y, z), (x, y, + z)] or [(x, y), (x, y), (x, y), (x, y)]... + + Returns: + list: List of tuples of coordinates sorted (2d or 3d). + + >>> sortRotation([(0, 45, 100), (4, -5, 5),(-5, 36, -2)]) + [(0, 45, 100), (-5, 36, -2), (4, -5, 5)] + """ + x, y = [], [] + for i in range(len(points)): + x.append(points[i][0]) + y.append(points[i][-1]) + x, y = np.array(x), np.array(y) + + x0 = np.mean(x) + y0 = np.mean(y) + + r = np.sqrt((x - x0) ** 2 + (y - y0) ** 2) + + angles = np.where( + (y - y0) > 0, + np.arccos((x - x0) / r), + 2 * np.pi - np.arccos((x - x0) / r), + ) + + mask = np.argsort(angles) + + x_sorted = list(x[mask]) + y_sorted = list(y[mask]) + + # Rearrange tuples to get the right coordinates. + sortedPoints = [] + for i in range(len(points)): + j = 0 + while (x_sorted[i] != points[j][0]) and (y_sorted[i] != points[j][-1]): + j += 1 + else: + if len(points[0]) == 3: + sortedPoints.append((x_sorted[i], points[j][1], y_sorted[i])) + else: + sortedPoints.append((x_sorted[i], y_sorted[i])) + + return sortedPoints + + +def curveCornerIntersectionPoints( + line0, line1, startDistance, angleAdaptation=False +): + """ + Create points between the two lines to smooth the intersection. + + Args: + line0 (tuple): Tuple of tuple. Line coordinates. Order matters. + line1 (tuple): Tuple of tuple. Line coordinates. Order matters. + startDistance (int): distance from the intersection where the + curve should starts. + angleAdaptation (bool, optional): True will adapt the + startDistance depending of the angle between the two lines. + False will force the distance to be startDistance. Defaults to + False. + + Returns: + [list]: List of tuple of coordinates (2d) that forms the curve. + Starts on the line and end on the other line. + + >>> curveCornerIntersectionPoints(((0, 0), (50, 20)), ((-5, 50), (25, -5)), 10) + """ + intersection = lineIntersection(line0, line1, fullLine=True) + + if intersection == None: + return None + + # Define automatically the distance from the intersection, where the curve + # starts. + if angleAdaptation: + angle = getAngle( + (line0[0][0], line0[0][-1]), + intersection, + (line1[0][0], line1[0][-1]), + ) + # Set here the radius of the circle for a square angle. + startDistance = startDistance * abs(1 / (angle / 90)) + + startCurvePoint = circleLineSegmentIntersection( + intersection, startDistance, line0[0], intersection, fullLine=True + )[0] + endCurvePoint = circleLineSegmentIntersection( + intersection, startDistance, line1[0], intersection, fullLine=True + )[0] + # Higher value for better precision + perpendicular0 = perpendicular(10e3, startCurvePoint, intersection)[0] + perpendicular1 = perpendicular(10e3, endCurvePoint, intersection)[1] + + center = lineIntersection( + (perpendicular0, startCurvePoint), (perpendicular1, endCurvePoint) + ) + + # Distance with startCurvePoint and endCurvePoint from the center are the + # same. + radius = distance2D(startCurvePoint, center) + + circle = circlePoints( + center, round(radius), 32 + ) # n=round((2 * pi * radius) / 32) + + # Find the correct point on the circle. + curveCornerPointsTemp = [startCurvePoint] + for point in circle: + if InTriangle(point, intersection, startCurvePoint, endCurvePoint): + curveCornerPointsTemp.append(point) + curveCornerPointsTemp.append(endCurvePoint) + + # Be sure that all the points are in correct order. + curveCornerPoints = optimizedPath(curveCornerPointsTemp, startCurvePoint) + return curveCornerPoints + + +def curveCornerIntersectionLine( + line0, line1, startDistance, angleAdaptation=False, center=() +): + """ + Create a continuous circular line between the two lines to smooth + the intersection. + + Args: + line0 (tuple): Tuple of tuple. Line coordinates. Order matters. + line1 (tuple): Tuple of tuple. Line coordinates. Order matters. + startDistance (int): distance from the intersection where the + curve should starts. + angleAdaptation (bool, optional): True will adapt the + startDistance depending of the angle between the two lines. + False will force the distance to be startDistance. Defaults to + False. + + Returns: + [list]: List of tuple of coordinates (2d) that forms the curve. + Starts on the line and end on the other line. + + TODO: + angleAdaptation : Set circle radius and not startDistance. + Polar coordinates / Unit circle instead of InTriangle. + + >>> curveCornerIntersectionLine(((0, 0), (50, 20)), ((-5, 50), (25, -5)), 10) + """ + intersection = lineIntersection(line0, line1, fullLine=True) + + if intersection == None: + return None + + # Define automatically the distance from the intersection, where the curve + # starts. + if angleAdaptation: + angle = getAngle( + (line0[0][0], line0[0][-1]), + intersection, + (line1[0][0], line1[0][-1]), + ) + # Set here the radius of the circle for a square angle. + startDistance = startDistance * abs(1 / (angle / 90)) + + startCurvePoint = circleLineSegmentIntersection( + intersection, startDistance, line0[0], intersection, fullLine=True + )[0] + endCurvePoint = circleLineSegmentIntersection( + intersection, startDistance, line1[0], intersection, fullLine=True + )[0] + # Higher value for better precision + perpendicular0 = perpendicular(10e3, startCurvePoint, intersection)[0] + perpendicular1 = perpendicular(10e3, endCurvePoint, intersection)[1] + + if center == (): + center = lineIntersection( + (perpendicular0, startCurvePoint), (perpendicular1, endCurvePoint) + ) + + # Distance with startCurvePoint and endCurvePoint from the center + # are almost the same. + radius = distance2D(startCurvePoint, center) + + circleArc = circle(center, round(radius))[0] + + # Find the correct point on the circle. + curveCornerPointsTemp = [startCurvePoint] + for point in circleArc: + if InTriangle(point, intersection, startCurvePoint, endCurvePoint): + curveCornerPointsTemp.append(point) + # curveCornerPointsTemp.append(endCurvePoint) + + # Be sure that all the points are in correct order. + curveCornerPoints = optimizedPath(curveCornerPointsTemp, startCurvePoint) + return curveCornerPoints, center + + +def middleLine(xyz0, xyz1): + x = (xyz0[0] + xyz1[0]) / 2 + z = (xyz0[-1] + xyz1[-1]) / 2 + if len(xyz0) <= 2: + return (x, z) + else: + y = (xyz0[1] + xyz1[1]) / 2 + return (round(x), round(y), round(z)) diff --git a/networks/legacy_roads/roads.py b/networks/legacy_roads/roads.py new file mode 100644 index 0000000..e398a34 --- /dev/null +++ b/networks/legacy_roads/roads.py @@ -0,0 +1,662 @@ +import networks.legacy_roads.Skeleton as Skeleton +import networks.legacy_roads.house as house +from math import sqrt +from gdpc import Editor +import sys +from gdpc import Block as place +import numpy as np +import networks.legacy_roads.maths as maths +import math + +import networks.legacy_roads.tools as tools + +import random +from random import randint + +from PIL import Image +from collections import Counter + +alreadyGenerated = [] + + +######################## Lanes materials presets ####################### + + +standard_modern_lane_composition = { + "road_surface": { + "black_concrete": 3, + "coal_block": 1, + "black_concrete_powder": 2, + }, + "median_strip": {"stone": 1}, + "structure": {"stone": 3, "andesite": 1}, + "central_lines": {"yellow_concrete": 3, "yellow_concrete_powder": 1}, + "external_lines": {"white_concrete": 3, "white_concrete_powder": 1}, + "lines": {"white_concrete": 3, "white_concrete_powder": 1}, +} + +# editor.placeBlock((x, y, z), place("minecraft:white_concrete")) + +######################### Additional functions ######################### + + +def cleanLanes(lanes): + cleanLanes = {} + for lane in lanes: + for xyz in lanes[lane]: + if (round(xyz[0]), round(xyz[1]), round(xyz[2]),) not in [ + cleanLanes[i][j] + for __, i in enumerate(cleanLanes) + for j in range(len(cleanLanes[i])) + ]: + if cleanLanes.get(lane) == None: + cleanLanes[lane] = [] + cleanLanes[lane].append( + (round(xyz[0]), round(xyz[1]), round(xyz[2])) + ) + return cleanLanes + + +def findGround(xzStart, xz): # TODO: Change error. + """ + Find the surface at xz using heightmap. + + Args: + xzStart (tuple): Starting coordinates of the heightmap (northwest corner). + xz (tuple): Coordinates xz in the Minecraft world. + + Returns: + tuple: Coordinates xyz in the Minecraft world. + """ + im = Image.open("./world_maker/data/heightmap.png") + x = round(xz[0] - xzStart[0]) + z = round(xz[-1] - xzStart[-1]) + # Alpha is defined as the height ([3]). + width, height = im.size + if x >= width or z >= height: + print("img:", x, z) + print(width, height) + print(xzStart, xz) + try: + return xz[0], (im.getpixel((x, z))[2]) - 1, xz[-1] + except: + print("Error getpixel in map.py:42 with ", x, z) + return None + + +############################ Lanes functions ########################### + +housesCoordinates = [] + + +def singleLaneLeft(XYZ, blocks=standard_modern_lane_composition): + """Left side.""" + + factor = 8 + distance = 2 + + roadMarkings = maths.curveSurface( + np.array(XYZ), + distance + 1, + resolution=0, + pixelPerfect=True, + factor=1, + start=2, + ) + roadMarkings = cleanLanes(roadMarkings) + + roadSurface = maths.curveSurface( + np.array(XYZ), + distance, + resolution=0, + pixelPerfect=False, + factor=factor, + ) + roadSurface = cleanLanes(roadSurface) + + walkway = maths.curveSurface( + np.array(XYZ), + distance + 3, + resolution=0, + pixelPerfect=False, + factor=4, + start=3, + ) + walkway = cleanLanes(walkway) + + houses = maths.curveSurface( + np.array(XYZ), + distance + 14, + resolution=0, + pixelPerfect=False, + factor=1, + start=distance + 13, + ) + houses = cleanLanes(houses) + + road_surface = blocks.get("road_surface") + structure = blocks.get("structure") + + for lane in roadSurface: + for xyz in roadSurface[lane]: + tools.fillBlock( + "air", (xyz[0], xyz[1], xyz[2], xyz[0], xyz[1] + 4, xyz[2]) + ) + tools.setBlock( + random.choices( + list(structure.keys()), + weights=structure.values(), + k=1, + )[0], + (xyz[0], xyz[1] - 1, xyz[2]), + ) + tools.setBlock( + random.choices( + list(road_surface.keys()), + weights=road_surface.values(), + k=1, + )[0], + xyz, + ) + alreadyGenerated.append((xyz[0], xyz[2])) + + lines = blocks.get("lines") + for lane in roadMarkings: + for xyz in roadMarkings[lane]: + if lane == -1: + tools.setBlock( + random.choices( + list(structure.keys()), + weights=structure.values(), + k=1, + )[0], + (xyz[0], xyz[1] - 1, xyz[2]), + ) + tools.setBlock( + random.choices( + list(lines.keys()), + weights=lines.values(), + k=1, + )[0], + (xyz[0], xyz[1], xyz[2]), + ) + + for lane in walkway: + for xyz in walkway[lane]: + if lane <= -1: + counterSegments = 0 + tools.fillBlock( + "air", + (xyz[0], xyz[1] + 1, xyz[2], xyz[0], xyz[1] + 4, xyz[2]), + ) + tools.fillBlock( + random.choices( + list(structure.keys()), + weights=structure.values(), + k=1, + )[0], + (xyz[0], xyz[1] + 1, xyz[2], xyz[0], xyz[1] - 1, xyz[2]), + ) + alreadyGenerated.append((xyz[0], xyz[2])) + + counterSegments = 0 + for lane in houses: + for xyz in houses[lane]: + if lane <= -1: + counterSegments += 1 + if counterSegments % 10 == 0: + housesCoordinates.append((xyz[0], xyz[1], xyz[2])) + + +def singleLaneRight(XYZ, blocks=standard_modern_lane_composition): + """Right side.""" + + factor = 8 + distance = 2 + + roadMarkings = maths.curveSurface( + np.array(XYZ), + distance + 1, + resolution=0, + pixelPerfect=True, + factor=1, + start=2, + ) + roadMarkings = cleanLanes(roadMarkings) + + roadSurface = maths.curveSurface( + np.array(XYZ), + distance, + resolution=0, + pixelPerfect=False, + factor=factor, + ) + roadSurface = cleanLanes(roadSurface) + + walkway = maths.curveSurface( + np.array(XYZ), + distance + 3, + resolution=0, + pixelPerfect=False, + factor=4, + start=3, + ) + walkway = cleanLanes(walkway) + + houses = maths.curveSurface( + np.array(XYZ), + distance + 14, + resolution=0, + pixelPerfect=False, + factor=1, + start=distance + 13, + ) + houses = cleanLanes(houses) + + road_surface = blocks.get("road_surface") + structure = blocks.get("structure") + central_lines = blocks.get("central_lines") + + for lane in roadSurface: + for xyz in roadSurface[lane]: + tools.fillBlock( + "air", (xyz[0], xyz[1], xyz[2], xyz[0], xyz[1] + 4, xyz[2]) + ) + tools.setBlock( + random.choices( + list(structure.keys()), + weights=structure.values(), + k=1, + )[0], + (xyz[0], xyz[1] - 1, xyz[2]), + ) + tools.setBlock( + random.choices( + list(road_surface.keys()), + weights=road_surface.values(), + k=1, + )[0], + xyz, + ) + alreadyGenerated.append((xyz[0], xyz[2])) + + lines = blocks.get("lines") + counterSegments = 0 + for lane in roadMarkings: + for xyz in roadMarkings[lane]: + if lane == 1: + tools.setBlock( + random.choices( + list(structure.keys()), + weights=structure.values(), + k=1, + )[0], + (xyz[0], xyz[1] - 1, xyz[2]), + ) + tools.setBlock( + random.choices( + list(lines.keys()), + weights=lines.values(), + k=1, + )[0], + (xyz[0], xyz[1], xyz[2]), + ) + + if lane == -1: # Central Lane. + counterSegments += 1 + if counterSegments % 4 != 0: + tools.setBlock( + random.choices( + list(structure.keys()), + weights=structure.values(), + k=1, + )[0], + (xyz[0], xyz[1] - 1, xyz[2]), + ) + tools.setBlock( + random.choices( + list(central_lines.keys()), + weights=central_lines.values(), + k=1, + )[0], + (xyz[0], xyz[1], xyz[2]), + ) + else: + tools.setBlock( + random.choices( + list(structure.keys()), + weights=structure.values(), + k=1, + )[0], + (xyz[0], xyz[1] - 1, xyz[2]), + ) + tools.setBlock( + random.choices( + list(road_surface.keys()), + weights=road_surface.values(), + k=1, + )[0], + (xyz[0], xyz[1], xyz[2]), + ) + + for lane in walkway: + for xyz in walkway[lane]: + if lane >= 1: + tools.fillBlock( + "air", + (xyz[0], xyz[1] + 1, xyz[2], xyz[0], xyz[1] + 4, xyz[2]), + ) + tools.fillBlock( + random.choices( + list(structure.keys()), + weights=structure.values(), + k=1, + )[0], + (xyz[0], xyz[1] + 1, xyz[2], xyz[0], xyz[1] - 1, xyz[2]), + ) + alreadyGenerated.append((xyz[0], xyz[2])) + + counterSegments = 0 + for lane in houses: + for xyz in houses[lane]: + if lane >= 1: + counterSegments += 1 + if counterSegments % 10 == 0: + housesCoordinates.append((xyz[0], xyz[1], xyz[2])) + + +############################ Roads Generator ########################### + + +class RoadCurve: + def __init__(self, roadData, XYZ): + print("road, first input:", XYZ) + """Create points that forms the lanes depending of the roadData.""" + self.roadData = roadData + self.XYZ = XYZ + + # Find the offset, where the lanes is. + self.lanesXYZ = {} + for __, i in enumerate(self.roadData["lanes"]): + laneCenterDistance = self.roadData["lanes"][i]["centerDistance"] + self.lanesXYZ[i] = maths.curveSurface( + np.array(XYZ), + abs(laneCenterDistance), + resolution=0, + pixelPerfect=True, + factor=1, + start=abs(laneCenterDistance) - 1, + returnLine=False, + ) + # We only take the desired side. + if laneCenterDistance == 0: + self.lanesXYZ[i] = self.lanesXYZ[i][0] + if laneCenterDistance > 0: + self.lanesXYZ[i] = self.lanesXYZ[i][1] + if laneCenterDistance < 0: + self.lanesXYZ[i] = self.lanesXYZ[i][-1] + + def setLanes(self, lanes=[]): + """Generate the lanes depending of the function name.""" + for __, i in enumerate(self.roadData["lanes"]): + if i in lanes or lanes == []: + self.roadData["lanes"][i]["type"](np.array(self.lanesXYZ[i])) + + def getLanes(self, lanes=[]): + """Return the points that forms the lanes.""" + lanesDict = {} + for __, i in enumerate(self.roadData["lanes"]): + if i in lanes or lanes == []: + lanesDict[i] = self.lanesXYZ[i] + return lanesDict + + +############################# Lanes Preset ############################# + + +standard_modern_lane_agencement = { + "lanes": { + -1: {"type": singleLaneLeft, "centerDistance": -3}, + 1: {"type": singleLaneRight, "centerDistance": 3}, + }, +} + + +standard_modern_lanes_agencement = { + "mainRoads": { + 0: { + "lanes": { + -1: {"type": singleLaneLeft, "centerDistance": -5}, + 0: {"type": singleLaneLeft, "centerDistance": 0}, + 1: {"type": singleLaneRight, "centerDistance": 5}, + } + }, + 1: { + "lanes": { + -1: {"type": singleLaneRight, "centerDistance": -5}, + 0: {"type": singleLaneRight, "centerDistance": 0}, + 1: {"type": singleLaneRight, "centerDistance": 5}, + } + }, + }, + "sideRoads": { + 0: { + "lanes": { + -1: {"type": singleLaneLeft, "centerDistance": -5}, + 1: {"type": singleLaneLeft, "centerDistance": 0}, + 2: {"type": singleLaneLeft, "centerDistance": 5}, + } + }, + 1: { + "lanes": { + -1: {"type": singleLaneLeft, "centerDistance": -5}, + 1: {"type": singleLaneLeft, "centerDistance": 0}, + 2: {"type": singleLaneLeft, "centerDistance": 5}, + } + }, + }, +} + + +###### + + +sys.path.append("Terraformer/mapAnalysis/") + + +def get_distance(point1, point2): + # Calculate the Euclidean distance between two points + return sqrt((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2 + (point1[2] - point2[2]) ** 2) + + +def simplify_coordinates(coordinates, epsilon): + if len(coordinates) < 3: + return coordinates + + # Find the point with the maximum distance + max_distance = 0 + max_index = 0 + end_index = len(coordinates) - 1 + + for i in range(1, end_index): + distance = get_distance(coordinates[i], coordinates[0]) + if distance > max_distance: + max_distance = distance + max_index = i + + simplified_coordinates = [] + + # If the maximum distance is greater than epsilon, recursively simplify + if max_distance > epsilon: + rec_results1 = simplify_coordinates(coordinates[:max_index+1], epsilon) + rec_results2 = simplify_coordinates(coordinates[max_index:], epsilon) + + # Combine the simplified sub-results + simplified_coordinates.extend(rec_results1[:-1]) + simplified_coordinates.extend(rec_results2) + else: + # The maximum distance is less than epsilon, retain the endpoints + simplified_coordinates.append(coordinates[0]) + simplified_coordinates.append(coordinates[end_index]) + + return simplified_coordinates + + +def irlToMc(coordinates): + + heightmap = Image.open('./world_maker/data/heightmap.png') + + editor = Editor() + buildArea = editor.getBuildArea() + xMin = (editor.getBuildArea().begin).x + yMin = (editor.getBuildArea().begin).y + zMin = (editor.getBuildArea().begin).z + + print(xMin, yMin, zMin) + + coordinates_final = [] + + coordinates_final.append(coordinates[0] + xMin) + coordinates_final.append(heightmap.getpixel( + (coordinates[0], coordinates[2]))[0]) + coordinates_final.append(coordinates[2] + zMin) + + return coordinates_final + + +def setRoads(skeleton): + # Generation + for i in range(len(skeleton.lines)): + for j in range(len(skeleton.lines[i])): + xyz = irlToMc(skeleton.coordinates[skeleton.lines[i][j]]) + skeleton.lines[i][j] = xyz + print(skeleton.lines[i][j]) + + # Simplification + + for i in range(len(skeleton.lines)): + skeleton.lines[i] = simplify_coordinates(skeleton.lines[i], 10) + + for i in range(len(skeleton.lines)): # HERE -------------------------------------- + print(skeleton.lines[i]) + road = RoadCurve(standard_modern_lane_agencement, skeleton.lines[i]) + road.setLanes() + print(road.getLanes(), "LANES ***********") + + rejected = [] + accepted = [] + # print(housesCoordinates) + for i in range(len(housesCoordinates)): + pos = housesCoordinates[i] + # print(pos, "pos0") + editor = Editor() + xMin = (editor.getBuildArea().begin).x + yMin = (editor.getBuildArea().begin).y + zMin = (editor.getBuildArea().begin).z + base = findGround((xMin, zMin), pos) + if base != None: + # print(pos, "pos1") + pos1 = ( + pos[0] - random.randint(3, 6), + base[1], + pos[2] - random.randint(3, 6), + ) + pos2 = ( + pos[0] + random.randint(3, 6), + base[1], + pos[2] + random.randint(3, 6), + ) + pos3 = ( + pos1[0], + base[1], + pos2[2], + ) + pos4 = ( + pos2[0], + base[1], + pos1[2], + ) + # print(pos1, pos2, pos3, pos4, "pos") + xMin = (editor.getBuildArea().begin).x + yMin = (editor.getBuildArea().begin).y + zMin = (editor.getBuildArea().begin).z + Ypos1 = findGround((xMin, zMin), pos1) + Ypos2 = findGround((xMin, zMin), pos2) + Ypos3 = findGround((xMin, zMin), pos3) + Ypos4 = findGround((xMin, zMin), pos4) + + if ( + Ypos1 != None + and Ypos2 != None + and Ypos3 != None + and Ypos4 != None + ): + + pos2 = ( + pos2[0], + max(Ypos1[1], Ypos2[1], base[1], Ypos3[1], Ypos4[1]), + pos2[2], + ) + pos1 = ( + pos1[0], + max(Ypos1[1], Ypos2[1], base[1], Ypos3[1], Ypos4[1]), + pos1[2], + ) + if ( + (pos1[0], pos1[2]) not in alreadyGenerated + and ( + pos2[0], + pos2[2], + ) + not in alreadyGenerated + and (pos1[0], pos2[2]) not in alreadyGenerated + and (pos2[0], pos1[2]) + ): # HERE, remove print and find why house gen on self + + for xi in range( + -5, + (max(pos1[0], pos2[0]) - min(pos1[0], pos2[0])) + 5, + ): + for yi in range( + -5, + (max(pos1[2], pos2[2]) - min(pos1[2], pos2[2])) + + 5, + ): + alreadyGenerated.append( + ( + min(pos1[0], pos2[0]) + xi, + min(pos1[2], pos2[2]) + yi, + ) + ) + + nb_style = randint(0, 3) + door = ["left", "right"] + r2 = random.randint(0, 1) + facing = ["south", "north", "east", "west"] + r3 = random.randint(0, 3) + + xyz1 = (min(pos1[0], pos2[0]), min( + pos1[1], pos2[1]), min(pos1[2], pos2[2])) + xyz2 = (max(pos1[0], pos2[0]), max( + pos1[1], pos2[1]), max(pos1[2], pos2[2])) + + house.house(xyz1, xyz2, door[r2], 10, nb_style, facing[r3]) + accepted.append( + ( + pos1[0], + pos1[2], + pos2[0], + pos2[2], + ) + ) + else: + rejected.append( + ( + pos1[0], + pos1[2], + pos2[0], + pos2[2], + ) + ) + + print("Done") diff --git a/networks/legacy_roads/tools.py b/networks/legacy_roads/tools.py new file mode 100644 index 0000000..f27f0ba --- /dev/null +++ b/networks/legacy_roads/tools.py @@ -0,0 +1,40 @@ +from gdpc import Block as place +from gdpc import Editor +import networks.legacy_roads.maths as maths + + +USE_BATCHING = True +editor = Editor(buffering=True, caching=True, multithreading=True) + + +def setBlock(block, xyz): + x, y, z = xyz + editor.placeBlock((x, y, z), place(block)) + + +def getBlock(xyz): + print("You used getBlock in a deprecated manner.") + # x, y, z = xyz + # return minecraft.getBlock(x, y, z) + + +def fillBlock(block, xyz): + print("fill", xyz) + xDistance = max(xyz[0], xyz[3]) - min(xyz[0], xyz[3]) + yDistance = max(xyz[1], xyz[4]) - min(xyz[1], xyz[4]) + zDistance = max(xyz[2], xyz[5]) - min(xyz[2], xyz[5]) + + coordinates = [] + + for i in range(min(xyz[0], xyz[3]), max(xyz[0], xyz[3])+1): + for j in range(min(xyz[1], xyz[4]), max(xyz[1], xyz[4])+1): + for k in range(min(xyz[2], xyz[5]), max(xyz[2], xyz[5])+1): + coordinates.append((i, j, k)) + + editor.placeBlock(coordinates, place(block)) + + +def setLine(block, xyz0, xyz1, pixelPerfect=True): + points = maths.line(xyz0, xyz1, pixelPerfect) + for i in points: + setBlock(block, (i[0], i[1], i[2])) diff --git a/world_maker/data/building.png b/world_maker/data/building.png index c3ad1eb..a36ebd6 100644 Binary files a/world_maker/data/building.png and b/world_maker/data/building.png differ diff --git a/world_maker/data/city_map.png b/world_maker/data/city_map.png index d83d3c6..8a6c6ec 100644 Binary files a/world_maker/data/city_map.png and b/world_maker/data/city_map.png differ diff --git a/world_maker/data/district.png b/world_maker/data/district.png index e21d711..7552641 100644 Binary files a/world_maker/data/district.png and b/world_maker/data/district.png differ diff --git a/world_maker/data/heightmap.png b/world_maker/data/heightmap.png index b707a30..154bfdf 100644 Binary files a/world_maker/data/heightmap.png and b/world_maker/data/heightmap.png differ diff --git a/world_maker/data/highwaymap.png b/world_maker/data/highwaymap.png index 5d713b2..5b97f93 100644 Binary files a/world_maker/data/highwaymap.png and b/world_maker/data/highwaymap.png differ diff --git a/world_maker/data/mountain_map.png b/world_maker/data/mountain_map.png index 69a0654..a977b00 100644 Binary files a/world_maker/data/mountain_map.png and b/world_maker/data/mountain_map.png differ diff --git a/world_maker/data/roadmap.png b/world_maker/data/roadmap.png index b332976..5c8c5cd 100644 Binary files a/world_maker/data/roadmap.png and b/world_maker/data/roadmap.png differ diff --git a/world_maker/data/skeleton_highway.png b/world_maker/data/skeleton_highway.png index e2d8875..d48cab2 100644 Binary files a/world_maker/data/skeleton_highway.png and b/world_maker/data/skeleton_highway.png differ diff --git a/world_maker/data/skeleton_highway_area.png b/world_maker/data/skeleton_highway_area.png index 7345149..1fdae99 100644 Binary files a/world_maker/data/skeleton_highway_area.png and b/world_maker/data/skeleton_highway_area.png differ diff --git a/world_maker/data/skeleton_mountain.png b/world_maker/data/skeleton_mountain.png index 6ea1561..14f9cb7 100644 Binary files a/world_maker/data/skeleton_mountain.png and b/world_maker/data/skeleton_mountain.png differ diff --git a/world_maker/data/skeleton_mountain_area.png b/world_maker/data/skeleton_mountain_area.png index 86d2c2e..7010d14 100644 Binary files a/world_maker/data/skeleton_mountain_area.png and b/world_maker/data/skeleton_mountain_area.png differ diff --git a/world_maker/data/smooth_sobel_watermap.png b/world_maker/data/smooth_sobel_watermap.png index e60ab19..3ec92a1 100644 Binary files a/world_maker/data/smooth_sobel_watermap.png and b/world_maker/data/smooth_sobel_watermap.png differ diff --git a/world_maker/data/sobelmap.png b/world_maker/data/sobelmap.png index d755e40..83ff8f6 100644 Binary files a/world_maker/data/sobelmap.png and b/world_maker/data/sobelmap.png differ diff --git a/world_maker/data/treemap.png b/world_maker/data/treemap.png index d2d6aa5..db12c75 100644 Binary files a/world_maker/data/treemap.png and b/world_maker/data/treemap.png differ diff --git a/world_maker/data/watermap.png b/world_maker/data/watermap.png index cfa137a..7010d14 100644 Binary files a/world_maker/data/watermap.png and b/world_maker/data/watermap.png differ