Commit b2fe726c authored by Rick Gruber-Riemer's avatar Rick Gruber-Riemer

Adding new parameter TEXTURES_REGIONS_EXPLICIT to be able to filter textures by region.

parent 9118c561
......@@ -27,7 +27,7 @@ Therefore before running ``osm2city`` related programs please either:
Creating the Texture Atlas
==========================
In order to consume the textures linked as described in chapter :ref:`Creating Soft Links to Texture Data <chapter-texture_data-label>` a texture atlas needs to be created. As this is a bit of a time consuming task, re-creating a texture atlas should only be done if the contained textures change. That is rarely the case. Also remember that if the texture atlas changes, then also the content has to be copied separately (see :ref:`chapter-copy-textures-label`).
In order to be able to use textures for buildings a texture atlas (a structured collection of textures stored in a single image file) needs to be created. As this is a bit of a time consuming task, re-creating a texture atlas should only be done if the contained textures change. That is rarely the case. Also remember that if the texture atlas changes, then also the content has to be copied separately (see :ref:`chapter-copy-textures-label`).
In most situations it is enough to call the following command once and then only if the textures have changed:
......@@ -37,7 +37,7 @@ In most situations it is enough to call the following command once and then only
Alternatively `buildings.py` can be called with the ``-a`` option.
Chapter :ref:`Textures <chapter-parameters-textures>` has an overview of how roof and facade textures can be filtered.
Chapter :ref:`Textures <chapter-parameters-textures>` has an overview of how roof and facade textures can be filtered to suit a given scenery's needs by means of parameters.
====================
......
......@@ -197,6 +197,13 @@ TEXTURES_ROOFS_PROVIDE_EXCLUDE List [] List of pro
TEXTURES_FACADES_PROVIDE_EXCLUDE List [] Ditto for facades.
TEXTURES_REGIONS_EXPLICIT List [] Explicit list of regions to include. If list is empty, then all regions are
accepted.
There is also a special region "generic", which corresponds to
top directory structure. In many situations it might not make sense to include
"generic", as it provides a lot of colours etc. (which however could be
filtered with the other parameters).
============================================= ======== ======= ==============================================================================
......
......@@ -258,6 +258,7 @@ TEXTURES_ROOFS_NAME_EXCLUDE = [] # list of roof file names to exclude, e.g. ["r
TEXTURES_FACADES_NAME_EXCLUDE = [] # e.g. ["de/commercial/facade_modern_21x42m.jpg"]
TEXTURES_ROOFS_PROVIDE_EXCLUDE = [] # list of roof provides features to exclude, e.g. ["colour:red"]
TEXTURES_FACADES_PROVIDE_EXCLUDE = [] # ditto for facade provides features, e.g. ["age:modern"]
TEXTURES_REGIONS_EXPLICIT = [] # list of exclusive regions to accept. All if empty
# default_args_end # DO NOT MODIFY THIS LINE
......
......@@ -141,9 +141,6 @@ def _make_texture_atlas(texture_list: List[Texture], atlas_filename: str, ext: s
if not the_atlas.pack(l):
logging.info("Failed to pack" + str(l))
# the_atlas.write("atlas.png", "RGBA")
# return
atlas_sy = _next_pow2(atlas_sy)
the_atlas.set_height(atlas_sy)
logging.info("Final atlas height %i" % atlas_sy)
......@@ -217,6 +214,30 @@ def _append_roofs(roof_manager: RoofManager, tex_prefix: str) -> None:
sys.exit(1)
def _dump_all_provides_across_textures(texture_list: List[Texture]) -> None:
provided_features_level_one = set()
provided_features_level_two = set()
provided_features_level_three = set()
provided_features_level_four = set()
for texture in texture_list:
for feature in texture.provides:
parts = feature.split(":")
if len(parts) > 0:
provided_features_level_one.add(parts[0])
if len(parts) > 1:
provided_features_level_two.add(parts[1])
if len(parts) > 2:
provided_features_level_three.add(parts[2])
if len(parts) > 3:
provided_features_level_four.add(parts[3])
logging.debug("1st level provides: %s", provided_features_level_one)
logging.debug("2nd level provides: %s", provided_features_level_two)
logging.debug("3rd level provides: %s", provided_features_level_three)
logging.debug("4th level provides: %s", provided_features_level_four)
def init(create_atlas: bool=True) -> None:
logging.debug("textures: init")
global facades
......@@ -243,6 +264,7 @@ def init(create_atlas: bool=True) -> None:
texture_list = facades.get_list() + roofs.get_list()
# warn for missed out textures
_check_missed_input_textures(my_tex_prefix_src, texture_list)
......
......@@ -9,6 +9,7 @@ import numpy as np
import tools
import parameters
from utils.utilities import replace_with_os_separator
class Texture(object):
......@@ -51,11 +52,12 @@ class Texture(object):
height_min=0, height_max=9999,
v_align_bottom: bool=False,
provides=list(), requires=list(), levels=None) -> None:
self.filename = Texture.tex_prefix + os.sep + filename
self.filename = Texture.tex_prefix + os.sep + replace_with_os_separator(filename)
self.x0 = self.x1 = self.y0 = self.y1 = 0
self.sy = self.sx = 0
self.rotated = False
self.provides = provides
self._parse_region()
self.requires = requires
self.height_min = height_min
self.height_max = height_max
......@@ -173,6 +175,15 @@ Please set either h_can_repeat or v_can_repeat to False.' % self.filename
def closest_h_match(self, frac):
return self.h_cuts[np.abs(self.h_cuts - frac).argmin()]
def _parse_region(self) -> None:
"""Parses its filename to find out, which region it is and then adds it to self.provides."""
my_region = "generic"
specific_name = self.filename[len(Texture.tex_prefix) + 1:]
index = specific_name.find(os.sep)
if index > 0:
my_region = specific_name[:index]
self.provides.append("region:" + my_region)
class RoofManager(object):
def __init__(self, cls):
......@@ -185,7 +196,7 @@ class RoofManager(object):
"""Appends a texture to the catalog if the referenced file exists, in which case True is returned.
Otherwise False is returned and the texture is not added.
Prepend each item in t.provides with class name, except for class-independent keywords: age,region,compat
Prepend each item in t.provides with class name, except for class-independent keywords: age, region, compat
"""
# check whether already during initialization an error occurred
if texture.validation_message:
......@@ -199,6 +210,9 @@ class RoofManager(object):
if not self._screen_exclude_texture_by_name(texture):
return False
if not self._screen_exclude_texture_by_region(texture):
return False
# check whether the same texture already has been referenced in an existing entry
for existing in self.__l:
if existing.filename == texture.filename:
......@@ -257,6 +271,16 @@ class RoofManager(object):
return False
return True
def _screen_exclude_texture_by_region(self, texture: Texture) -> bool:
if isinstance(self, FacadeManager):
if len(parameters.TEXTURES_REGIONS_EXPLICIT) > 0:
for feature in texture.provides:
for region in parameters.TEXTURES_REGIONS_EXPLICIT:
if len(feature) > 7 and feature[7:] == region: # [:7] because "region:gb" in texture.provides
return True
return False
return True
def find_matching_roof(self, requires=[]):
candidates = self.find_candidates(requires)
logging.verbose("looking for texture" + str(requires)) # @UndefinedVariable
......
......@@ -107,6 +107,12 @@ def assert_trailing_slash(path: str) -> str:
return my_path
def replace_with_os_separator(path: str) -> str:
"""Switches forward and backward slash depending on os."""
my_string = path.replace("/", os.sep)
my_string = my_string.replace("\\", os.sep)
return my_string
class Stats(object):
def __init__(self):
self.objects = 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment