Different approach to resource placement raytracing, several layergen fixes, adjustments to photogen, new logging type.

This commit is contained in:
Marcus Str. 2024-12-19 12:16:21 +01:00
parent b07caba79d
commit 8b027cf096
7 changed files with 198 additions and 110 deletions

View File

@ -44,7 +44,7 @@ mstr_clear_cache = True
# Whether or not you want to see progress of the tool as it walks on. # Whether or not you want to see progress of the tool as it walks on.
# High recommendation to leave this on. # High recommendation to leave this on.
mstr_show_log = True mstr_show_log = False
# Should a pseudo shadow be rendered on certain elements? # Should a pseudo shadow be rendered on certain elements?

View File

@ -390,7 +390,7 @@ class mstr_layergen:
# Make sure patch is within bounds # Make sure patch is within bounds
if patchmask.width > self._imgsize or patchmask.height > self._imgsize: if patchmask.width > self._imgsize or patchmask.height > self._imgsize:
patchmask.resize((mstr_photores, mstr_photores), Image.Resampling.BILINEAR) patchmask = patchmask.resize((mstr_photores, mstr_photores), Image.Resampling.BILINEAR)
patchpix = patchmask.load() patchpix = patchmask.load()
# Pick from possible tags and values for the patches # Pick from possible tags and values for the patches
@ -403,7 +403,16 @@ class mstr_layergen:
rg.setLayerContrast(ctr) rg.setLayerContrast(ctr)
ptch = rg.gensource() ptch = rg.gensource()
rg_img = ptch[0] # Generate a full size of the source
ptc_full = Image.new("RGBA", (mstr_photores, mstr_photores))
# Generate the source image
for p in range(1, 201):
rx = randrange(0 - int(ptch[0].width / 2), ptc_full.width - int(ptch[0].width / 2))
ry = randrange(0 - int(ptch[0].height / 2), ptc_full.height - int(ptch[0].height / 2))
ptc_full.alpha_composite(ptch[0], dest=(rx, ry))
rg_img = ptc_full
rg_pix = rg_img.load() rg_pix = rg_img.load()
# The patch to be used in the layer # The patch to be used in the layer
@ -593,6 +602,7 @@ class mstr_layergen:
if lx < self._imgsize and ly < self._imgsize: if lx < self._imgsize and ly < self._imgsize:
tree = self.generate_tree() tree = self.generate_tree()
trees.alpha_composite(tree, (lx, ly)) trees.alpha_composite(tree, (lx, ly))
trees = ImageEnhance.Contrast(trees).enhance(0.8)
if mstr_shadow_enabled == True: if mstr_shadow_enabled == True:
tree_shadow = Image.new("RGBA", (self._imgsize, self._imgsize)) tree_shadow = Image.new("RGBA", (self._imgsize, self._imgsize))
tree_pix = trees.load() tree_pix = trees.load()

13
log.py
View File

@ -15,6 +15,11 @@ from colorama import init as colorama_init
from colorama import Fore from colorama import Fore
from colorama import Style from colorama import Style
from defines import * from defines import *
import sys
import warnings
if not sys.warnoptions:
warnings.simplefilter("ignore")
def mstr_msg(fnc, msg): def mstr_msg(fnc, msg):
if mstr_show_log == True: if mstr_show_log == True:
@ -23,3 +28,11 @@ def mstr_msg(fnc, msg):
print(f' {Fore.GREEN}'+now.strftime("%H:%M:%S")+f'{Style.RESET_ALL} | {Fore.YELLOW}[' + fnc + f']{Style.RESET_ALL} | {Fore.CYAN}'+ msg + f'{Style.RESET_ALL}') print(f' {Fore.GREEN}'+now.strftime("%H:%M:%S")+f'{Style.RESET_ALL} | {Fore.YELLOW}[' + fnc + f']{Style.RESET_ALL} | {Fore.CYAN}'+ msg + f'{Style.RESET_ALL}')
#print(f"{Fore.GREEN}" + now.strftime(" %H:%M:%S" + " | ["+fnc+"] | " + msg)) #print(f"{Fore.GREEN}" + now.strftime(" %H:%M:%S" + " | ["+fnc+"] | " + msg))
def mstr_important_msg(fnc, msg):
colorama_init()
now = datetime.datetime.now()
print(f' {Fore.GREEN}' + now.strftime(
"%H:%M:%S") + f'{Style.RESET_ALL} | {Fore.YELLOW}[' + fnc + f']{Style.RESET_ALL} | {Fore.CYAN}' + msg + f'{Style.RESET_ALL}')

25
og.py
View File

@ -19,12 +19,25 @@ from defines import *
# Print a welcome message # Print a welcome message
print(" ") print(r' ')
print(" ---------------------------------------------------------------- ") print(r' ____ __ __ __ _ ')
print(" ORTHOGRAPHIC: An ortho-photo generator, using real world data.") print(r' / __ \_____/ /_/ /_ ____ ____ __________ _____ / /_ (_)____')
print(" Developed by MarStr - Code available on marstr.online") print(r' / / / / ___/ __/ __ \/ __ \/ __ `/ ___/ __ `/ __ \/ __ \/ / ___/')
print(" ---------------------------------------------------------------- ") print(r'/ /_/ / / / /_/ / / / /_/ / /_/ / / / /_/ / /_/ / / / / / /__ ')
print(" ") print(r'\____/_/ \__/_/ /_/\____/\__, /_/ \__,_/ .___/_/ /_/_/\___/ ')
print(r' /____/ /_/ ')
print(r' ----------------------------------------------------------------')
print(r' A ground texture generator, using photo realistic resources,')
print(r' for flight simulators.')
print(r' ----------------------------------------------------------------')
print(r' Developed by and (c) Marcus Str.')
print(r' Website: https://marstr.online/orthographic')
print(r' Code repo: https://marstr.online/code/gitweb.cgi?p=orthographic')
print(r' ----------------------------------------------------------------')
print(r' If you paid for this software, you have been scammed. The source')
print(r' code and always available free of charge.')
print(r' ----------------------------------------------------------------')
print(r' ')
# Evaluate CLI arguments and process tile. # Evaluate CLI arguments and process tile.

View File

@ -279,9 +279,7 @@ class mstr_orthographic:
pg = mstr_photogen(self._lat, self._long, grid_lat, grid_lng, maxlatlng[0], maxlatlng[1]) pg = mstr_photogen(self._lat, self._long, grid_lat, grid_lng, maxlatlng[0], maxlatlng[1])
pg.setLayerNames(layers) pg.setLayerNames(layers)
pg.genphoto(photolayers, waterlayers, cpl) pg.genphoto(photolayers, waterlayers, cpl)
mstr_msg("orthographic", " -- Ortho photo generated -- ") mstr_important_msg("orthographic", "Ortho photo " + str(grid_lat)+"_"+str(grid_lng)+" generated!")
print("")
print("")
# Perform adjustment of grid position # Perform adjustment of grid position
n_lng = grid_lng + step n_lng = grid_lng + step

View File

@ -129,7 +129,7 @@ class mstr_photogen:
# Make sure patch is within bounds # Make sure patch is within bounds
if patchmask.width > self._tile.width or patchmask.height > self._tile.height: if patchmask.width > self._tile.width or patchmask.height > self._tile.height:
patchmask.resize((mstr_photores, mstr_photores), Image.Resampling.BILINEAR) patchmask = patchmask.resize((mstr_photores, mstr_photores), Image.Resampling.BILINEAR)
patchpix = patchmask.load() patchpix = patchmask.load()
@ -143,7 +143,16 @@ class mstr_photogen:
rg.setLayerContrast(randrange(1, 4)) rg.setLayerContrast(randrange(1, 4))
ptch = rg.gensource() ptch = rg.gensource()
rg_img = ptch[0] # Generate a full size of the source
ptc_full = Image.new("RGBA", (mstr_photores, mstr_photores))
# Generate the source image
for p in range(1, 201):
rx = randrange(0 - int(ptch[0].width / 2), ptc_full.width - int(ptch[0].width / 2))
ry = randrange(0 - int(ptch[0].height / 2), ptc_full.height - int(ptch[0].height / 2))
ptc_full.alpha_composite(ptch[0], dest=(rx, ry))
rg_img = ptc_full
rg_pix = rg_img.load() rg_pix = rg_img.load()
# The patch to be used in the layer # The patch to be used in the layer
@ -348,6 +357,8 @@ class mstr_photogen:
tree = self.generate_tree() tree = self.generate_tree()
trees.alpha_composite(tree, (lx, ly)) trees.alpha_composite(tree, (lx, ly))
trees = ImageEnhance.Contrast(trees).enhance(0.8)
tree_shadow = Image.new("RGBA", (self._imgsize, self._imgsize)) tree_shadow = Image.new("RGBA", (self._imgsize, self._imgsize))
tree_pix = trees.load() tree_pix = trees.load()
shadow_pix = tree_shadow.load() shadow_pix = tree_shadow.load()

View File

