Commit 2a25935d authored by Thomas Albrecht's avatar Thomas Albrecht

- facade splits now also from bottom. This way, facades with

  roof section requiring black roof can be re-used with red roofs
  by splitting from bottom and limiting height to stay below roof section.
- finally! some cmd line options
- tools: tiny gnuplot writer
parent 4963c9a1
......@@ -78,14 +78,28 @@ def check_height(building_height, t):
# - evaluate error
# - error acceptable?
if building_height >= t.v_splits_meters[0] and building_height <= t.v_size_meters:
for i in range(len(t.v_splits_meters)):
if t.v_splits_meters[i] >= building_height:
tex_y0 = 1-t.v_splits[i]
#print "# height %g storey %i" % (building_height, i)
break
tex_y1 = 1.
# print "--->"
if t.v_split_from_bottom:
# print "from bottom"
for i in range(len(t.v_splits_meters)):
if t.v_splits_meters[i] >= building_height:
# print "bot trying %g >= %g ?" % (t.v_splits_meters[i], building_height)
tex_y0 = 0
tex_y1 = t.v_splits[i]
#print "# height %g storey %i" % (building_height, i)
return tex_y0, tex_y1
else:
# print "from top"
# print "got", t.v_splits_meters
for i in range(len(t.v_splits_meters)-2, -1, -1):
# print "%i top trying %g >= %g ?" % (i, t.v_splits_meters[-1] - t.v_splits_meters[i], building_height)
if t.v_splits_meters[-1] - t.v_splits_meters[i] >= building_height:
# FIXME: probably a bug. Should use distance to height?
tex_y0 = t.v_splits[i]
tex_y1 = 1.
return tex_y0, tex_y1
#tex_filename = t.filename + '.png'
return tex_y0, tex_y1
raise ValueError("SHOULD NOT HAPPEN! found no tex_y0, tex_y1 (building_height %g splits %s %g)" % (building_height, str(t.v_splits_meters), t.v_size_meters))
else:
raise ValueError("SHOULD NOT HAPPEN! building_height %g outside %g %g" % (building_height, t.v_splits_meters[0], t.v_size_meters))
return 0, 0
......@@ -268,7 +282,7 @@ def analyse(buildings, static_objects, transform, elev, facades, roofs, model_pr
level_height = random_level_height()
# -- LOWI year 2525
if True:
if False:
if b.area >= 1500:
b.levels = int(random_levels_skyscraper())
b.height = float(b.levels) * level_height
......@@ -306,7 +320,7 @@ def analyse(buildings, static_objects, transform, elev, facades, roofs, model_pr
continue
# -- skipping 50% of under 200 sqm buildings
if b.area < 30. or (b.area < 200. and random.uniform(0,1) < 0.5):
if b.area < 50. or (b.area < 200. and random.uniform(0,1) < 0.5):
#if b.area < 20. : # FIXME use limits.area_min:
#print "Skipping small building (area)"
tools.stats.skipped_small += 1
......@@ -327,7 +341,7 @@ def analyse(buildings, static_objects, transform, elev, facades, roofs, model_pr
# -- model roof if we have 4 ground nodes and area below 1000m2
if b.nnodes_ground == 4 and b.area < 1000:
b.roof_separate = True
b.roof_flat = False # -- gable roof
b.roof_flat = False # -- pitched roof
# -- no gable roof on tall buildings
......@@ -575,7 +589,7 @@ def write(b, out, elev, tile_elev, transform, offset, LOD_lists):
out.write("kids 0\n")
else:
# -- gable roof
# -- pitched roof
write_and_count_numvert(out, b, nnodes_ground + 2)
# -- 4 corners
for x in X[:-1]:
......
......@@ -87,8 +87,12 @@ no_elev = False # -- skip elevation interpolation
#no_elev = True # -- skip elevation interpolation
check_overlap = True # -- check for overlap with static models
if len(sys.argv) > 1:
no_elev = int(sys.argv[1])
if '-e' in sys.argv:
no_elev = True
if '-c' in sys.argv:
check_overlap = False
# -t #
use_pkl = True
#use_pkl = False
buildings = [] # -- master list, holds all buildings
......@@ -140,6 +144,7 @@ class Building(object):
self.facade_texture = None
self.roof_texture = None
self.roof_separate = False
self.roof_flat = True
self.ac_name = None
#print "tr X", self.X
......@@ -359,21 +364,6 @@ def write_xml(fname, LOD_lists, LM_dict, buildings):
# print texture.filename
# print LMs_avail
if texture.filename in LMs_avail:
# xml.write(textwrap.dedent("""
# <effect>
# <inherits-from>Effects/model-combined-deferred</inherits-from>
# <parameters>
# <lightmap-enabled type="int">1</lightmap-enabled>
# <texture n="3">
# <image>%s_LM.png</image>
# <wrap-s>repeat</wrap-s>
# <wrap-t>repeat</wrap-t>
# </texture>
# <lightmap-factor type="float" n="0"><use>/scenery/LOWI/garage[0]/door[0]/position-norm</use></lightmap-factor>
# </parameters>
# """ % texture.filename))
# "tex/DSCF9495_pow2"))
xml.write(textwrap.dedent("""
<effect>
<inherits-from>cityLM</inherits-from>
......@@ -531,6 +521,8 @@ if __name__ == "__main__":
# - decide LOD
buildings = building_lib.analyse(buildings, static_objects, transform, elev, tex.facades, tex.roofs, prefix+"city")
#tools.write_gp(buildings)
tools.stats.print_summary()
# -- now put buildings into clusters
......@@ -557,7 +549,7 @@ if __name__ == "__main__":
# -- get cluster center
offset = cl.center
print "\ncl offset", offset
#print "\ncl offset", offset
# for b in cl.objects:
#print (b.anchor - offset), " ", b.anchor
......
......@@ -123,6 +123,7 @@ class Texture(object):
v_size_meters, v_splits, v_can_repeat, \
has_roof_section = False, \
height_min = 0, height_max = 9999, \
v_split_from_bottom = False, \
provides = {}, requires = {}):
self.filename = filename
self.provides = provides
......@@ -130,17 +131,25 @@ class Texture(object):
self.has_roof_section = has_roof_section
self.height_min = height_min
self.height_max = height_max
self.v_split_from_bottom = v_split_from_bottom
# roof type, color
# self.v_min = v_min
# self.v_max = v_max
self.v_size_meters = v_size_meters
self.v_splits = np.array(v_splits, dtype=np.float)
if v_splits == None:
if v_splits != None:
v_splits.insert(0,0)
self.v_splits = np.array(v_splits, dtype=np.float)
if len(self.v_splits) > 1:
# FIXME test for not type list
self.v_splits /= self.v_splits[-1]
# print self.v_splits
# -- Gimp origin is upper left, convert to OpenGL lower left
self.v_splits = (1. - self.v_splits)[::-1]
# print self.v_splits
else:
self.v_splits = 1.
elif len(self.v_splits) > 1:
# FIXME test for not type list
self.v_splits /= self.v_splits[-1]
self.v_splits_meters = self.v_splits * self.v_size_meters
self.v_can_repeat = v_can_repeat
if not self.v_can_repeat:
......@@ -183,11 +192,22 @@ def init():
if True:
facades.append(Texture('tex/DSCF9495_pow2',
14, (585, 873, 1179, 1480, 2048), True,
19.4, (1094, 1531, 2048), False, True,
14, [585, 873, 1179, 1480, 2048], True,
19.4, [274, 676, 1114, 1542, 2048], False, True,
requires=['roof:color:black'],
provides=['shape:residential','age:old','compat:roof-flat','compat:roof-gable']))
# 19.4, [1094, 1531, 2048], False, True,
facades.append(Texture('tex/DSCF9495_pow2',
14, [585, 873, 1179, 1480, 2048], True,
19.4, [274, 676, 1114, 1542, 2048], False, True,
height_max = 13.,
v_split_from_bottom = True,
requires=['roof:color:red'],
provides=['shape:residential','age:old','compat:roof-flat','compat:roof-gable']))
if True:
# -- just two windows. Looks rather boring. But maybe we need a very narrow texture?
# facades.append(Texture('tex/DSCF9496_pow2',
# 4.44, None, True,
......@@ -196,14 +216,14 @@ def init():
# provides=['shape:residential','age:old','compat:roof-flat','compat:roof-gable']))
facades.append(Texture('tex/LZ_old_bright_bc2',
17.9, (345,807,1023,1236,1452,1686,2048), True,
14.8, (558,1005,1446,2048), False, True,
17.9, [345,807,1023,1236,1452,1686,2048], True,
14.8, [558,1005,1446,2048], False, True,
provides=['shape:residential','age:old','compat:roof-flat','compat:roof-gable']))
facades.append(Texture('tex/facade_modern36x36_12',
36., (None), True,
36., (158, 234, 312, 388, 465, 542, 619, 697, 773, 870, 1024), True, True,
36., [None], True,
36., [158, 234, 312, 388, 465, 542, 619, 697, 773, 870, 1024], True, True,
provides=['shape:urban','shape:residential','age:modern',
'compat:roof-flat']))
......@@ -214,7 +234,7 @@ def init():
# provides=['shape:residential','age:old','compat:roof-flat','compat:roof-gable']))
facades.append(Texture('tex/DSCF9503_noroofsec_pow2',
12.85, None, True,
17.66, (556,1015,1474,2048), False, True,
17.66, [556,1015,1474,2048], False, True,
requires=['roof:color:black'],
provides=['shape:residential','age:old','compat:roof-flat','compat:roof-gable']))
......@@ -232,29 +252,29 @@ def init():
# provides=['shape:residential','age:old','compat:roof-flat','compat:roof-gable']))
facades.append(Texture('tex/DSCF9710',
29.9, (142,278,437,590,756,890,1024), True,
19.8, (130,216,297,387,512), False, True,
29.9, [142,278,437,590,756,890,1024], True,
19.8, [130,216,297,387,512], False, True,
provides=['shape:residential','age:old','compat:roof-flat','compat:roof-gable']))
facades.append(Texture('tex/DSCF9678_pow2',
10.4, (97,152,210,299,355,411,512), True,
15.5, (132,211,310,512), False, True,
10.4, [97,152,210,299,355,411,512], True,
15.5, [132,211,310,512], False, True,
provides=['shape:residential','shape:commercial','age:modern','compat:roof-flat']))
facades.append(Texture('tex/DSCF9726_noroofsec_pow2',
15.1, (321,703,1024), True,
9.6, (227,512), False, True,
15.1, [321,703,1024], True,
9.6, [227,512], False, True,
provides=['shape:residential','age:old','compat:roof-flat','compat:roof-gable']))
facades.append(Texture('tex/wohnheime_petersburger',
15.6, (215, 414, 614, 814, 1024), True,
15.6, (112, 295, 477, 660, 843, 1024), True, True,
height_min = 15.,
provides=['shape:urban','shape:residential','age:modern',
'compat:roof-flat']))
# provides=['shape:urban','shape:residential','age:modern','age:old',
# 'compat:roof-flat','compat:roof-gable']))
facades.append(Texture('tex/wohnheime_petersburger',
15.6, [215, 414, 614, 814, 1024], True,
15.6, [112, 295, 477, 660, 843, 1024], True, True,
height_min = 15.,
provides=['shape:urban','shape:residential','age:modern',
'compat:roof-flat']))
# provides=['shape:urban','shape:residential','age:modern','age:old',
# 'compat:roof-flat','compat:roof-gable']))
......@@ -282,7 +302,6 @@ def init():
if __name__ == "__main__":
init()
bla
cands = facades.find_candidates([], 14)
print "cands ar", cands
for t in cands:
......
......@@ -156,6 +156,16 @@ def write_map(filename, transform, elev, gmin, gmax):
out.close()
#print "OBJECT_STATIC surface.ac"
def write_gp(buildings):
gp = open("buildings.dat", "w")
for b in buildings:
gp.write("# %s\n" % b.osm_id)
for x in b.X:
gp.write("%g %g\n" % (x[0], x[1]))
gp.write("\n")
gp.close()
class Stats(object):
def __init__(self):
......@@ -168,6 +178,7 @@ class Stats(object):
self.area_above = np.zeros_like(self.area_levels)
self.vertices = 0
self.surfaces = 0
self.have_pitched_roof = 0
self.out = None
self.LOD = np.zeros(3)
......@@ -176,6 +187,7 @@ class Stats(object):
"""
self.vertices += b.vertices
self.surfaces += b.surfaces
self.have_pitched_roof += not b.roof_flat
# self.objects += 1 # skipped because we count buildings while OSM parsing
for i in range(len(self.area_levels))[::-1]:
if b.area >= self.area_levels[i]:
......@@ -197,6 +209,7 @@ class Stats(object):
small %i
nearby %i
texture %i
pitched roof %i
vertices %i
surfaces %i
LOD bare %i (%2.0f)
......@@ -204,6 +217,7 @@ class Stats(object):
LOD detail %i (%2.0f)
""" % (self.objects, total_written,
self.skipped_small, self.skipped_nearby, self.skipped_texture,
self.have_pitched_roof,
self.vertices, self.surfaces,
self.LOD[0], 100.*self.LOD[0]/total_written,
self.LOD[1], 100.*self.LOD[1]/total_written,
......
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