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

Adding basic support for colours in facades and roofs based on tagging

parent 6f3aa0d3
......@@ -195,8 +195,8 @@ if __name__ == '__main__':
configure_logging(my_log_level, args.log_to_file)
parameters.read_from_file(args.filename)
if parameters.FLAG_2018:
logging.info('Processing for 2018 version')
if parameters.FLAG_2018_2:
logging.info('Processing for 2018.2 version')
exec_procedure = Procedures.all
if args.exec:
......
This diff is collapsed.
......@@ -96,8 +96,8 @@ Important Flags
============================================= ======== ======= ==============================================================================
Parameter Type Default Description / Example
============================================= ======== ======= ==============================================================================
FLAG_2018 Boolean False If True then then texture catalog and shader integration is for minimal
version of FlightGear 2018.1.
FLAG_2018_2 Boolean False If True then then the texture catalog and shader integration is for minimal
version of FlightGear 2018.2.
BUILDING_USE_SHARED_WORSHIP Boolean False Use a shared model for worship buildings instead of OSM floor plan and
heuristics. The shared models will try to respect the type of building (e.g.
......
......@@ -76,7 +76,7 @@ USE_EXTERNAL_MODELS = False
WRITE_CLUSTER_STATS = False
FLAG_2018 = False # Feature flag for 2018.1 or greater version of FG
FLAG_2018_2 = False # Feature flag for 2018.1 or greater version of FG
# =============================================================================
# PARAMETERS RELATED TO BUILDINGS IN osm2city
......@@ -150,6 +150,10 @@ BUILDING_CITY_LEVEL_HEIGHT_HIGH = 3.6
BUILDING_USE_SHARED_WORSHIP = False # try to use shared models for worship buildings
# a hex value for the colour to be used if the colour value in OSM is missing or cannot be interpreted
BUILDING_FACADE_DEFAULT_COLOUR = '#D3D3D3' # e.g. #d3d3d3 - light grey
BUILDING_ROOF_DEFAULT_COLOUR = '#B22222' # e.g. #b22222 - firebrick
# -- The more buildings end up in LOD rough, the more work for your GPU.
# Increasing any of the following parameters will decrease GPU load.
LOD_ALWAYS_DETAIL_BELOW_AREA = 150 # -- below this area, buildings will always be LOD detail
......
......@@ -11,7 +11,7 @@ Created on Wed Mar 13 22:22:05 2013
#
# ideally:
# Texture(rules='building.height > 15
# AND (roof.color = black OR roof.color = grey)
# AND (roof.colour = black OR roof.colour = gray)
# AND roof.shape = flat ')
......
......@@ -80,7 +80,6 @@ import math
import multiprocessing as mp
import os
import random
import textwrap
from typing import Dict, List, MutableMapping, Optional, Tuple
import unittest
......
......@@ -10,7 +10,8 @@ from utils.utilities import Stats
from textures.texture import Texture, RoofManager
def flat(ac_object: ac.Object, index_first_node_in_ac_obj: int, b, roof_mgr: RoofManager, stats: Stats) -> None:
def flat(ac_object: ac.Object, index_first_node_in_ac_obj: int, b, roof_mgr: RoofManager, roof_mat_idx: int,
stats: Stats) -> None:
"""Flat roof. Also works for relations."""
# 3-----------------2 Outer is CCW: 0 1 2 3
# | /| Inner[0] is CW: 4 5 6 7
......@@ -60,14 +61,14 @@ def flat(ac_object: ac.Object, index_first_node_in_ac_obj: int, b, roof_mgr: Roo
nodes_uv_list = []
for i, node in enumerate(nodes):
nodes_uv_list.append((node + index_first_node_in_ac_obj, uv[i][0], uv[i][1]))
ac_object.face(nodes_uv_list)
ac_object.face(nodes_uv_list, mat_idx=roof_mat_idx)
def separate_hipped(ac_object: ac.Object, b) -> None:
return separate_gable(ac_object, b, inward_meters=3.)
def separate_hipped(ac_object: ac.Object, b, roof_mat_idx: int) -> None:
return separate_gable(ac_object, b, roof_mat_idx, inward_meters=3.)
def separate_gable(ac_object, b, inward_meters=0.) -> None:
def separate_gable(ac_object, b, roof_mat_idx: int, inward_meters=0.) -> None:
"""gable roof, 4 nodes, separate model. Inward_"""
# -- pitched roof for 4 ground nodes
t = b.roof_texture
......@@ -137,27 +138,31 @@ def separate_gable(ac_object, b, inward_meters=0.) -> None:
ac_object.face([(o + 0, t.x(0), t.y(0)),
(o + 1, t.x(repeat_x), t.y(0)),
(o + 5, t.x(repeat_x*(1-inward_meters/len_roof_bottom)), t.y(repeat_y)),
(o + 4, t.x(repeat_x*(inward_meters/len_roof_bottom)), t.y(repeat_y))])
(o + 4, t.x(repeat_x*(inward_meters/len_roof_bottom)), t.y(repeat_y))],
mat_idx=roof_mat_idx)
ac_object.face([(o + 2, t.x(0), t.y(0)),
(o + 3, t.x(repeat_x), t.y(0)),
(o + 4, t.x(repeat_x*(1-inward_meters/len_roof_bottom)), t.y(repeat_y)),
(o + 5, t.x(repeat_x*(inward_meters/len_roof_bottom)), t.y(repeat_y))])
(o + 5, t.x(repeat_x*(inward_meters/len_roof_bottom)), t.y(repeat_y))],
mat_idx=roof_mat_idx)
repeat_x = b.edge_length_pts[ind_X[1]]/roof_texture_size_x
len_roof_hypo = (inward_meters**2 + roof_height**2)**0.5
repeat_y = len_roof_hypo/roof_texture_size_y
ac_object.face([(o + 1, t.x(0), t.y(0)),
(o + 2, t.x(repeat_x), t.y(0)),
(o + 5, t.x(0.5*repeat_x), t.y(repeat_y))])
(o + 5, t.x(0.5*repeat_x), t.y(repeat_y))],
mat_idx=roof_mat_idx)
repeat_x = b.edge_length_pts[ind_X[3]]/roof_texture_size_x
ac_object.face([(o + 3, t.x(0), t.y(0)),
(o + 0, t.x(repeat_x), t.y(0)),
(o + 4, t.x(0.5*repeat_x), t.y(repeat_y))])
(o + 4, t.x(0.5*repeat_x), t.y(repeat_y))],
mat_idx=roof_mat_idx)
def separate_pyramidal(ac_object: ac.Object, b, inward_meters=0.0) -> None:
def separate_pyramidal(ac_object: ac.Object, b, roof_mat_idx: int, inward_meters=0.0) -> None:
"""pyramidal roof, ? nodes, separate model. Inward_"""
# -- pitched roof for ? ground nodes
t = b.roof_texture
......@@ -191,10 +196,11 @@ def separate_pyramidal(ac_object: ac.Object, b, inward_meters=0.0) -> None:
repeat_y = len_roof_hypo/roof_texture_size_pt
ac_object.face([(o + i, t.x(0), t.y(0)),
(o + (i+1) % len(b.pts_all), t.x(repeat_x), t.y(0)),
(o + len(b.pts_all), t.x(0.5*repeat_x), t.y(repeat_y))])
(o + len(b.pts_all), t.x(0.5*repeat_x), t.y(repeat_y))],
mat_idx=roof_mat_idx)
def separate_skillion(ac_object: ac.Object, b):
def separate_skillion(ac_object: ac.Object, b, roof_mat_idx: int):
"""skillion roof, n nodes, separate model. Inward_"""
# - handle square skillion roof
# it's assumed that the first 2 nodes are at building:height-roof:height
......@@ -247,7 +253,7 @@ def separate_skillion(ac_object: ac.Object, b):
ac_object.node(-b.pts_all[node][1], b.beginning_of_roof_above_sea_level + b.roof_height_pts[node],
-b.pts_all[node][0])
nodes_uv_list.append((object_node_index + node, uv[i][0], uv[i][1]))
ac_object.face(nodes_uv_list)
ac_object.face(nodes_uv_list, mat_idx=roof_mat_idx)
return
......
This diff is collapsed.
......@@ -18,7 +18,7 @@ class Texture(object):
"""
spelling used internally in osm2city and in many cases automatically converted:
- colour (instead of color)
- grey (instead of gray)
- gray (instead of grey)
possible texture types:
- facade
......
import logging
from typing import Optional
from typing import List, Optional
import matplotlib.pyplot as plt
import numpy as np
import parameters
from pyparsing import Literal, Word, alphas, Optional, OneOrMore, \
Group, nums, Regex, alphanums, LineEnd, Each, ZeroOrMore
import textures.materials
fmt_node = '%g'
fmt_surf = '%1.4g'
......@@ -101,7 +100,7 @@ class Object(object):
"""Add new face. Return its index."""
if not typ:
typ = self.default_type
if not mat_idx:
if mat_idx is None:
mat_idx = self.default_mat_ix
if not swap_uv:
swap_uv = self.default_swap_uv
......@@ -199,10 +198,10 @@ class File(object):
a common source of bugs. Can also add 3d labels (useful for debugging, disabled
by default)
"""
def __init__(self, file_name=None, stats=None, show_labels=False) -> None:
def __init__(self, file_name=None, stats=None, show_labels=False, materials_list: List[str]=list()) -> None:
"""If file_name not None, then read ac3d data from file_name if given. Otherwise create empty ac3d object."""
self.objects = []
self.materials_list = []
self.materials_list = materials_list
self.show_labels = show_labels
self.stats = stats
self._current_object = None
......@@ -276,11 +275,9 @@ class File(object):
def __str__(self) -> str:
s = 'AC3Db\n'
if self.materials_list:
s += "".join(['MATERIAL %s\n' % the_mat for the_mat in self.materials_list])
else:
s += 'MATERIAL "unlit" rgb 0 0 0 amb 1 1 1 emis 0 0 0 spec 0.5 0.5 0.5 shi 64 trans 0\n'
s += 'MATERIAL "lit" rgb 1 1 1 amb 1 1 1 emis 0 0 0 spec 0.5 0.5 0.5 shi 64 trans 0\n'
if not self.materials_list:
self.materials_list = textures.materials.create_materials_list_roads()
s += "".join(['%s\n' % the_mat for the_mat in self.materials_list])
non_empty = [o for o in self.objects if not o.is_empty()]
# FIXME: this doesn't handle nested kids properly
s += 'OBJECT world\nkids %i\n' % len(non_empty)
......
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