@ -127,12 +127,30 @@ class mstr_tileprep:
for ln in fnlines: for ln in fnlines:
l = ln.split(" ") l = ln.split(" ")
if l[0] == self._tag and l[1] == self._value: if l[0] == self._tag and l[1] == self._value:
l[3] = l[3].replace("\n", "")
src = l[2] src = l[2]
return src return src
# Get existing contrast value
def _getResourceContrast(self, tv, th):
# This either remains 0 or a string different to "0" in the end
ctr = "0"
df = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/" + str(tv) + "_" + str(th)
fnlines = []
if os.path.isfile(df) == True: # It is possible that the requested file does not yet exist
with open(df) as textfile:
fnlines = textfile.readlines()
for ln in fnlines:
l = ln.split(" ")
if l[0] == self._tag and l[1] == self._value:
l[4] = l[4].replace("\n", "")
ctr = l[4]
return ctr
# Find the edge touch info # Find the edge touch info
def _getResourceTouch(self, tv, th): def _getResourceTouch(self, tv, th):
touch = "" touch = ""
@ -145,7 +163,6 @@ class mstr_tileprep:
for ln in fnlines: for ln in fnlines:
l = ln.split(" ") l = ln.split(" ")
if l[0] == self._tag and l[1] == self._value: if l[0] == self._tag and l[1] == self._value:
l[3] = l[3].replace("\n", "")
touch = l[3] touch = l[3]
return touch return touch
@ -167,21 +184,24 @@ class mstr_tileprep:
# Store the required resource information into the appropriate tile # Store the required resource information into the appropriate tile
def _storeResourceInfo(self, tile_v, tile_h, res): def _storeResourceInfo(self, tile_v, tile_h, res, ctr):
df = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/" + str(tile_v) + "_" + str(tile_h) df = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/" + str(tile_v) + "_" + str(tile_h)
fnlines = [] fnlines = []
contrast = 0 contrast = ctr
if os.path.isfile(df) == True: # It is possible that the requested file does not yet exist if os.path.isfile(df) == True: # It is possible that the requested file does not yet exist
with open(df) as textfile: with open(df) as textfile:
fnlines = textfile.readlines() fnlines = textfile.readlines()
curline = 0 curline = 0
for ln in fnlines: for ln in fnlines:
l = ln.split(" ") l = ln.split(" ")
if len(l) > 1:
if l[0] == self._tag and l[1] == self._value: if l[0] == self._tag and l[1] == self._value:
l[2] = res l[2] = res
contrast = int(l[4]) l[4] = l[4].replace("\n", "")
#contrast = l[4]
# Find contrast values for some tags # Find contrast values for some tags
if contrast == "0":
if ( if (
(l[0] == "landuse" and l[1] == "forest") or (l[0] == "landuse" and l[1] == "forest") or
(l[0] == "landuse" and l[1] == "meadow") or (l[0] == "landuse" and l[1] == "meadow") or
@ -194,16 +214,17 @@ class mstr_tileprep:
(l[0] == "leisure" and l[1] == "park") or (l[0] == "leisure" and l[1] == "park") or
(l[0] == "building") (l[0] == "building")
): ):
if int(l[4]) == 0: contrast = randrange(1, 4) contrast = str(randrange(1, 4))
l[3] = l[3].replace("\n", "") l[4] = l[4].replace("\n", "")
fnlines[curline] = l[0] + " " + l[1] + " " + l[2] + " " + l[3] + " " + str(contrast) + "\n" fnlines[curline] = l[0] + " " + l[1] + " " + l[2] + " " + l[3] + " " + contrast
curline = curline+1 curline = curline+1
lines = "" lines = ""
for l in range(len(fnlines)): for l in range(len(fnlines)):
lines = lines + fnlines[l] lines = lines + fnlines[l]
if l < len(lines)-1: lines = lines+"\n"
with open(df, 'w') as textfile: with open(df, 'w') as textfile:
textfile.write(lines) textfile.write(lines)
@ -213,78 +234,100 @@ class mstr_tileprep:
# sources for every tile, thus evading previous edge detection errors # sources for every tile, thus evading previous edge detection errors
def _placeTileSources(self, mlat, mlng): def _placeTileSources(self, mlat, mlng):
# The first tile gets to choose something for itself # None of the edges have reached their end yet
if self._tile_v == 1 and self._tile_h == 1: edge_end = [0,0,0,0] # top, right, bottom, left
resstr = self._selectResources()
self._storeResourceInfo(1, 1, resstr)
# Start "raytracing" # Array with info we need
resinfo = ["", "", ""] # Touch, Resource numbers, contrast
# Initial reset # Go through everything until the end is reached (no more options left)
end_reached = False
while end_reached == False:
# Go north
tv = self._tile_v tv = self._tile_v
th = self._tile_h th = self._tile_h
# Start marching north
while tv < mlat+1:
restch = self._getResourceTouch(tv, th)
if "t" in restch:
resstr = self._getResourceInfo(tv, th)
if resstr == "0":
resstr = self._selectResources()
self._storeResourceInfo(tv, th, resstr)
resd = self._getResourceInfo(tv+1, th)
if resd=="0":
self._storeResourceInfo(tv + 1, th, resstr)
else:
break
tv = tv + 1
# Start marching east while edge_end[0] == 0:
resinfo[0] = self._getResourceTouch(tv, th)
resinfo[1] = self._getResourceInfo(tv, th)
resinfo[2] = self._getResourceContrast(tv, th)
if resinfo[1] == "0":
self._storeResourceInfo(tv, th, self._selectResources(), resinfo[2])
resinfo[1] = self._getResourceInfo(tv, th)
resinfo[2] = self._getResourceContrast(tv, th)
if "t" in resinfo[0]:
tv=tv+1
rinfo = self._getResourceInfo(tv, th)
if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1], resinfo[2])
else:
edge_end[0] = 1
# Go east
tv = self._tile_v tv = self._tile_v
th = self._tile_h th = self._tile_h
while th < mlng + 1:
restch = self._getResourceTouch(tv, th)
if "r" in restch:
resstr = self._getResourceInfo(tv, th)
if resstr == "0":
resstr = self._selectResources()
self._storeResourceInfo(tv, th, resstr)
resd = self._getResourceInfo(tv, th+1)
if resd == "0":
self._storeResourceInfo(tv, th + 1, resstr)
else:
break
th = th + 1
# Start marching south while edge_end[1] == 0:
resinfo[0] = self._getResourceTouch(tv, th)
resinfo[1] = self._getResourceInfo(tv, th)
resinfo[2] = self._getResourceContrast(tv, th)
if resinfo[1] == "0":
self._storeResourceInfo(tv, th, self._selectResources(), resinfo[2])
resinfo[1] = self._getResourceInfo(tv, th)
resinfo[2] = self._getResourceContrast(tv, th)
if "r" in resinfo[0]:
th=th+1
rinfo = self._getResourceInfo(tv, th)
if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1], resinfo[2])
else:
edge_end[1] = 1
# Go south
tv = self._tile_v tv = self._tile_v
th = self._tile_h th = self._tile_h
while tv > 0:
restch = self._getResourceTouch(tv, th)
if "b" in restch:
resstr = self._getResourceInfo(tv, th)
if resstr == "0":
resstr = self._selectResources()
self._storeResourceInfo(tv, th, resstr)
resd = self._getResourceInfo(tv - 1, th)
if resd == "0":
self._storeResourceInfo(tv - 1, th, resstr)
else:
break
tv = tv - 1
# Start marching west while edge_end[2] == 0:
resinfo[0] = self._getResourceTouch(tv, th)
resinfo[1] = self._getResourceInfo(tv, th)
resinfo[2] = self._getResourceContrast(tv, th)
if resinfo[1] == "0":
self._storeResourceInfo(tv, th, self._selectResources(), resinfo[2])
resinfo[1] = self._getResourceInfo(tv, th)
resinfo[2] = self._getResourceContrast(tv, th)
if "b" in resinfo[0]:
tv=tv-1
rinfo = self._getResourceInfo(tv, th)
if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1], resinfo[2])
else:
edge_end[2] = 1
# Go west
tv = self._tile_v tv = self._tile_v
th = self._tile_h th = self._tile_h
while th > 0:
restch = self._getResourceTouch(tv, th) while edge_end[3] == 0:
if "l" in restch: resinfo[0] = self._getResourceTouch(tv, th)
resstr = self._getResourceInfo(tv, th) resinfo[1] = self._getResourceInfo(tv, th)
if resstr == "0": resinfo[2] = self._getResourceContrast(tv, th)
resstr = self._selectResources()
self._storeResourceInfo(tv, th, resstr) if resinfo[1] == "0":
resd = self._getResourceInfo(tv, th-1) self._storeResourceInfo(tv, th, self._selectResources(), resinfo[2])
if resd == "0": resinfo[1] = self._getResourceInfo(tv, th)
self._storeResourceInfo(tv, th - 1, resstr) resinfo[2] = self._getResourceContrast(tv, th)
if "l" in resinfo[0]:
th=th-1
rinfo = self._getResourceInfo(tv, th)
if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1], resinfo[2])
else: else:
break edge_end[3] = 1
th = th - 1
if edge_end[0] == 1 and edge_end[1] == 1 and edge_end[2] == 1 and edge_end[3] == 1:
end_reached = True # <- Break loop